Skip to content

Commit c923d5b

Browse files
aaimenyalldawson
authored andcommitted
Fixes #16706, categorized symbology matching lack of value is not properly encoded in SLD
1 parent b56f113 commit c923d5b

File tree

3 files changed

+482
-3
lines changed

3 files changed

+482
-3
lines changed

src/core/symbology/qgscategorizedsymbolrenderer.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,20 @@ void QgsRendererCategory::toSld( QDomDocument &doc, QDomElement &element, QgsStr
131131
ruleElem.appendChild( descrElem );
132132

133133
// create the ogc:Filter for the range
134-
QString filterFunc = QStringLiteral( "%1 = '%2'" )
135-
.arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ),
136-
mValue.toString().replace( '\'', QLatin1String( "''" ) ) );
134+
QString filterFunc;
135+
if ( mValue.isNull() || mValue.toString().isEmpty() )
136+
{
137+
filterFunc = QStringLiteral( "%1 = '%2' or %1 is null" )
138+
.arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ),
139+
mValue.toString().replace( '\'', QLatin1String( "''" ) ) );
140+
}
141+
else
142+
{
143+
filterFunc = QStringLiteral( "%1 = '%2'" )
144+
.arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ),
145+
mValue.toString().replace( '\'', QLatin1String( "''" ) ) );
146+
}
147+
137148
QgsSymbolLayerUtils::createFunctionElement( doc, ruleElem, filterFunc );
138149

139150
// add the mix/max scale denoms if we got any from the callers

tests/src/python/test_qgssymbollayer_createsld.py

+17
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,23 @@ def assertVendorOption(self, container, expectedName, allowMissing=False):
11951195
else:
11961196
self.fail('Could not find a se:VendorOption named ' + expectedName + ' in ' + container.nodeName())
11971197

1198+
def testRuleBaseEmptyFilter(self):
1199+
layer = QgsVectorLayer("Point", "addfeat", "memory")
1200+
1201+
mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "categorizedEmptyValue"))
1202+
status = layer.loadNamedStyle(mFilePath) # NOQA
1203+
1204+
dom, root = self.layerToSld(layer)
1205+
# print("Rule based, with last rule checking against empty value:" + dom.toString())
1206+
1207+
# get the third rule
1208+
rule = root.elementsByTagName('se:Rule').item(2).toElement()
1209+
filter = rule.elementsByTagName('Filter').item(0).toElement()
1210+
filter = filter.firstChild().toElement()
1211+
self.assertEqual("ogc:Or", filter.nodeName())
1212+
self.assertEqual(1, filter.elementsByTagName('ogc:PropertyIsEqualTo').size())
1213+
self.assertEqual(1, filter.elementsByTagName('ogc:PropertyIsNull').size())
1214+
11981215
def assertScaleDenominator(self, root, expectedMinScale, expectedMaxScale, index=0):
11991216
rule = root.elementsByTagName('se:Rule').item(index).toElement()
12001217

0 commit comments

Comments
 (0)