mirror of
https://github.com/qgis/QGIS.git
synced 2025-07-03 00:03:10 -04:00
Compare commits
17 Commits
ba2070b3e3
...
1ae5196805
Author | SHA1 | Date | |
---|---|---|---|
|
1ae5196805 | ||
|
74549aad26 | ||
|
eac401c009 | ||
|
1f0166d35e | ||
|
ada589bb1d | ||
|
b1c8ef3265 | ||
|
f4cf09d4b0 | ||
|
9db58e3726 | ||
|
551aa20f20 | ||
|
24bbdda539 | ||
|
c3641ecdad | ||
|
a36f64edba | ||
|
7181b40dea | ||
|
37b2f2257d | ||
|
30798bb462 | ||
|
52a05a08bd | ||
|
a156c43f7b |
@ -979,7 +979,31 @@ if (WITH_CORE)
|
||||
else()
|
||||
# UNIX
|
||||
set (DEFAULT_BIN_SUBDIR bin)
|
||||
set (DEFAULT_CGIBIN_SUBDIR bin)
|
||||
|
||||
# From https://www.cyberciti.biz/faq/how-do-i-find-the-url-for-my-cgi-bin/
|
||||
execute_process(COMMAND lsb_release -a OUTPUT_VARIABLE LSB_RELEASE_A)
|
||||
if(EXISTS "/etc/fedora-release")
|
||||
# in /var/www/cgi-bin
|
||||
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
|
||||
|
||||
elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
# in /usr/local/www/cgi-bin/
|
||||
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
|
||||
|
||||
elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "BSD")
|
||||
# in /usr/local/libexec/cgi-bin/
|
||||
set (DEFAULT_CGIBIN_SUBDIR libexec/cgi-bin)
|
||||
|
||||
elseif ("${LSB_RELEASE_A}" MATCHES "Ubuntu" OR "${LSB_RELEASE_A}" MATCHES "Debian" OR "${LSB_RELEASE_A}" MATCHES "Mint")
|
||||
# in /usr/lib/cgi-bin/
|
||||
set (DEFAULT_CGIBIN_SUBDIR lib/cgi-bin)
|
||||
|
||||
else()
|
||||
# others: Red Hat/CentOS/Rocky/Alma Linux
|
||||
# in /var/www/cgi-bin/
|
||||
set (DEFAULT_CGIBIN_SUBDIR www/cgi-bin)
|
||||
endif()
|
||||
|
||||
set (DEFAULT_LIB_SUBDIR lib${LIB_SUFFIX})
|
||||
set (DEFAULT_DATA_SUBDIR share/qgis)
|
||||
set (DEFAULT_LIBEXEC_SUBDIR lib${LIB_SUFFIX}/qgis)
|
||||
|
@ -4,6 +4,7 @@ QgsProjectServerValidator.LayerShortName = QgsProjectServerValidator.ValidationE
|
||||
QgsProjectServerValidator.LayerEncoding = QgsProjectServerValidator.ValidationError.LayerEncoding
|
||||
QgsProjectServerValidator.ProjectShortName = QgsProjectServerValidator.ValidationError.ProjectShortName
|
||||
QgsProjectServerValidator.ProjectRootNameConflict = QgsProjectServerValidator.ValidationError.ProjectRootNameConflict
|
||||
QgsProjectServerValidator.OnlyMaptipTrueButEmptyMaptip = QgsProjectServerValidator.ValidationError.OnlyMaptipTrueButEmptyMaptip
|
||||
try:
|
||||
QgsProjectServerValidator.ValidationResult.__attribute_docs__ = {'error': 'Error which occurred during the validation process.', 'identifier': 'Identifier related to the error. It can be a layer/group name.'}
|
||||
QgsProjectServerValidator.ValidationResult.__annotations__ = {'error': 'QgsProjectServerValidator.ValidationError', 'identifier': 'object'}
|
||||
|
@ -33,6 +33,7 @@ project.
|
||||
LayerEncoding,
|
||||
ProjectShortName,
|
||||
ProjectRootNameConflict,
|
||||
OnlyMaptipTrueButEmptyMaptip,
|
||||
};
|
||||
|
||||
static QString displayValidationError( QgsProjectServerValidator::ValidationError error );
|
||||
|
@ -23,6 +23,7 @@ try:
|
||||
QgsServerProjectUtils.wmsInfoFormatSia2045 = staticmethod(QgsServerProjectUtils.wmsInfoFormatSia2045)
|
||||
QgsServerProjectUtils.wmsFeatureInfoAddWktGeometry = staticmethod(QgsServerProjectUtils.wmsFeatureInfoAddWktGeometry)
|
||||
QgsServerProjectUtils.wmsFeatureInfoUseAttributeFormSettings = staticmethod(QgsServerProjectUtils.wmsFeatureInfoUseAttributeFormSettings)
|
||||
QgsServerProjectUtils.wmsHTMLFeatureInfoUseOnlyMaptip = staticmethod(QgsServerProjectUtils.wmsHTMLFeatureInfoUseOnlyMaptip)
|
||||
QgsServerProjectUtils.wmsFeatureInfoSegmentizeWktGeometry = staticmethod(QgsServerProjectUtils.wmsFeatureInfoSegmentizeWktGeometry)
|
||||
QgsServerProjectUtils.wmsAddLegendGroupsLegendGraphic = staticmethod(QgsServerProjectUtils.wmsAddLegendGroupsLegendGraphic)
|
||||
QgsServerProjectUtils.wmsSkipNameForGroup = staticmethod(QgsServerProjectUtils.wmsSkipNameForGroup)
|
||||
|
@ -252,6 +252,20 @@ the feature info response
|
||||
feature info response
|
||||
%End
|
||||
|
||||
static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if only the maptip should be used for HTML feature info response
|
||||
so that the HTML response to the feature info request only contains the
|
||||
maptip. If no maptip is set, the HTML response is empty.
|
||||
|
||||
:param project: the QGIS project
|
||||
|
||||
:return: true if only the maptip should be used for the feature info
|
||||
response only
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
static bool wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
|
@ -33,6 +33,7 @@ project.
|
||||
LayerEncoding,
|
||||
ProjectShortName,
|
||||
ProjectRootNameConflict,
|
||||
OnlyMaptipTrueButEmptyMaptip,
|
||||
};
|
||||
|
||||
static QString displayValidationError( QgsProjectServerValidator::ValidationError error );
|
||||
|
@ -659,7 +659,10 @@ class Repositories(QObject):
|
||||
.strip()
|
||||
)
|
||||
if not qgisMaximumVersion:
|
||||
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
|
||||
if qgisMinimumVersion[0] == "3" and supports_qt6:
|
||||
qgisMaximumVersion = "4.99"
|
||||
else:
|
||||
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
|
||||
# if compatible, add the plugin to the list
|
||||
if not pluginNodes.item(i).firstChildElement(
|
||||
"disabled"
|
||||
@ -845,7 +848,10 @@ class Plugins(QObject):
|
||||
qgisMinimumVersion = "0"
|
||||
qgisMaximumVersion = pluginMetadata("qgisMaximumVersion").strip()
|
||||
if not qgisMaximumVersion:
|
||||
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
|
||||
if qgisMinimumVersion[0] == "3" and supports_qt6:
|
||||
qgisMaximumVersion = "4.99"
|
||||
else:
|
||||
qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
|
||||
# if compatible, add the plugin to the list
|
||||
if not isCompatible(
|
||||
pyQgisVersion(), qgisMinimumVersion, qgisMaximumVersion
|
||||
|
@ -23,6 +23,7 @@ try:
|
||||
QgsServerProjectUtils.wmsInfoFormatSia2045 = staticmethod(QgsServerProjectUtils.wmsInfoFormatSia2045)
|
||||
QgsServerProjectUtils.wmsFeatureInfoAddWktGeometry = staticmethod(QgsServerProjectUtils.wmsFeatureInfoAddWktGeometry)
|
||||
QgsServerProjectUtils.wmsFeatureInfoUseAttributeFormSettings = staticmethod(QgsServerProjectUtils.wmsFeatureInfoUseAttributeFormSettings)
|
||||
QgsServerProjectUtils.wmsHTMLFeatureInfoUseOnlyMaptip = staticmethod(QgsServerProjectUtils.wmsHTMLFeatureInfoUseOnlyMaptip)
|
||||
QgsServerProjectUtils.wmsFeatureInfoSegmentizeWktGeometry = staticmethod(QgsServerProjectUtils.wmsFeatureInfoSegmentizeWktGeometry)
|
||||
QgsServerProjectUtils.wmsAddLegendGroupsLegendGraphic = staticmethod(QgsServerProjectUtils.wmsAddLegendGroupsLegendGraphic)
|
||||
QgsServerProjectUtils.wmsSkipNameForGroup = staticmethod(QgsServerProjectUtils.wmsSkipNameForGroup)
|
||||
|
@ -252,6 +252,20 @@ the feature info response
|
||||
feature info response
|
||||
%End
|
||||
|
||||
static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if only the maptip should be used for HTML feature info response
|
||||
so that the HTML response to the feature info request only contains the
|
||||
maptip. If no maptip is set, the HTML response is empty.
|
||||
|
||||
:param project: the QGIS project
|
||||
|
||||
:return: true if only the maptip should be used for the feature info
|
||||
response only
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
static bool wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project );
|
||||
%Docstring
|
||||
Returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
|
@ -727,19 +727,25 @@ bool QgsPluginRegistry::checkPythonPlugin( const QString &packageName )
|
||||
bool QgsPluginRegistry::isPythonPluginCompatible( const QString &packageName ) const
|
||||
{
|
||||
#ifdef WITH_BINDINGS
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
bool supportsQgis4 = true;
|
||||
const QString supportsQt6 = mPythonUtils->getPluginMetadata( packageName, QStringLiteral( "supportsQt6" ) ).trimmed();
|
||||
if ( supportsQt6.compare( QLatin1String( "YES" ), Qt::CaseInsensitive ) != 0 && supportsQt6.compare( QLatin1String( "TRUE" ), Qt::CaseInsensitive ) != 0 )
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
if ( !getenv( "QGIS_DISABLE_SUPPORTS_QT6_CHECK" ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
supportsQgis4 = false;
|
||||
}
|
||||
const QString minVersion = mPythonUtils->getPluginMetadata( packageName, QStringLiteral( "qgisMinimumVersion" ) );
|
||||
// try to read qgisMaximumVersion. Note checkQgisVersion can cope with "__error__" value.
|
||||
const QString maxVersion = mPythonUtils->getPluginMetadata( packageName, QStringLiteral( "qgisMaximumVersion" ) );
|
||||
QString maxVersion = mPythonUtils->getPluginMetadata( packageName, QStringLiteral( "qgisMaximumVersion" ) );
|
||||
if ( maxVersion == QLatin1String( "__error__" ) && minVersion.startsWith( QLatin1String( "3." ) ) && supportsQgis4 )
|
||||
{
|
||||
maxVersion = QLatin1String( "4.99.0" );
|
||||
}
|
||||
return minVersion != QLatin1String( "__error__" ) && checkQgisVersion( minVersion, maxVersion );
|
||||
#else
|
||||
Q_UNUSED( packageName )
|
||||
|
@ -736,6 +736,9 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
|
||||
bool useAttributeFormSettings = QgsProject::instance()->readBoolEntry( QStringLiteral( "WMSFeatureInfoUseAttributeFormSettings" ), QStringLiteral( "/" ) );
|
||||
mUseAttributeFormSettingsCheckBox->setChecked( useAttributeFormSettings );
|
||||
|
||||
bool useOnlyMaptip = QgsProject::instance()->readBoolEntry( QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ), QStringLiteral( "/" ) );
|
||||
mHTMLFiOnlyMaptip->setChecked( useOnlyMaptip );
|
||||
|
||||
bool addWktGeometry = QgsProject::instance()->readBoolEntry( QStringLiteral( "WMSAddWktGeometry" ), QStringLiteral( "/" ) );
|
||||
mAddWktGeometryCheckBox->setChecked( addWktGeometry );
|
||||
|
||||
@ -1566,6 +1569,7 @@ void QgsProjectProperties::apply()
|
||||
}
|
||||
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "WMSFeatureInfoUseAttributeFormSettings" ), QStringLiteral( "/" ), mUseAttributeFormSettingsCheckBox->isChecked() );
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ), QStringLiteral( "/" ), mHTMLFiOnlyMaptip->isChecked() );
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "WMSAddWktGeometry" ), QStringLiteral( "/" ), mAddWktGeometryCheckBox->isChecked() );
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "WMSSegmentizeFeatureInfoGeometry" ), QStringLiteral( "/" ), mSegmentizeFeatureInfoGeometryCheckBox->isChecked() );
|
||||
QgsProject::instance()->writeEntry( QStringLiteral( "WMSAddLayerGroupsLegendGraphic" ), QStringLiteral( "/" ), mAddLayerGroupsLegendGraphicCheckBox->isChecked() );
|
||||
|
@ -1532,6 +1532,7 @@ void QgsLineString::visitPointsByRegularDistance( const double distance, const s
|
||||
double pZ = std::numeric_limits<double>::quiet_NaN();
|
||||
double pM = std::numeric_limits<double>::quiet_NaN();
|
||||
double nextPointDistance = distance;
|
||||
const double eps = 4 * nextPointDistance * std::numeric_limits<double>::epsilon ();
|
||||
for ( int i = 1; i < totalPoints; ++i )
|
||||
{
|
||||
double thisX = *x++;
|
||||
@ -1540,7 +1541,7 @@ void QgsLineString::visitPointsByRegularDistance( const double distance, const s
|
||||
double thisM = m ? *m++ : 0.0;
|
||||
|
||||
const double segmentLength = QgsGeometryUtilsBase::distance2D( thisX, thisY, prevX, prevY );
|
||||
while ( nextPointDistance < distanceTraversed + segmentLength || qgsDoubleNear( nextPointDistance, distanceTraversed + segmentLength ) )
|
||||
while ( nextPointDistance < distanceTraversed + segmentLength || qgsDoubleNear( nextPointDistance, distanceTraversed + segmentLength, eps ) )
|
||||
{
|
||||
// point falls on this segment - truncate to segment length if qgsDoubleNear test was actually > segment length
|
||||
const double distanceToPoint = std::min( nextPointDistance - distanceTraversed, segmentLength );
|
||||
|
@ -116,21 +116,6 @@ QStringList makeKeyTokens_( const QString &scope, const QString &key )
|
||||
// be sure to include the canonical root node
|
||||
keyTokens.push_front( QStringLiteral( "properties" ) );
|
||||
|
||||
//check validy of keys since an invalid xml name will will be dropped upon saving the xml file. If not valid, we print a message to the console.
|
||||
for ( int i = 0; i < keyTokens.size(); ++i )
|
||||
{
|
||||
const QString keyToken = keyTokens.at( i );
|
||||
|
||||
//invalid chars in XML are found at http://www.w3.org/TR/REC-xml/#NT-NameChar
|
||||
//note : it seems \x10000-\xEFFFF is valid, but it when added to the regexp, a lot of unwanted characters remain
|
||||
const thread_local QRegularExpression sInvalidRegexp = QRegularExpression( QStringLiteral( "([^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\-\\.0-9\\x{B7}\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]|^[^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}])" ) );
|
||||
if ( keyToken.contains( sInvalidRegexp ) )
|
||||
{
|
||||
const QString errorString = QObject::tr( "Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
|
||||
QgsMessageLog::logMessage( errorString, QString(), Qgis::MessageLevel::Critical );
|
||||
}
|
||||
}
|
||||
|
||||
return keyTokens;
|
||||
}
|
||||
|
||||
@ -1322,20 +1307,20 @@ void dump_( const QgsProjectPropertyKey &topQgsPropertyKey )
|
||||
* scope. "layers" is a list containing three string values.
|
||||
*
|
||||
* \code{.xml}
|
||||
* <properties>
|
||||
* <fsplugin>
|
||||
* <foo type="int" >42</foo>
|
||||
* <baz type="int" >1</baz>
|
||||
* <layers type="QStringList" >
|
||||
* <properties name="properties">
|
||||
* <properties name="fsplugin">
|
||||
* <properties name="foo" type="int" >42</properties>
|
||||
* <properties name="baz" type="int" >1</properties>
|
||||
* <properties name="layers" type="QStringList">
|
||||
* <value>railroad</value>
|
||||
* <value>airport</value>
|
||||
* </layers>
|
||||
* <xyqzzy type="int" >1</xyqzzy>
|
||||
* <bar type="double" >123.456</bar>
|
||||
* <feature_types type="QStringList" >
|
||||
* </properties>
|
||||
* <properties name="xyqzzy" type="int" >1</properties>
|
||||
* <properties name="bar" type="double" >123.456</properties>
|
||||
* <properties name="feature_types" type="QStringList">
|
||||
* <value>type</value>
|
||||
* </feature_types>
|
||||
* </fsplugin>
|
||||
* </properties>
|
||||
* </properties>
|
||||
* </properties>
|
||||
* \endcode
|
||||
*
|
||||
@ -3992,10 +3977,25 @@ bool QgsProject::createEmbeddedLayer( const QString &layerId, const QString &pro
|
||||
const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral( "properties" ) );
|
||||
if ( !propertiesElem.isNull() )
|
||||
{
|
||||
const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral( "Paths" ) ).firstChildElement( QStringLiteral( "Absolute" ) );
|
||||
if ( !absElem.isNull() )
|
||||
QDomElement e = propertiesElem.firstChildElement( QStringLiteral( "Paths" ) );
|
||||
if ( e.isNull() )
|
||||
{
|
||||
useAbsolutePaths = absElem.text().compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
|
||||
e = propertiesElem.firstChildElement( QStringLiteral( "properties" ) );
|
||||
while ( !e.isNull() && e.attribute( QStringLiteral( "name" ) ) != QStringLiteral( "Paths" ) )
|
||||
e = e.nextSiblingElement( QStringLiteral( "properties" ) );
|
||||
|
||||
e = e.firstChildElement( QStringLiteral( "properties" ) );
|
||||
while ( !e.isNull() && e.attribute( QStringLiteral( "name" ) ) != QStringLiteral( "Absolute" ) )
|
||||
e = e.nextSiblingElement( QStringLiteral( "properties" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
e = e.firstChildElement( QStringLiteral( "Absolute" ) );
|
||||
}
|
||||
|
||||
if ( !e.isNull() )
|
||||
{
|
||||
useAbsolutePaths = e.text().compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,15 +233,15 @@ bool QgsProjectPropertyValue::readXml( const QDomNode &keyNode )
|
||||
|
||||
// keyElement is created by parent QgsProjectPropertyKey
|
||||
bool QgsProjectPropertyValue::writeXml( QString const &nodeName,
|
||||
QDomElement &keyElement,
|
||||
QDomDocument &document )
|
||||
QDomElement &keyElement,
|
||||
QDomDocument &document )
|
||||
{
|
||||
QDomElement valueElement = document.createElement( nodeName );
|
||||
QDomElement valueElement = document.createElement( QStringLiteral( "properties" ) );
|
||||
|
||||
// remember the type so that we can rebuild it when the project is read in
|
||||
valueElement.setAttribute( QStringLiteral( "name" ), nodeName );
|
||||
valueElement.setAttribute( QStringLiteral( "type" ), mValue.typeName() );
|
||||
|
||||
|
||||
// we handle string lists differently from other types in that we
|
||||
// create a sequence of repeated elements to cover all the string list
|
||||
// members; each value will be in a <value></value> tag.
|
||||
@ -362,33 +362,41 @@ bool QgsProjectPropertyKey::readXml( const QDomNode &keyNode )
|
||||
|
||||
while ( i < subkeys.count() )
|
||||
{
|
||||
const QDomNode subkey = subkeys.item( i );
|
||||
QString name;
|
||||
|
||||
if ( subkey.nodeName() == QStringLiteral( "properties" ) &&
|
||||
subkey.hasAttributes() && // if we have attributes
|
||||
subkey.isElement() && // and we're an element
|
||||
subkey.toElement().hasAttribute( QStringLiteral( "name" ) ) ) // and we have a "name" attribute
|
||||
name = subkey.toElement().attribute( QStringLiteral( "name" ) );
|
||||
else
|
||||
name = subkey.nodeName();
|
||||
|
||||
// if the current node is an element that has a "type" attribute,
|
||||
// then we know it's a leaf node; i.e., a subkey _value_, and not
|
||||
// a subkey
|
||||
if ( subkeys.item( i ).hasAttributes() && // if we have attributes
|
||||
subkeys.item( i ).isElement() && // and we're an element
|
||||
subkeys.item( i ).toElement().hasAttribute( QStringLiteral( "type" ) ) ) // and we have a "type" attribute
|
||||
if ( subkey.hasAttributes() && // if we have attributes
|
||||
subkey.isElement() && // and we're an element
|
||||
subkey.toElement().hasAttribute( QStringLiteral( "type" ) ) ) // and we have a "type" attribute
|
||||
{
|
||||
// then we're a key value
|
||||
delete mProperties.take( subkeys.item( i ).nodeName() );
|
||||
mProperties.insert( subkeys.item( i ).nodeName(), new QgsProjectPropertyValue );
|
||||
//
|
||||
delete mProperties.take( name );
|
||||
mProperties.insert( name, new QgsProjectPropertyValue );
|
||||
|
||||
QDomNode subkey = subkeys.item( i );
|
||||
|
||||
if ( !mProperties[subkeys.item( i ).nodeName()]->readXml( subkey ) )
|
||||
if ( !mProperties[name]->readXml( subkey ) )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "unable to parse key value %1" ).arg( subkeys.item( i ).nodeName() ) );
|
||||
QgsDebugError( QStringLiteral( "unable to parse key value %1" ).arg( name ) );
|
||||
}
|
||||
}
|
||||
else // otherwise it's a subkey, so just recurse on down the remaining keys
|
||||
{
|
||||
addKey( subkeys.item( i ).nodeName() );
|
||||
addKey( name );
|
||||
|
||||
QDomNode subkey = subkeys.item( i );
|
||||
|
||||
if ( !mProperties[subkeys.item( i ).nodeName()]->readXml( subkey ) )
|
||||
if ( !mProperties[name]->readXml( subkey ) )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "unable to parse subkey %1" ).arg( subkeys.item( i ).nodeName() ) );
|
||||
QgsDebugError( QStringLiteral( "unable to parse subkey %1" ).arg( name ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +416,8 @@ bool QgsProjectPropertyKey::writeXml( QString const &nodeName, QDomElement &elem
|
||||
// If it's an _empty_ node (i.e., one with no properties) we need to emit
|
||||
// an empty place holder; else create new Dom elements as necessary.
|
||||
|
||||
QDomElement keyElement = document.createElement( nodeName ); // Dom element for this property key
|
||||
QDomElement keyElement = document.createElement( "properties" ); // Dom element for this property key
|
||||
keyElement.toElement().setAttribute( QStringLiteral( "name" ), nodeName );
|
||||
|
||||
if ( ! mProperties.isEmpty() )
|
||||
{
|
||||
|
@ -37,6 +37,8 @@ QString QgsProjectServerValidator::displayValidationError( QgsProjectServerValid
|
||||
return QObject::tr( "The project root name (either the project short name or project title) is not valid. It must start with an unaccented alphabetical letter, followed by any alphanumeric letters, dot, dash or underscore" );
|
||||
case QgsProjectServerValidator::ProjectRootNameConflict:
|
||||
return QObject::tr( "The project root name (either the project short name or project title) is already used by a layer or a group" );
|
||||
case QgsProjectServerValidator::OnlyMaptipTrueButEmptyMaptip:
|
||||
return QObject::tr( "Use only maptip for HTML GetFeatureInfo response is enabled but the HTML maptip is empty" );
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
@ -49,7 +51,7 @@ QString getShortName( T *node )
|
||||
return shortName.isEmpty() ? node->name() : shortName;
|
||||
}
|
||||
|
||||
void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages )
|
||||
void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages, QStringList &layerNames, QStringList &maptipTemplates )
|
||||
{
|
||||
const QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children();
|
||||
for ( int i = 0; i < treeGroupChildren.size(); ++i )
|
||||
@ -59,7 +61,7 @@ void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, Q
|
||||
{
|
||||
QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
|
||||
owsNames << getShortName( treeGroupChild );
|
||||
browseLayerTree( treeGroupChild, owsNames, encodingMessages );
|
||||
browseLayerTree( treeGroupChild, owsNames, encodingMessages, layerNames, maptipTemplates );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -74,11 +76,22 @@ void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, Q
|
||||
if ( vl->dataProvider() && vl->dataProvider()->encoding() == QLatin1String( "System" ) )
|
||||
encodingMessages << layer->name();
|
||||
}
|
||||
layerNames << treeLayer->name();
|
||||
maptipTemplates << layer->mapTipTemplate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsProjectServerValidator::isOnlyMaptipEnabled( QgsProject *project )
|
||||
{
|
||||
return project->readBoolEntry(
|
||||
QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ),
|
||||
QString(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectServerValidator::ValidationResult> &results )
|
||||
{
|
||||
results.clear();
|
||||
@ -90,8 +103,8 @@ bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectS
|
||||
if ( !project->layerTreeRoot() )
|
||||
return false;
|
||||
|
||||
QStringList owsNames, encodingMessages;
|
||||
browseLayerTree( project->layerTreeRoot(), owsNames, encodingMessages );
|
||||
QStringList owsNames, encodingMessages, layerNames, maptipTemplates;
|
||||
browseLayerTree( project->layerTreeRoot(), owsNames, encodingMessages, layerNames, maptipTemplates );
|
||||
|
||||
QStringList duplicateNames, regExpMessages;
|
||||
const thread_local QRegularExpression snRegExp = QgsApplication::shortNameRegularExpression();
|
||||
@ -152,6 +165,24 @@ bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectS
|
||||
results << ValidationResult( QgsProjectServerValidator::ProjectShortName, rootLayerName );
|
||||
}
|
||||
}
|
||||
if ( isOnlyMaptipEnabled( project ) )
|
||||
{
|
||||
QStringList emptyLayers;
|
||||
for ( int i = 0; i < maptipTemplates.size(); ++i )
|
||||
{
|
||||
if ( maptipTemplates[i].trimmed().isEmpty() )
|
||||
emptyLayers << layerNames[i];
|
||||
}
|
||||
|
||||
if ( !emptyLayers.isEmpty() )
|
||||
{
|
||||
result = false;
|
||||
QString details = emptyLayers.join( QLatin1String( ", " ) ).toHtmlEscaped();
|
||||
results << ValidationResult(
|
||||
QgsProjectServerValidator::OnlyMaptipTrueButEmptyMaptip,
|
||||
details );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class CORE_EXPORT QgsProjectServerValidator
|
||||
LayerEncoding = 2, //!< Encoding is not correctly set on a vector layer.
|
||||
ProjectShortName = 3, //!< The project short name is not valid.
|
||||
ProjectRootNameConflict = 4, //!< The project root name is already used by a layer or a group.
|
||||
OnlyMaptipTrueButEmptyMaptip = 5, //!< Use only maptip for HTML GetFeatureInfo response is enabled but HTML maptip is empty
|
||||
};
|
||||
|
||||
/**
|
||||
@ -92,7 +93,8 @@ class CORE_EXPORT QgsProjectServerValidator
|
||||
static bool validate( QgsProject *project, QList< QgsProjectServerValidator::ValidationResult > &results SIP_OUT );
|
||||
|
||||
private:
|
||||
static void browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages );
|
||||
static void browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages, QStringList &layerNames, QStringList &maptipTemplates );
|
||||
static bool isOnlyMaptipEnabled( QgsProject *project );
|
||||
|
||||
};
|
||||
|
||||
|
@ -180,6 +180,12 @@ bool QgsServerProjectUtils::wmsFeatureInfoUseAttributeFormSettings( const QgsPro
|
||||
|| useFormSettings.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
|
||||
}
|
||||
|
||||
bool QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project )
|
||||
{
|
||||
const QString useFormSettings = project.readEntry( QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ), QStringLiteral( "/" ), "" );
|
||||
return useFormSettings.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0;
|
||||
}
|
||||
|
||||
bool QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project )
|
||||
{
|
||||
const QString segmGeom = project.readEntry( QStringLiteral( "WMSSegmentizeFeatureInfoGeometry" ), QStringLiteral( "/" ), "" );
|
||||
|
@ -222,6 +222,16 @@ class SERVER_EXPORT QgsServerProjectUtils
|
||||
*/
|
||||
static bool wmsFeatureInfoUseAttributeFormSettings( const QgsProject &project );
|
||||
|
||||
/**
|
||||
* Returns if only the maptip should be used for HTML feature info response so
|
||||
* that the HTML response to the feature info request only contains the maptip.
|
||||
* If no maptip is set, the HTML response is empty.
|
||||
* \param project the QGIS project
|
||||
* \returns true if only the maptip should be used for the feature info response only
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project );
|
||||
|
||||
/**
|
||||
* Returns if the geometry has to be segmentize in GetFeatureInfo request.
|
||||
* \param project the QGIS project
|
||||
|
@ -2009,7 +2009,7 @@ namespace QgsWms
|
||||
|
||||
//add maptip attribute based on html/expression (in case there is no maptip attribute)
|
||||
QString mapTip = layer->mapTipTemplate();
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() ) )
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() || QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( *mProject ) ) )
|
||||
{
|
||||
QDomElement maptipElem = infoDocument.createElement( QStringLiteral( "Attribute" ) );
|
||||
maptipElem.setAttribute( QStringLiteral( "name" ), QStringLiteral( "maptip" ) );
|
||||
@ -2325,7 +2325,7 @@ namespace QgsWms
|
||||
}
|
||||
//add maptip attribute based on html/expression
|
||||
QString mapTip = layer->mapTipTemplate();
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() ) )
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() || QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( *mProject ) ) )
|
||||
{
|
||||
QDomElement maptipElem = infoDocument.createElement( QStringLiteral( "Attribute" ) );
|
||||
maptipElem.setAttribute( QStringLiteral( "name" ), QStringLiteral( "maptip" ) );
|
||||
@ -2586,7 +2586,7 @@ namespace QgsWms
|
||||
|
||||
QByteArray QgsRenderer::convertFeatureInfoToHtml( const QDomDocument &doc ) const
|
||||
{
|
||||
const bool onlyMapTip = mWmsParameters.htmlInfoOnlyMapTip();
|
||||
const bool onlyMapTip = mWmsParameters.htmlInfoOnlyMapTip() || QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( *mProject );
|
||||
QString featureInfoString = QStringLiteral( " <!DOCTYPE html>" );
|
||||
if ( !onlyMapTip )
|
||||
{
|
||||
@ -3203,7 +3203,7 @@ namespace QgsWms
|
||||
{
|
||||
QString mapTip = layer->mapTipTemplate();
|
||||
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() ) )
|
||||
if ( !mapTip.isEmpty() && ( mWmsParameters.withMapTip() || mWmsParameters.htmlInfoOnlyMapTip() || QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( *mProject ) ) )
|
||||
{
|
||||
QString fieldTextString = QgsExpression::replaceExpressionText( mapTip, &expressionContext );
|
||||
QDomElement fieldElem = doc.createElement( QStringLiteral( "qgs:maptip" ) );
|
||||
|
@ -2730,6 +2730,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="mHTMLFiOnlyMaptip">
|
||||
<property name="text">
|
||||
<string>Use only maptip for HTML GetFeatureInfo (empty response when maptip template is missing)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="mWmsUseLayerIDs">
|
||||
<property name="text">
|
||||
@ -2737,7 +2744,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<layout class="QHBoxLayout" name="grpWMSPrecision">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
@ -2761,21 +2768,21 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="mSegmentizeFeatureInfoGeometryCheckBox">
|
||||
<property name="text">
|
||||
<string>Segmentize feature info geometry</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="mAddWktGeometryCheckBox">
|
||||
<property name="text">
|
||||
<string>Add geometry to feature response</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="mWMSUrlLabel">
|
||||
@ -3765,6 +3772,7 @@
|
||||
<tabstop>mWMSInspireMetadataDate</tabstop>
|
||||
<tabstop>mWmsUseLayerIDs</tabstop>
|
||||
<tabstop>mUseAttributeFormSettingsCheckBox</tabstop>
|
||||
<tabstop>mHTMLFiOnlyMaptip</tabstop>
|
||||
<tabstop>mAddWktGeometryCheckBox</tabstop>
|
||||
<tabstop>mSegmentizeFeatureInfoGeometryCheckBox</tabstop>
|
||||
<tabstop>mWMSPrecisionSpinBox</tabstop>
|
||||
|
@ -65,84 +65,6 @@ class TestQgsProject(QgisTestCase):
|
||||
QgisTestCase.__init__(self, methodName)
|
||||
self.messageCaught = False
|
||||
|
||||
def test_makeKeyTokens_(self):
|
||||
# see http://www.w3.org/TR/REC-xml/#d0e804 for a list of valid characters
|
||||
|
||||
invalidTokens = []
|
||||
validTokens = []
|
||||
|
||||
# all test tokens will be generated by prepending or inserting characters to this token
|
||||
validBase = "valid"
|
||||
|
||||
# some invalid characters, not allowed anywhere in a token
|
||||
# note that '/' must not be added here because it is taken as a separator by makeKeyTokens_()
|
||||
invalidChars = "+*,;<>|!$%()=?#\x01"
|
||||
|
||||
# generate the characters that are allowed at the start of a token (and at every other position)
|
||||
validStartChars = ":_"
|
||||
charRanges = [
|
||||
(ord("a"), ord("z")),
|
||||
(ord("A"), ord("Z")),
|
||||
(0x00F8, 0x02FF),
|
||||
(0x0370, 0x037D),
|
||||
(0x037F, 0x1FFF),
|
||||
(0x200C, 0x200D),
|
||||
(0x2070, 0x218F),
|
||||
(0x2C00, 0x2FEF),
|
||||
(0x3001, 0xD7FF),
|
||||
(0xF900, 0xFDCF),
|
||||
(0xFDF0, 0xFFFD),
|
||||
# (0x10000, 0xEFFFF), while actually valid, these are not yet accepted by makeKeyTokens_()
|
||||
]
|
||||
for r in charRanges:
|
||||
for c in range(r[0], r[1]):
|
||||
validStartChars += chr(c)
|
||||
|
||||
# generate the characters that are only allowed inside a token, not at the start
|
||||
validInlineChars = "-.\xB7"
|
||||
charRanges = [
|
||||
(ord("0"), ord("9")),
|
||||
(0x0300, 0x036F),
|
||||
(0x203F, 0x2040),
|
||||
]
|
||||
for r in charRanges:
|
||||
for c in range(r[0], r[1]):
|
||||
validInlineChars += chr(c)
|
||||
|
||||
# test forbidden start characters
|
||||
for c in invalidChars + validInlineChars:
|
||||
invalidTokens.append(c + validBase)
|
||||
|
||||
# test forbidden inline characters
|
||||
for c in invalidChars:
|
||||
invalidTokens.append(validBase[:4] + c + validBase[4:])
|
||||
|
||||
# test each allowed start character
|
||||
for c in validStartChars:
|
||||
validTokens.append(c + validBase)
|
||||
|
||||
# test each allowed inline character
|
||||
for c in validInlineChars:
|
||||
validTokens.append(validBase[:4] + c + validBase[4:])
|
||||
|
||||
logger = QgsApplication.messageLog()
|
||||
logger.messageReceived.connect(self.catchMessage)
|
||||
prj = QgsProject.instance()
|
||||
|
||||
for token in validTokens:
|
||||
self.messageCaught = False
|
||||
prj.readEntry("test", token)
|
||||
myMessage = f"valid token '{token}' not accepted"
|
||||
assert not self.messageCaught, myMessage
|
||||
|
||||
for token in invalidTokens:
|
||||
self.messageCaught = False
|
||||
prj.readEntry("test", token)
|
||||
myMessage = f"invalid token '{token}' accepted"
|
||||
assert self.messageCaught, myMessage
|
||||
|
||||
logger.messageReceived.disconnect(self.catchMessage)
|
||||
|
||||
def catchMessage(self):
|
||||
self.messageCaught = True
|
||||
|
||||
|
@ -124,6 +124,60 @@ class TestQgsprojectServerValidator(QgisTestCase):
|
||||
results[0].error,
|
||||
)
|
||||
|
||||
def test_empty_maptip_enabled(self):
|
||||
"""Empty maptip must fail when only‐maptip is enabled."""
|
||||
project = QgsProject()
|
||||
layer = QgsVectorLayer("Point?field=fldtxt:string", "testlayer", "memory")
|
||||
project.addMapLayers([layer])
|
||||
layer.setMapTipTemplate("")
|
||||
project.writeEntry("WMSHTMLFeatureInfoUseOnlyMaptip", "", True)
|
||||
valid, results = QgsProjectServerValidator.validate(project)
|
||||
self.assertFalse(valid)
|
||||
self.assertEqual(1, len(results))
|
||||
self.assertEqual(
|
||||
QgsProjectServerValidator.ValidationError.OnlyMaptipTrueButEmptyMaptip,
|
||||
results[0].error,
|
||||
)
|
||||
# Explicitly enable MapTips — should still fail
|
||||
layer.setMapTipsEnabled(True)
|
||||
valid2, results2 = QgsProjectServerValidator.validate(project)
|
||||
self.assertFalse(valid2)
|
||||
self.assertEqual(1, len(results2))
|
||||
self.assertEqual(
|
||||
QgsProjectServerValidator.ValidationError.OnlyMaptipTrueButEmptyMaptip,
|
||||
results2[0].error,
|
||||
)
|
||||
# Explicitly disable MapTips — should still fail
|
||||
layer.setMapTipsEnabled(False)
|
||||
valid3, results3 = QgsProjectServerValidator.validate(project)
|
||||
self.assertFalse(valid3)
|
||||
self.assertEqual(1, len(results3))
|
||||
self.assertEqual(
|
||||
QgsProjectServerValidator.ValidationError.OnlyMaptipTrueButEmptyMaptip,
|
||||
results3[0].error,
|
||||
)
|
||||
|
||||
def test_empty_maptip_disabled(self):
|
||||
"""Empty maptip must pass when only‐maptip is disabled."""
|
||||
project = QgsProject()
|
||||
layer = QgsVectorLayer("Point?field=fldtxt:string", "testlayer", "memory")
|
||||
project.addMapLayers([layer])
|
||||
layer.setMapTipTemplate("")
|
||||
project.writeEntry("WMSHTMLFeatureInfoUseOnlyMaptip", "", False)
|
||||
valid, results = QgsProjectServerValidator.validate(project)
|
||||
self.assertTrue(valid)
|
||||
self.assertEqual(0, len(results))
|
||||
# Explicitly enable MapTips — should still pass
|
||||
layer.setMapTipsEnabled(True)
|
||||
valid2, results2 = QgsProjectServerValidator.validate(project)
|
||||
self.assertTrue(valid2)
|
||||
self.assertEqual(0, len(results2))
|
||||
# Explicitly disable MapTips — should still pass
|
||||
layer.setMapTipsEnabled(False)
|
||||
valid3, results3 = QgsProjectServerValidator.validate(project)
|
||||
self.assertTrue(valid3)
|
||||
self.assertEqual(0, len(results3))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -174,7 +174,7 @@ class TestQgsServerWMSGetFeatureInfo(TestQgsServerWMSTestBase):
|
||||
"wms_getfeatureinfo-text-html-maptip",
|
||||
)
|
||||
|
||||
# Test getfeatureinfo response html only with maptip for vector layer
|
||||
# Test getfeatureinfo response html only with maptip for vector layer (URL parameter)
|
||||
self.wms_request_compare(
|
||||
"GetFeatureInfo",
|
||||
"&layers=testlayer%20%C3%A8%C3%A9&styles=&"
|
||||
@ -186,6 +186,18 @@ class TestQgsServerWMSGetFeatureInfo(TestQgsServerWMSTestBase):
|
||||
"wms_getfeatureinfo-html-only-with-maptip-vector",
|
||||
)
|
||||
|
||||
# Test getfeatureinfo response html only with maptip for vector layer (project settings)
|
||||
self.wms_request_compare(
|
||||
"GetFeatureInfo",
|
||||
"&layers=testlayer%20%C3%A8%C3%A9&styles=&"
|
||||
+ "info_format=text%2Fhtml&transparent=true&"
|
||||
+ "width=600&height=400&srs=EPSG%3A3857&bbox=913190.6389747962%2C"
|
||||
+ "5606005.488876367%2C913235.426296057%2C5606035.347090538&"
|
||||
+ "query_layers=testlayer%20%C3%A8%C3%A9&X=190&Y=320",
|
||||
"wms_getfeatureinfo-html-only-with-maptip-vector",
|
||||
"test_project_html_gfi_maptip_only.qgs",
|
||||
)
|
||||
|
||||
# Test getfeatureinfo response html with maptip and display name in text mode for vector layer
|
||||
self.wms_request_compare(
|
||||
"GetFeatureInfo",
|
||||
@ -352,7 +364,7 @@ class TestQgsServerWMSGetFeatureInfo(TestQgsServerWMSTestBase):
|
||||
"wms_getfeatureinfo-raster-text-xml-maptip",
|
||||
)
|
||||
|
||||
# Test GetFeatureInfo on raster layer HTML only with maptip
|
||||
# Test GetFeatureInfo on raster layer HTML only with maptip (URL parameter)
|
||||
self.wms_request_compare(
|
||||
"GetFeatureInfo",
|
||||
"&layers=landsat&styles=&"
|
||||
@ -364,6 +376,18 @@ class TestQgsServerWMSGetFeatureInfo(TestQgsServerWMSTestBase):
|
||||
"wms_getfeatureinfo-html-only-with-maptip-raster",
|
||||
)
|
||||
|
||||
# Test GetFeatureInfo on raster layer HTML only with maptip (project settings)
|
||||
self.wms_request_compare(
|
||||
"GetFeatureInfo",
|
||||
"&layers=landsat&styles=&"
|
||||
+ "info_format=text%2Fhtml&transparent=true&"
|
||||
+ "width=500&height=500&srs=EPSG%3A3857&"
|
||||
+ "bbox=1989139.6,3522745.0,2015014.9,3537004.5&"
|
||||
+ "query_layers=landsat&X=250&Y=250",
|
||||
"wms_getfeatureinfo-html-only-with-maptip-raster",
|
||||
"test_project_html_gfi_maptip_only.qgs",
|
||||
)
|
||||
|
||||
def testGetFeatureInfoValueRelation(self):
|
||||
"""Test GetFeatureInfo resolves "value relation" widget values. regression 18518"""
|
||||
mypath = self.testdata_path + "test_project_values.qgz"
|
||||
|
4860
tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs
vendored
Normal file
4860
tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user