Skip to content

Commit f22ee6b

Browse files
committedJun 15, 2017
Fixes 16712, SLD export of categorized style fails if attribute name conflicts with a built-in function name
1 parent 7aec4d1 commit f22ee6b

File tree

3 files changed

+591
-1
lines changed

3 files changed

+591
-1
lines changed
 

‎src/core/symbology-ng/qgsgraduatedsymbolrenderer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void QgsRendererRange::toSld( QDomDocument &doc, QDomElement &element, QgsString
166166
ruleElem.appendChild( descrElem );
167167

168168
// create the ogc:Filter for the range
169-
QString filterFunc = QStringLiteral( "%1 %2 %3 AND %1 <= %4" )
169+
QString filterFunc = QStringLiteral( "\"%1\" %2 %3 AND \"%1\" <= %4" )
170170
.arg( attrName.replace( '\"', QLatin1String( "\"\"" ) ),
171171
firstRange ? ">=" : ">",
172172
qgsDoubleToString( mLowerValue ),

‎tests/src/python/test_qgssymbollayer_createsld.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,48 @@ def testRuleBasedNoRootScaleDependencies(self):
495495
self.assertScaleDenominator(root, '5000', '40000000', 0)
496496
self.assertScaleDenominator(root, '5000', '50000000', 1)
497497

498+
def testCategorizedFunctionConflict(self):
499+
layer = QgsVectorLayer("Point", "addfeat", "memory")
500+
501+
mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.qml' % (unitTestDataPath(), "categorizedFunctionConflict"))
502+
status = layer.loadNamedStyle(mFilePath) # NOQA
503+
504+
dom, root = self.layerToSld(layer)
505+
# print("Rule based, with root scale deps:" + dom.toString())
506+
507+
ruleCount = root.elementsByTagName('se:Rule').size() # NOQA
508+
self.assertEqual(7, ruleCount)
509+
self.assertRuleRangeFilter(root, 0, 'Area', '0', True, '500', True)
510+
self.assertRuleRangeFilter(root, 1, 'Area', '500', False, '1000', True)
511+
self.assertRuleRangeFilter(root, 2, 'Area', '1000', False, '5000', True)
512+
self.assertRuleRangeFilter(root, 3, 'Area', '5000', False, '10000', True)
513+
self.assertRuleRangeFilter(root, 4, 'Area', '10000', False, '50000', True)
514+
self.assertRuleRangeFilter(root, 5, 'Area', '50000', False, '100000', True)
515+
self.assertRuleRangeFilter(root, 6, 'Area', '100000', False, '200000', True)
516+
517+
def assertRuleRangeFilter(self, root, index, attributeName, min, includeMin, max, includeMax):
518+
rule = root.elementsByTagName('se:Rule').item(index).toElement()
519+
filter = rule.elementsByTagName("Filter").item(0).firstChild()
520+
self.assertEqual("ogc:And", filter.nodeName())
521+
522+
gt = filter.firstChild()
523+
expectedGtName = "ogc:PropertyIsGreaterThanOrEqualTo" if includeMin else "ogc:PropertyIsGreaterThan"
524+
self.assertEquals(expectedGtName, gt.nodeName())
525+
gtProperty = gt.firstChild()
526+
self.assertEquals("ogc:PropertyName", gtProperty.nodeName())
527+
self.assertEquals(attributeName, gtProperty.toElement().text())
528+
gtValue = gt.childNodes().item(1)
529+
self.assertEquals(min, gtValue.toElement().text())
530+
531+
lt = filter.childNodes().item(1)
532+
expectedLtName = "ogc:PropertyIsLessThanOrEqualTo" if includeMax else "ogc:PropertyIsLessThan"
533+
self.assertEquals(expectedLtName, lt.nodeName())
534+
ltProperty = lt.firstChild()
535+
self.assertEquals("ogc:PropertyName", ltProperty.nodeName())
536+
self.assertEquals(attributeName, ltProperty.toElement().text())
537+
ltValue = lt.childNodes().item(1)
538+
self.assertEquals(max, ltValue.toElement().text())
539+
498540
def assertScaleDenominator(self, root, expectedMinScale, expectedMaxScale, index=0):
499541
rule = root.elementsByTagName('se:Rule').item(index).toElement()
500542

0 commit comments

Comments
 (0)
Please sign in to comment.