Skip to content

Commit 98235eb

Browse files
committed
[Bugfix][Server] QGIS Server removes empty string in style parameter even if it describes default style
In OGC WMS standard, the empty string represents the default style. QGIS Server when it parses the parameters, QGIS Server when it parses parameters it removes empty parts. When all requested styles are default ones it's equal to an empty parameter STYLE, as defined in the standard. When only one layer is requested, there is no issue with custom or default style. When multiple layers are requested and some with custom styles, because QGIS Server does not retain empty strings, it loses the layer / style match. To fix it, keeps empty parts for not empty styles parameters.
1 parent 8703378 commit 98235eb

File tree

10 files changed

+89
-9
lines changed

10 files changed

+89
-9
lines changed

python/server/auto_generated/qgsserverparameters.sip.in

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ Converts the parameter into a string. If ``defaultValue`` is true
4949
and current value is empty, then the default value is returned.
5050
%End
5151

52-
QStringList toStringList( char delimiter = ',' ) const;
52+
QStringList toStringList( char delimiter = ',', bool skipEmptyParts = true ) const;
5353
%Docstring
54-
Converts the parameter into a list of strings.
54+
Converts the parameter into a list of strings
5555

5656
:param delimiter: The character used for delimiting
57+
:param skipEmptyParts: To use QString.SkipEmptyParts for splitting
5758

5859
:return: A list of strings
5960
%End

src/server/qgsserverparameters.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,21 @@ QString QgsServerParameterDefinition::toString( const bool defaultValue ) const
7272
return value;
7373
}
7474

75-
QStringList QgsServerParameterDefinition::toStringList( const char delimiter ) const
75+
QStringList QgsServerParameterDefinition::toStringList( const char delimiter, const bool skipEmptyParts ) const
7676
{
77-
return toString().split( delimiter, QString::SkipEmptyParts );
77+
if ( skipEmptyParts )
78+
{
79+
return toString().split( delimiter, QString::SkipEmptyParts );
80+
}
81+
else
82+
{
83+
QStringList list;
84+
if ( !toString().isEmpty() )
85+
{
86+
list = toString().split( delimiter, QString::KeepEmptyParts );
87+
}
88+
return list;
89+
}
7890
}
7991

8092
QList<QgsGeometry> QgsServerParameterDefinition::toGeomList( bool &ok, const char delimiter ) const

src/server/qgsserverparameters.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ class SERVER_EXPORT QgsServerParameterDefinition
6565
QString toString( bool defaultValue = false ) const;
6666

6767
/**
68-
* Converts the parameter into a list of strings.
68+
* Converts the parameter into a list of strings
6969
* \param delimiter The character used for delimiting
70+
* \param skipEmptyParts To use QString::SkipEmptyParts for splitting
7071
* \returns A list of strings
7172
*/
72-
QStringList toStringList( char delimiter = ',' ) const;
73+
QStringList toStringList( char delimiter = ',', bool skipEmptyParts = true ) const;
7374

7475
/**
7576
* Converts the parameter into a list of integers.

src/server/services/wms/qgswmsparameters.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ namespace QgsWms
4646
QgsServerParameterDefinition::raiseError( msg );
4747
}
4848

49+
QStringList QgsWmsParameter::toStyleList( const char delimiter ) const
50+
{
51+
return QgsServerParameterDefinition::toStringList( delimiter, false );
52+
}
53+
4954
QList<QgsGeometry> QgsWmsParameter::toGeomList( const char delimiter ) const
5055
{
5156
bool ok = true;
@@ -1368,8 +1373,8 @@ namespace QgsWms
13681373

13691374
QStringList QgsWmsParameters::allStyles() const
13701375
{
1371-
QStringList style = mWmsParameters[ QgsWmsParameter::STYLE ].toStringList();
1372-
const QStringList styles = mWmsParameters[ QgsWmsParameter::STYLES ].toStringList();
1376+
QStringList style = mWmsParameters[ QgsWmsParameter::STYLE ].toStyleList();
1377+
const QStringList styles = mWmsParameters[ QgsWmsParameter::STYLES ].toStyleList();
13731378
return style << styles;
13741379
}
13751380

@@ -1673,7 +1678,7 @@ namespace QgsWms
16731678
wmsParam = idParameter( QgsWmsParameter::STYLES, mapId );
16741679
if ( wmsParam.isValid() )
16751680
{
1676-
styles = wmsParam.toStringList();
1681+
styles = wmsParam.toStyleList();
16771682
}
16781683

16791684
QList<QgsWmsParametersLayer> lParams;

src/server/services/wms/qgswmsparameters.h

+9
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ namespace QgsWms
201201
*/
202202
bool isValid() const override;
203203

