From 52a05a08bd8b1396b6a40cd60edbe5d9dd1293c9 Mon Sep 17 00:00:00 2001 From: pathmapper Date: Fri, 6 Jun 2025 10:10:55 +0200 Subject: [PATCH 1/7] Add project setting to enable HTML GetFeatureInfo maptip-only mode --- .../auto_additions/qgsserverprojectutils.py | 1 + .../qgsserverprojectutils.sip.in | 12 + .../auto_additions/qgsserverprojectutils.py | 1 + .../qgsserverprojectutils.sip.in | 12 + src/app/qgsprojectproperties.cpp | 4 + src/server/qgsserverprojectutils.cpp | 7 + src/server/qgsserverprojectutils.h | 8 + src/server/services/wms/qgswmsrenderer.cpp | 8 +- src/ui/qgsprojectpropertiesbase.ui | 16 +- .../test_qgsserver_wms_getfeatureinfo.py | 28 +- .../test_project_html_gfi_maptip_only.qgs | 4860 +++++++++++++++++ 11 files changed, 4947 insertions(+), 10 deletions(-) create mode 100644 tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs diff --git a/python/PyQt6/server/auto_additions/qgsserverprojectutils.py b/python/PyQt6/server/auto_additions/qgsserverprojectutils.py index 5a3774350a9..72fdf8a9f5b 100644 --- a/python/PyQt6/server/auto_additions/qgsserverprojectutils.py +++ b/python/PyQt6/server/auto_additions/qgsserverprojectutils.py @@ -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) diff --git a/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in b/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in index 9e3c3a24954..8e2fc0b21ef 100644 --- a/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in +++ b/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in @@ -252,6 +252,18 @@ the feature info response feature info response %End + static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project ); +%Docstring +Returns if only maptip should be used for HTML feature info response + +: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. diff --git a/python/server/auto_additions/qgsserverprojectutils.py b/python/server/auto_additions/qgsserverprojectutils.py index 5a3774350a9..72fdf8a9f5b 100644 --- a/python/server/auto_additions/qgsserverprojectutils.py +++ b/python/server/auto_additions/qgsserverprojectutils.py @@ -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) diff --git a/python/server/auto_generated/qgsserverprojectutils.sip.in b/python/server/auto_generated/qgsserverprojectutils.sip.in index 9e3c3a24954..8e2fc0b21ef 100644 --- a/python/server/auto_generated/qgsserverprojectutils.sip.in +++ b/python/server/auto_generated/qgsserverprojectutils.sip.in @@ -252,6 +252,18 @@ the feature info response feature info response %End + static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project ); +%Docstring +Returns if only maptip should be used for HTML feature info response + +: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. diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index e0703def270..d2ebe2814c0 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -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() ); diff --git a/src/server/qgsserverprojectutils.cpp b/src/server/qgsserverprojectutils.cpp index 1c4213ec68d..7335d8e188a 100644 --- a/src/server/qgsserverprojectutils.cpp +++ b/src/server/qgsserverprojectutils.cpp @@ -180,6 +180,13 @@ 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( "enabled" ), Qt::CaseInsensitive ) == 0 + || useFormSettings.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0; +} + bool QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project ) { const QString segmGeom = project.readEntry( QStringLiteral( "WMSSegmentizeFeatureInfoGeometry" ), QStringLiteral( "/" ), "" ); diff --git a/src/server/qgsserverprojectutils.h b/src/server/qgsserverprojectutils.h index 27f96919b24..9781b2e6ba1 100644 --- a/src/server/qgsserverprojectutils.h +++ b/src/server/qgsserverprojectutils.h @@ -222,6 +222,14 @@ class SERVER_EXPORT QgsServerProjectUtils */ static bool wmsFeatureInfoUseAttributeFormSettings( const QgsProject &project ); + /** + * Returns if only maptip should be used for HTML feature info response + * \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 diff --git a/src/server/services/wms/qgswmsrenderer.cpp b/src/server/services/wms/qgswmsrenderer.cpp index a0e5fe2a110..11ed2f088c4 100644 --- a/src/server/services/wms/qgswmsrenderer.cpp +++ b/src/server/services/wms/qgswmsrenderer.cpp @@ -2005,7 +2005,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" ) ); @@ -2321,7 +2321,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" ) ); @@ -2582,7 +2582,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( " " ); if ( !onlyMapTip ) { @@ -3199,7 +3199,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" ) ); diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index ed690d324df..0b113f78241 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -2730,6 +2730,13 @@ + + + + Use maptip only for HTML GetFeatureInfo response + + + @@ -2737,7 +2744,7 @@ - + @@ -2761,21 +2768,21 @@ - + Segmentize feature info geometry - + Add geometry to feature response - + @@ -3765,6 +3772,7 @@ mWMSInspireMetadataDate mWmsUseLayerIDs mUseAttributeFormSettingsCheckBox + mHTMLFiOnlyMaptip mAddWktGeometryCheckBox mSegmentizeFeatureInfoGeometryCheckBox mWMSPrecisionSpinBox diff --git a/tests/src/python/test_qgsserver_wms_getfeatureinfo.py b/tests/src/python/test_qgsserver_wms_getfeatureinfo.py index e733deda347..e531b4969d3 100644 --- a/tests/src/python/test_qgsserver_wms_getfeatureinfo.py +++ b/tests/src/python/test_qgsserver_wms_getfeatureinfo.py @@ -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" diff --git a/tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs b/tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs new file mode 100644 index 00000000000..61fddf548d6 --- /dev/null +++ b/tests/testdata/qgis_server/test_project_html_gfi_maptip_only.qgs @@ -0,0 +1,4860 @@ + + + + QGIS Test Project + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://groupmetadata1.com + http://groupmetadata1.com + + group_name + Group title + Group abstract + + keyword1 + keyword2 + + http://mydataurl.com + http://mylegendurl.com + Attribution Title + + + + + + + + + + + + + + + + + + + testlayer20150528120452665 + testlayer_c0988fd7_97ca_451d_adbc_37ad6d10583a + testlayer_0b835118_a5d5_4255_b5dd_f42253c0a4a0 + testlayer_2b89ed65_ef2f_4897_af15_9b32d4c4e040 + testlayer_èé_cf86cf11_222f_4b62_929c_12cfc82b9774 + testlayer_èé_2_a5f61891_b949_43e3_ad30_84013fc922de + landsat_a7d15b35_ca83_4b23_a9fb_af3fbdd60d15 + testlayer2024010401 + testlayer2024010402 + + + + + + + + + + + + + + + + degrees + + 17.92123882869385909 + 30.1492204088525888 + 18.0486921925404431 + 30.25992437587047235 + + 0 + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Annotations_5cf31e47_572b_45e7_a02d_14ff92c67510 + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + 1 + 0 + + + + + + 781662.375 + 3339523.125 + 793062.375 + 3350923.125 + + + 17.92427343259496908 + 30.15185621759111001 + 18.04565758863933667 + 30.25728856713202219 + + landsat_a7d15b35_ca83_4b23_a9fb_af3fbdd60d15 + ../landsat.tif + landsat + + + PROJCRS["WGS 84 / UTM zone 33N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 33N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Navigation and medium accuracy spatial referencing."],AREA["Between 12°E and 18°E, northern hemisphere between equator and 84°N, onshore and offshore. Austria. Bosnia and Herzegovina. Cameroon. Central African Republic. Chad. Congo. Croatia. Czechia. Democratic Republic of the Congo (Zaire). Gabon. Germany. Hungary. Italy. Libya. Malta. Niger. Nigeria. Norway. Poland. San Marino. Slovakia. Slovenia. Svalbard. Sweden. Vatican City State."],BBOX[0,12,84,18]],ID["EPSG",32633]] + +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs + 3117 + 32633 + EPSG:32633 + WGS 84 / UTM zone 33N + utm + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / UTM zone 33N",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 33N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Navigation and medium accuracy spatial referencing."],AREA["Between 12°E and 18°E, northern hemisphere between equator and 84°N, onshore and offshore. Austria. Bosnia and Herzegovina. Cameroon. Central African Republic. Chad. Congo. Croatia. Czechia. Democratic Republic of the Congo (Zaire). Gabon. Germany. Hungary. Italy. Libya. Malta. Niger. Nigeria. Norway. Poland. San Marino. Slovakia. Slovenia. Svalbard. Sweden. Vatican City State."],BBOX[0,12,84,18]],ID["EPSG",32633]] + +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs + 3117 + 32633 + EPSG:32633 + WGS 84 / UTM zone 33N + utm + EPSG:7030 + false + + + + + + + + + + + + + + + + + gdal + + + + + + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <title>Maptip</title> +[% 'Value Band 5: ' || raster_value(@layer_id, 5, @layer_cursor_point) %] + + + + + + + + + + + MinMax + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + 122 + 130 + StretchToMinimumMaximum + + + + + + + + + + + resamplingFilter + + 0 + + + testlayer20150528120452665 + ./testlayer.shp + testlayer èé + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + A test vector layer + A test vector layer with unicode òà + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + <title>Maptip</title> +[% 'Name: ' || represent_value( "name" ) %] + + + testlayer2024010401 + ./testlayer_tag_chars.shp + <test layer name> + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + A test vector layer with <tag> chars without title + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + [% 'Name: ' || represent_value( "name" ) %] + + + testlayer2024010402 + ./testlayer_tag_chars.shp + <test layer title> + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + <title> + A test vector layer with <tag> chars with title + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + [% 'Name: ' || represent_value( "name" ) %] + + + testlayer_0b835118_a5d5_4255_b5dd_f42253c0a4a0 + ./testlayer.shp + testlayer3 + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + ogr + + + + + + + + + + 0 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + + + 0 + generatedlayout + + + + + + + + + + testlayer_2b89ed65_ef2f_4897_af15_9b32d4c4e040 + ./testlayer.shp + testlayer2 + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + + + 0 + generatedlayout + + + + + + + + + + + + + + id + + + + testlayer_c0988fd7_97ca_451d_adbc_37ad6d10583a + ./testlayer.shp + testlayer + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + https://my.other.url + https://some.data.com + + layer_with_short_name + A Layer with a short name + A Layer with an abstract + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + "id" + + + + testlayer_èé_2_a5f61891_b949_43e3_ad30_84013fc922de + ./testlayer.shp + exclude_attribute + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + A test vector layer + A test vector layer with unicode òà + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + name + [% 'Name: ' || "name" %] + + + testlayer_èé_cf86cf11_222f_4b62_929c_12cfc82b9774 + ./testlayer.shp + fields_alias + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + A test vector layer + A test vector layer with unicode òà + + + + ogr + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + name + [% 'Name: ' || "name" %] + + + + + + + + + + + + + + + + + + + 2 + 0 + 2 + off + + + + + + current_layer + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + + testlayer_0b835118_a5d5_4255_b5dd_f42253c0a4a0 + + + + false + + + + + + WGS84 + + + m2 + meters + + + 50 + 5 + 16 + 30 + 2.5 + false + true + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255,rgb:1,0,0,1 + + + false + + + true + 2 + D + + + + + + 3452 + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 1 + + + + + + + + + testlayer20150528120452665 + + + 8 + + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + + + None + true + elpaso@itopen.it + QGIS dev team + Alessandro Pasotti + + + + 8.20315414376310059 + 44.901236559338642 + 8.204164917965862 + 44.90159838674664172 + + conditions unknown + true + 90 + + + + + 4 + false + + + false + Some UTF8 text èòù + true + QGIS TestProject + + false + + + + + + + + + + + + QGIS Test Project + + + + + + + + + + + + + + + + 2000-01-01T00:00:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + From 30798bb4628c1e29ed55c79c775232cda49ce480 Mon Sep 17 00:00:00 2001 From: pathmapper Date: Fri, 6 Jun 2025 10:24:14 +0200 Subject: [PATCH 2/7] Better wording --- src/ui/qgsprojectpropertiesbase.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index 0b113f78241..1b80ee9ce57 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -2733,7 +2733,7 @@ - Use maptip only for HTML GetFeatureInfo response + Use only maptip for HTML GetFeatureInfo response From 37b2f2257d3afcfef5d7257590a1c5b4e29fd7cb Mon Sep 17 00:00:00 2001 From: pathmapper Date: Fri, 6 Jun 2025 14:25:00 +0200 Subject: [PATCH 3/7] Address code review comments --- .../PyQt6/server/auto_generated/qgsserverprojectutils.sip.in | 4 +++- python/server/auto_generated/qgsserverprojectutils.sip.in | 4 +++- src/server/qgsserverprojectutils.cpp | 3 +-- src/server/qgsserverprojectutils.h | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in b/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in index 8e2fc0b21ef..62693e1f987 100644 --- a/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in +++ b/python/PyQt6/server/auto_generated/qgsserverprojectutils.sip.in @@ -254,7 +254,9 @@ the feature info response static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project ); %Docstring -Returns if only maptip should be used for HTML feature info response +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 diff --git a/python/server/auto_generated/qgsserverprojectutils.sip.in b/python/server/auto_generated/qgsserverprojectutils.sip.in index 8e2fc0b21ef..62693e1f987 100644 --- a/python/server/auto_generated/qgsserverprojectutils.sip.in +++ b/python/server/auto_generated/qgsserverprojectutils.sip.in @@ -254,7 +254,9 @@ the feature info response static bool wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project ); %Docstring -Returns if only maptip should be used for HTML feature info response +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 diff --git a/src/server/qgsserverprojectutils.cpp b/src/server/qgsserverprojectutils.cpp index 7335d8e188a..8dc3dbe3471 100644 --- a/src/server/qgsserverprojectutils.cpp +++ b/src/server/qgsserverprojectutils.cpp @@ -183,8 +183,7 @@ bool QgsServerProjectUtils::wmsFeatureInfoUseAttributeFormSettings( const QgsPro bool QgsServerProjectUtils::wmsHTMLFeatureInfoUseOnlyMaptip( const QgsProject &project ) { const QString useFormSettings = project.readEntry( QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ), QStringLiteral( "/" ), "" ); - return useFormSettings.compare( QLatin1String( "enabled" ), Qt::CaseInsensitive ) == 0 - || useFormSettings.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0; + return useFormSettings.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0; } bool QgsServerProjectUtils::wmsFeatureInfoSegmentizeWktGeometry( const QgsProject &project ) diff --git a/src/server/qgsserverprojectutils.h b/src/server/qgsserverprojectutils.h index 9781b2e6ba1..4efdf678e2e 100644 --- a/src/server/qgsserverprojectutils.h +++ b/src/server/qgsserverprojectutils.h @@ -223,7 +223,9 @@ class SERVER_EXPORT QgsServerProjectUtils static bool wmsFeatureInfoUseAttributeFormSettings( const QgsProject &project ); /** - * Returns if only maptip should be used for HTML feature info response + * 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 From 7181b40deacd8904948f60ab9dc34028c3ffda49 Mon Sep 17 00:00:00 2001 From: pathmapper Date: Mon, 9 Jun 2025 10:15:16 +0200 Subject: [PATCH 4/7] Add check for empty maptips to the project validator --- .../qgsprojectservervalidator.py | 1 + .../project/qgsprojectservervalidator.sip.in | 1 + .../project/qgsprojectservervalidator.sip.in | 1 + .../project/qgsprojectservervalidator.cpp | 39 +++++++++++++++++-- src/core/project/qgsprojectservervalidator.h | 4 +- .../python/test_qgsprojectservervalidator.py | 26 +++++++++++++ 6 files changed, 67 insertions(+), 5 deletions(-) diff --git a/python/PyQt6/core/auto_additions/qgsprojectservervalidator.py b/python/PyQt6/core/auto_additions/qgsprojectservervalidator.py index d1c898a538c..1e085fe3b89 100644 --- a/python/PyQt6/core/auto_additions/qgsprojectservervalidator.py +++ b/python/PyQt6/core/auto_additions/qgsprojectservervalidator.py @@ -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'} diff --git a/python/PyQt6/core/auto_generated/project/qgsprojectservervalidator.sip.in b/python/PyQt6/core/auto_generated/project/qgsprojectservervalidator.sip.in index 7701768f613..e74bda0dcf3 100644 --- a/python/PyQt6/core/auto_generated/project/qgsprojectservervalidator.sip.in +++ b/python/PyQt6/core/auto_generated/project/qgsprojectservervalidator.sip.in @@ -33,6 +33,7 @@ project. LayerEncoding, ProjectShortName, ProjectRootNameConflict, + OnlyMaptipTrueButEmptyMaptip, }; static QString displayValidationError( QgsProjectServerValidator::ValidationError error ); diff --git a/python/core/auto_generated/project/qgsprojectservervalidator.sip.in b/python/core/auto_generated/project/qgsprojectservervalidator.sip.in index d12e6923fb3..053be4b393f 100644 --- a/python/core/auto_generated/project/qgsprojectservervalidator.sip.in +++ b/python/core/auto_generated/project/qgsprojectservervalidator.sip.in @@ -33,6 +33,7 @@ project. LayerEncoding, ProjectShortName, ProjectRootNameConflict, + OnlyMaptipTrueButEmptyMaptip, }; static QString displayValidationError( QgsProjectServerValidator::ValidationError error ); diff --git a/src/core/project/qgsprojectservervalidator.cpp b/src/core/project/qgsprojectservervalidator.cpp index fab5f10d81a..38b7b8df2ee 100644 --- a/src/core/project/qgsprojectservervalidator.cpp +++ b/src/core/project/qgsprojectservervalidator.cpp @@ -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( 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" ), + QStringLiteral( "" ), + false + ); +} + bool QgsProjectServerValidator::validate( QgsProject *project, QList &results ) { results.clear(); @@ -90,8 +103,8 @@ bool QgsProjectServerValidator::validate( QgsProject *project, QListlayerTreeRoot() ) 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 &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 ); }; diff --git a/tests/src/python/test_qgsprojectservervalidator.py b/tests/src/python/test_qgsprojectservervalidator.py index 7747e304e23..763d63810a0 100644 --- a/tests/src/python/test_qgsprojectservervalidator.py +++ b/tests/src/python/test_qgsprojectservervalidator.py @@ -124,6 +124,32 @@ 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, + ) + + 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)) + if __name__ == "__main__": unittest.main() From a36f64edba3f3f8eacc59e6ade1b32db7d0cb516 Mon Sep 17 00:00:00 2001 From: pathmapper Date: Mon, 9 Jun 2025 10:21:08 +0200 Subject: [PATCH 5/7] Update option description in UI --- src/ui/qgsprojectpropertiesbase.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index 1b80ee9ce57..892c828c271 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -2733,7 +2733,7 @@ - Use only maptip for HTML GetFeatureInfo response + Use only maptip for HTML GetFeatureInfo (empty response when maptip template is missing) From c3641ecdadeb091a0644173ec55175bffd51ae19 Mon Sep 17 00:00:00 2001 From: pathmapper Date: Mon, 9 Jun 2025 10:37:50 +0200 Subject: [PATCH 6/7] Fix test --- src/core/project/qgsprojectservervalidator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/project/qgsprojectservervalidator.cpp b/src/core/project/qgsprojectservervalidator.cpp index 38b7b8df2ee..8076486d9a7 100644 --- a/src/core/project/qgsprojectservervalidator.cpp +++ b/src/core/project/qgsprojectservervalidator.cpp @@ -87,7 +87,7 @@ bool QgsProjectServerValidator::isOnlyMaptipEnabled( QgsProject *project ) { return project->readBoolEntry( QStringLiteral( "WMSHTMLFeatureInfoUseOnlyMaptip" ), - QStringLiteral( "" ), + QString(), false ); } From 24bbdda53918b2c234f01cadd1f1b3b7c61b38ff Mon Sep 17 00:00:00 2001 From: pathmapper Date: Thu, 12 Jun 2025 12:50:30 +0200 Subject: [PATCH 7/7] Add tests for explicitly enabling and disabling maptips --- .../python/test_qgsprojectservervalidator.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/src/python/test_qgsprojectservervalidator.py b/tests/src/python/test_qgsprojectservervalidator.py index 763d63810a0..d6c7e04dfb4 100644 --- a/tests/src/python/test_qgsprojectservervalidator.py +++ b/tests/src/python/test_qgsprojectservervalidator.py @@ -138,6 +138,24 @@ class TestQgsprojectServerValidator(QgisTestCase): 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.""" @@ -149,6 +167,16 @@ class TestQgsprojectServerValidator(QgisTestCase): 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__":