diff --git a/src/server/services/wms/qgswmsgetcapabilities.cpp b/src/server/services/wms/qgswmsgetcapabilities.cpp
index f5c67318b351..40aec3dc2ec3 100644
--- a/src/server/services/wms/qgswmsgetcapabilities.cpp
+++ b/src/server/services/wms/qgswmsgetcapabilities.cpp
@@ -1048,25 +1048,32 @@ namespace QgsWms
//min/max scale denominatorScaleBasedVisibility
if ( layerInfos.hasScaleBasedVisibility )
{
+ // Convert double to string and remove trailing zero and last point if present
+ auto formatScale = []( double value ) {
+ const thread_local QRegularExpression trailingZeroRegEx = QRegularExpression( QStringLiteral( "0+$" ) );
+ const thread_local QRegularExpression trailingPointRegEx = QRegularExpression( QStringLiteral( "[.]+$" ) );
+ return QString::number( value, 'f' ).remove( trailingZeroRegEx ).remove( trailingPointRegEx );
+ };
+
if ( version == QLatin1String( "1.1.1" ) )
{
double OGC_PX_M = 0.00028; // OGC reference pixel size in meter, also used by qgis
double SCALE_TO_SCALEHINT = OGC_PX_M * M_SQRT2;
QDomElement scaleHintElem = doc.createElement( QStringLiteral( "ScaleHint" ) );
- scaleHintElem.setAttribute( QStringLiteral( "min" ), QString::number( layerInfos.maxScale * SCALE_TO_SCALEHINT ) );
- scaleHintElem.setAttribute( QStringLiteral( "max" ), QString::number( layerInfos.minScale * SCALE_TO_SCALEHINT ) );
+ scaleHintElem.setAttribute( QStringLiteral( "min" ), formatScale( layerInfos.maxScale * SCALE_TO_SCALEHINT ) );
+ scaleHintElem.setAttribute( QStringLiteral( "max" ), formatScale( layerInfos.minScale * SCALE_TO_SCALEHINT ) );
layerElem.appendChild( scaleHintElem );
}
else
{
QDomElement minScaleElem = doc.createElement( QStringLiteral( "MinScaleDenominator" ) );
- QDomText minScaleText = doc.createTextNode( QString::number( layerInfos.maxScale ) );
+ QDomText minScaleText = doc.createTextNode( formatScale( layerInfos.maxScale ) );
minScaleElem.appendChild( minScaleText );
layerElem.appendChild( minScaleElem );
QDomElement maxScaleElem = doc.createElement( QStringLiteral( "MaxScaleDenominator" ) );
- QDomText maxScaleText = doc.createTextNode( QString::number( layerInfos.minScale ) );
+ QDomText maxScaleText = doc.createTextNode( formatScale( layerInfos.minScale ) );
maxScaleElem.appendChild( maxScaleText );
layerElem.appendChild( maxScaleElem );
}
diff --git a/tests/src/python/test_qgsserver_wms.py b/tests/src/python/test_qgsserver_wms.py
index 350aad722cb9..170fa053b968 100644
--- a/tests/src/python/test_qgsserver_wms.py
+++ b/tests/src/python/test_qgsserver_wms.py
@@ -183,6 +183,14 @@ def test_getcapabilities_advertised_url(self):
b"\n".join(headers) + b"\n\n" + bytes(response.body()), expected
)
+ def test_getcapabilities_scale_denominator(self):
+ self.wms_request_compare(
+ "GetCapabilities",
+ None,
+ "wms_getcapabilities_scale_denominator",
+ "test_project_scale_denominator.qgs",
+ )
+
def test_getprojectsettings(self):
self.wms_request_compare("GetProjectSettings")
diff --git a/tests/testdata/qgis_server/test_project_scale_denominator.qgs b/tests/testdata/qgis_server/test_project_scale_denominator.qgs
new file mode 100644
index 000000000000..19a6d57a842e
--- /dev/null
+++ b/tests/testdata/qgis_server/test_project_scale_denominator.qgs
@@ -0,0 +1,1051 @@
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - landsat_a7d15b35_ca83_4b23_a9fb_af3fbdd60d15
+
+
+
+
+
+
+
+
+ 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_a1301aec_86dc_423e_937b_836af57c34a4
+
+
+
+
+
+
+
+
+
+ 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.25728856713195825
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +proj=utm +zone=33 +datum=WGS84 +units=m +no_defs
+ 0
+ 0
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+ 2
+ 0
+ 2
+ off
+
+
+
+
+
+ current_layer
+
+
+ 255
+ 255
+ 255
+ 255
+ 0
+ 255
+ 255
+
+
+
+ testlayer_0b835118_a5d5_4255_b5dd_f42253c0a4a0
+
+
+
+
+
+
+
+ WGS84
+
+
+ m2
+ meters
+
+
+ 50
+ 5
+ 16
+ 30
+ 2.5
+ false
+ true
+ false
+ false
+ 0
+ 0
+ false
+ false
+ true
+ 0
+ 255,0,0,255
+
+
+ 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
+ 90
+
+
+
+
+ 4
+ false
+
+
+ false
+ 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
+
+
+
+
+
+
+
diff --git a/tests/testdata/qgis_server/wms_getcapabilities_scale_denominator.txt b/tests/testdata/qgis_server/wms_getcapabilities_scale_denominator.txt
new file mode 100644
index 000000000000..e0d56b20e979
--- /dev/null
+++ b/tests/testdata/qgis_server/wms_getcapabilities_scale_denominator.txt
@@ -0,0 +1,148 @@
+*****
+Content-Type: text/xml; charset=utf-8
+
+
+
+
+ WMS
+ QGIS TestProject
+
+ infoMapAccessService
+
+
+
+
+ Alessandro Pasotti
+ QGIS dev team
+
+ elpaso@itopen.it
+
+ conditions unknown
+ None
+
+
+
+
+ text/xml
+
+
+
+
+
+
+
+
+
+ image/jpeg
+ image/png
+ image/png; mode=16bit
+ image/png; mode=8bit
+ image/png; mode=1bit
+ application/dxf
+ application/pdf
+
+
+
+
+
+
+
+
+
+ text/plain
+ text/html
+ text/xml
+ application/vnd.ogc.gml
+ application/vnd.ogc.gml/3.1.1
+ application/json
+ application/geo+json
+
+
+
+
+
+
+
+
+
+ image/jpeg
+ image/png
+ application/json
+
+
+
+
+
+
+
+
+
+ text/xml
+
+
+
+
+
+
+
+
+
+ text/xml
+
+
+
+
+
+
+
+
+
+
+ XML
+
+
+
+ QGIS Test Project
+ QGIS TestProject
+
+ infoMapAccessService
+
+ CRS:84
+ EPSG:4326
+ EPSG:3857
+
+ 8.203154
+ 8.204165
+ 44.901236
+ 44.901599
+
+
+
+
+ landsat
+ landsat
+ CRS:84
+ EPSG:4326
+ EPSG:3857
+
+ 17.924273
+ 18.045658
+ 30.151856
+ 30.257289
+
+
+
+
+ 500.42
+ 1000000
+
+
+
+