204+
/**
205+
* Converts the parameter into a list of strings and keeps empty parts
206+
* Default style value is an empty string
207+
* \param delimiter The character used for delimiting
208+
* \returns A list of strings
209+
* \since QGIS 3.8
210+
*/
211+
QStringList toStyleList( const char delimiter = ',' ) const;
212+
204213
/**
205214
* Converts the parameter into a list of geometries.
206215
* \param delimiter The character delimiting string geometries

tests/src/python/test_qgsserver_wms_getmap.py

+52
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,58 @@ def test_wms_getmap_style(self):
742742
r, h = self._result(self._execute_request(qs))
743743
self._img_diff_error(r, h, "WMS_GetMap_StyleCustom")
744744

745+
# mixed custom and default style with STYLES parameter
746+
qs = "?" + "&".join(["%s=%s" % i for i in list({
747+
"MAP": urllib.parse.quote(self.projectPath),
748+
"SERVICE": "WMS",
749+
"VERSION": "1.1.1",
750+
"REQUEST": "GetMap",
751+
"LAYERS": "Country_Labels,Hello",
752+
"STYLES": "custom,",
753+
"FORMAT": "image/png",
754+
"BBOX": "-16817707,-4710778,5696513,14587125",
755+
"HEIGHT": "500",
756+
"WIDTH": "500",
757+
"CRS": "EPSG:3857"
758+
}.items())])
759+
760+
r, h = self._result(self._execute_request(qs))
761+
self._img_diff_error(r, h, "WMS_GetMap_StyleMixed")
762+
763+
qs = "?" + "&".join(["%s=%s" % i for i in list({
764+
"MAP": urllib.parse.quote(self.projectPath),
765+
"SERVICE": "WMS",
766+
"VERSION": "1.1.1",
767+
"REQUEST": "GetMap",
768+
"LAYERS": "Hello,Country_Labels",
769+
"STYLES": "default,custom",
770+
"FORMAT": "image/png",
771+
"BBOX": "-16817707,-4710778,5696513,14587125",
772+
"HEIGHT": "500",
773+
"WIDTH": "500",
774+
"CRS": "EPSG:3857"
775+
}.items())])
776+
777+
r, h = self._result(self._execute_request(qs))
778+
self._img_diff_error(r, h, "WMS_GetMap_StyleMixed_LayerOrder")
779+
780+
qs = "?" + "&".join(["%s=%s" % i for i in list({
781+
"MAP": urllib.parse.quote(self.projectPath),
782+
"SERVICE": "WMS",
783+
"VERSION": "1.1.1",
784+
"REQUEST": "GetMap",
785+
"LAYERS": "Hello,Country_Labels",
786+
"STYLES": ",custom",
787+
"FORMAT": "image/png",
788+
"BBOX": "-16817707,-4710778,5696513,14587125",
789+
"HEIGHT": "500",
790+
"WIDTH": "500",
791+
"CRS": "EPSG:3857"
792+
}.items())])
793+
794+
r, h = self._result(self._execute_request(qs))
795+
self._img_diff_error(r, h, "WMS_GetMap_StyleMixed_LayerOrder")
796+
745797
def test_wms_getmap_filter(self):
746798
qs = "?" + "&".join(["%s=%s" % i for i in list({
747799
"MAP": urllib.parse.quote(self.projectPath),
Loading

0 commit comments

Comments
 (0)