mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-08 00:05:09 -04:00
[sld] Don't try to write rules/categorizes without symbolizers
Only create rules/categorized categories/graduated ranges if the associated symbol could be converted to SLD, and is not an "empty" symbol. Otherwise we do not generate a rule, as SLD spec requires a Symbolizer element to be present.
This commit is contained in:
parent
52dd3047ac
commit
2abc9d92ca
@ -22,6 +22,7 @@ try:
|
||||
QgsSymbolLayerUtils.decodeBrushStyle = staticmethod(QgsSymbolLayerUtils.decodeBrushStyle)
|
||||
QgsSymbolLayerUtils.encodeSldBrushStyle = staticmethod(QgsSymbolLayerUtils.encodeSldBrushStyle)
|
||||
QgsSymbolLayerUtils.decodeSldBrushStyle = staticmethod(QgsSymbolLayerUtils.decodeSldBrushStyle)
|
||||
QgsSymbolLayerUtils.hasSldSymbolizer = staticmethod(QgsSymbolLayerUtils.hasSldSymbolizer)
|
||||
QgsSymbolLayerUtils.decodeCoordinateReference = staticmethod(QgsSymbolLayerUtils.decodeCoordinateReference)
|
||||
QgsSymbolLayerUtils.encodeCoordinateReference = staticmethod(QgsSymbolLayerUtils.encodeCoordinateReference)
|
||||
QgsSymbolLayerUtils.decodeArrowHeadType = staticmethod(QgsSymbolLayerUtils.decodeArrowHeadType)
|
||||
|
@ -60,6 +60,13 @@ Contains utility functions for working with symbols and symbol layers.
|
||||
static QString encodeSldBrushStyle( Qt::BrushStyle style );
|
||||
static Qt::BrushStyle decodeSldBrushStyle( const QString &str );
|
||||
|
||||
static bool hasSldSymbolizer( const QDomElement &element );
|
||||
%Docstring
|
||||
Returns ``True`` if a DOM ``element`` contains an SLD Symbolizer element.
|
||||
|
||||
.. versionadded:: 3.42
|
||||
%End
|
||||
|
||||
static Qgis::SymbolCoordinateReference decodeCoordinateReference( const QString &string, bool *ok /Out/ = 0 );
|
||||
%Docstring
|
||||
Decodes a ``string`` representing a symbol coordinate reference mode.
|
||||
|
@ -22,6 +22,7 @@ try:
|
||||
QgsSymbolLayerUtils.decodeBrushStyle = staticmethod(QgsSymbolLayerUtils.decodeBrushStyle)
|
||||
QgsSymbolLayerUtils.encodeSldBrushStyle = staticmethod(QgsSymbolLayerUtils.encodeSldBrushStyle)
|
||||
QgsSymbolLayerUtils.decodeSldBrushStyle = staticmethod(QgsSymbolLayerUtils.decodeSldBrushStyle)
|
||||
QgsSymbolLayerUtils.hasSldSymbolizer = staticmethod(QgsSymbolLayerUtils.hasSldSymbolizer)
|
||||
QgsSymbolLayerUtils.decodeCoordinateReference = staticmethod(QgsSymbolLayerUtils.decodeCoordinateReference)
|
||||
QgsSymbolLayerUtils.encodeCoordinateReference = staticmethod(QgsSymbolLayerUtils.encodeCoordinateReference)
|
||||
QgsSymbolLayerUtils.decodeArrowHeadType = staticmethod(QgsSymbolLayerUtils.decodeArrowHeadType)
|
||||
|
@ -60,6 +60,13 @@ Contains utility functions for working with symbols and symbol layers.
|
||||
static QString encodeSldBrushStyle( Qt::BrushStyle style );
|
||||
static Qt::BrushStyle decodeSldBrushStyle( const QString &str );
|
||||
|
||||
static bool hasSldSymbolizer( const QDomElement &element );
|
||||
%Docstring
|
||||
Returns ``True`` if a DOM ``element`` contains an SLD Symbolizer element.
|
||||
|
||||
.. versionadded:: 3.42
|
||||
%End
|
||||
|
||||
static Qgis::SymbolCoordinateReference decodeCoordinateReference( const QString &string, bool *ok /Out/ = 0 );
|
||||
%Docstring
|
||||
Decodes a ``string`` representing a symbol coordinate reference mode.
|
||||
|
@ -150,7 +150,6 @@ void QgsRendererCategory::toSld( QDomDocument &doc, QDomElement &element, QVaria
|
||||
}
|
||||
|
||||
QDomElement ruleElem = doc.createElement( QStringLiteral( "se:Rule" ) );
|
||||
element.appendChild( ruleElem );
|
||||
|
||||
QDomElement nameElem = doc.createElement( QStringLiteral( "se:Name" ) );
|
||||
nameElem.appendChild( doc.createTextNode( mLabel ) );
|
||||
@ -199,6 +198,14 @@ void QgsRendererCategory::toSld( QDomDocument &doc, QDomElement &element, QVaria
|
||||
QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElem, props );
|
||||
|
||||
mSymbol->toSld( doc, ruleElem, props );
|
||||
if ( !QgsSymbolLayerUtils::hasSldSymbolizer( ruleElem ) )
|
||||
{
|
||||
// symbol could not be converted to SLD, or is an "empty" symbol. In this case we do not generate a rule, as
|
||||
// SLD spec requires a Symbolizer element to be present
|
||||
return;
|
||||
}
|
||||
|
||||
element.appendChild( ruleElem );
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
@ -138,7 +138,6 @@ void QgsRendererRange::toSld( QDomDocument &doc, QDomElement &element, QVariantM
|
||||
QString attrName = props[ QStringLiteral( "attribute" )].toString();
|
||||
|
||||
QDomElement ruleElem = doc.createElement( QStringLiteral( "se:Rule" ) );
|
||||
element.appendChild( ruleElem );
|
||||
|
||||
QDomElement nameElem = doc.createElement( QStringLiteral( "se:Name" ) );
|
||||
nameElem.appendChild( doc.createTextNode( mLabel ) );
|
||||
@ -160,6 +159,14 @@ void QgsRendererRange::toSld( QDomDocument &doc, QDomElement &element, QVariantM
|
||||
QgsSymbolLayerUtils::createFunctionElement( doc, ruleElem, filterFunc );
|
||||
|
||||
mSymbol->toSld( doc, ruleElem, props );
|
||||
if ( !QgsSymbolLayerUtils::hasSldSymbolizer( ruleElem ) )
|
||||
{
|
||||
// symbol could not be converted to SLD, or is an "empty" symbol. In this case we do not generate a rule, as
|
||||
// SLD spec requires a Symbolizer element to be present
|
||||
return;
|
||||
}
|
||||
|
||||
element.appendChild( ruleElem );
|
||||
}
|
||||
|
||||
//////////
|
||||
|
@ -375,7 +375,6 @@ void QgsRuleBasedRenderer::Rule::toSld( QDomDocument &doc, QDomElement &element,
|
||||
if ( mSymbol )
|
||||
{
|
||||
QDomElement ruleElem = doc.createElement( QStringLiteral( "se:Rule" ) );
|
||||
element.appendChild( ruleElem );
|
||||
|
||||
//XXX: <se:Name> is the rule identifier, but our the Rule objects
|
||||
// have no properties could be used as identifier. Use the label.
|
||||
@ -409,6 +408,13 @@ void QgsRuleBasedRenderer::Rule::toSld( QDomDocument &doc, QDomElement &element,
|
||||
QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElem, props );
|
||||
|
||||
mSymbol->toSld( doc, ruleElem, props );
|
||||
|
||||
// Only create rules if symbol could be converted to SLD, and is not an "empty" symbol. Otherwise we do not generate a rule, as
|
||||
// SLD spec requires a Symbolizer element to be present
|
||||
if ( QgsSymbolLayerUtils::hasSldSymbolizer( ruleElem ) )
|
||||
{
|
||||
element.appendChild( ruleElem );
|
||||
}
|
||||
}
|
||||
|
||||
// loop into children rule list
|
||||
|
@ -391,6 +391,20 @@ Qt::BrushStyle QgsSymbolLayerUtils::decodeSldBrushStyle( const QString &str )
|
||||
return Qt::NoBrush;
|
||||
}
|
||||
|
||||
bool QgsSymbolLayerUtils::hasSldSymbolizer( const QDomElement &element )
|
||||
{
|
||||
const QDomNodeList children = element.childNodes();
|
||||
for ( int i = 0; i < children.size(); ++i )
|
||||
{
|
||||
const QDomElement childElement = children.at( i ).toElement();
|
||||
if ( childElement.tagName() == QLatin1String( "se:LineSymbolizer" )
|
||||
|| childElement.tagName() == QLatin1String( "se:PointSymbolizer" )
|
||||
|| childElement.tagName() == QLatin1String( "se:PolygonSymbolizer" ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qgis::SymbolCoordinateReference QgsSymbolLayerUtils::decodeCoordinateReference( const QString &string, bool *ok )
|
||||
{
|
||||
const QString compareString = string.trimmed();
|
||||
|
@ -94,6 +94,13 @@ class CORE_EXPORT QgsSymbolLayerUtils
|
||||
static QString encodeSldBrushStyle( Qt::BrushStyle style );
|
||||
static Qt::BrushStyle decodeSldBrushStyle( const QString &str );
|
||||
|
||||
/**
|
||||
* Returns TRUE if a DOM \a element contains an SLD Symbolizer element.
|
||||
*
|
||||
* \since QGIS 3.42
|
||||
*/
|
||||
static bool hasSldSymbolizer( const QDomElement &element );
|
||||
|
||||
/**
|
||||
* Decodes a \a string representing a symbol coordinate reference mode.
|
||||
*
|
||||
|
@ -301,6 +301,7 @@ ADD_PYTHON_TEST(PyQgsRenderContext test_qgsrendercontext.py)
|
||||
ADD_PYTHON_TEST(PyQgsRenderedItemResults test_qgsrendereditemresults.py)
|
||||
ADD_PYTHON_TEST(PyQgsRenderer test_qgsrenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsReport test_qgsreport.py)
|
||||
ADD_PYTHON_TEST(PyQgsRuleBasedRenderer test_qgsrulebasedrenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsScaleBarRendererRegistry test_qgsscalebarrendererregistry.py)
|
||||
ADD_PYTHON_TEST(PyQgsScaleBarRenderers test_qgsscalebarrenderers.py)
|
||||
ADD_PYTHON_TEST(PyQgsScaleCalculator test_qgsscalecalculator.py)
|
||||
|
@ -935,6 +935,13 @@ class TestQgsCategorizedSymbolRenderer(QgisTestCase):
|
||||
symbol_f = createMarkerSymbol()
|
||||
renderer.addCategory(QgsRendererCategory(None, symbol_f, 'f', True, '4'))
|
||||
|
||||
# this category should NOT be included in the SLD, as it would otherwise result
|
||||
# in an invalid se:rule with no symbolizer element
|
||||
symbol_which_is_empty_in_sld = createFillSymbol()
|
||||
symbol_which_is_empty_in_sld[0].setBrushStyle(Qt.NoBrush)
|
||||
symbol_which_is_empty_in_sld[0].setStrokeStyle(Qt.NoPen)
|
||||
renderer.addCategory(QgsRendererCategory(None, symbol_which_is_empty_in_sld, 'empty', True, '4'))
|
||||
|
||||
dom = QDomDocument()
|
||||
root = dom.createElement("FakeRoot")
|
||||
dom.appendChild(root)
|
||||
|
@ -24,6 +24,7 @@ from qgis.core import (
|
||||
QgsRendererRange,
|
||||
QgsRendererRangeLabelFormat,
|
||||
QgsVectorLayer,
|
||||
QgsFillSymbol,
|
||||
)
|
||||
import unittest
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
@ -44,6 +45,13 @@ def createMarkerSymbol():
|
||||
return symbol
|
||||
|
||||
|
||||
def createFillSymbol():
|
||||
symbol = QgsFillSymbol.createSimple({
|
||||
"color": "100,150,50"
|
||||
})
|
||||
return symbol
|
||||
|
||||
|
||||
def createMemoryLayer(values):
|
||||
ml = QgsVectorLayer("Point?crs=epsg:4236&field=id:integer&field=value:double",
|
||||
"test_data", "memory")
|
||||
@ -563,6 +571,135 @@ class TestQgsGraduatedSymbolRenderer(QgisTestCase):
|
||||
self.assertTrue(ok)
|
||||
self.assertEqual(exp, """(log("field_name") >= 15.5) AND (log("field_name") <= 16.5)""")
|
||||
|
||||
def test_to_sld(self):
|
||||
renderer = QgsGraduatedSymbolRenderer()
|
||||
renderer.setClassAttribute('field_name')
|
||||
|
||||
symbol_a = createMarkerSymbol()
|
||||
renderer.addClassRange(QgsRendererRange(1, 2, symbol_a, 'a', True, '0'))
|
||||
symbol_b = createMarkerSymbol()
|
||||
renderer.addClassRange(QgsRendererRange(5, 6, symbol_b, 'b', True, '1'))
|
||||
symbol_c = createMarkerSymbol()
|
||||
renderer.addClassRange(QgsRendererRange(15.5, 16.5, symbol_c, 'c', False, '2'))
|
||||
|
||||
# this category should NOT be included in the SLD, as it would otherwise result
|
||||
# in an invalid se:rule with no symbolizer element
|
||||
symbol_which_is_empty_in_sld = createFillSymbol()
|
||||
symbol_which_is_empty_in_sld[0].setBrushStyle(Qt.NoBrush)
|
||||
symbol_which_is_empty_in_sld[0].setStrokeStyle(Qt.NoPen)
|
||||
renderer.addClassRange(
|
||||
QgsRendererRange(25.5, 26.5, symbol_which_is_empty_in_sld, 'd', False, '2'))
|
||||
|
||||
dom = QDomDocument()
|
||||
root = dom.createElement("FakeRoot")
|
||||
dom.appendChild(root)
|
||||
renderer.toSld(dom, root, {})
|
||||
|
||||
expected = """<FakeRoot>
|
||||
<se:Rule>
|
||||
<se:Name>a</se:Name>
|
||||
<se:Description>
|
||||
<se:Title>a</se:Title>
|
||||
</se:Description>
|
||||
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
|
||||
<ogc:And>
|
||||
<ogc:PropertyIsGreaterThanOrEqualTo>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>1</ogc:Literal>
|
||||
</ogc:PropertyIsGreaterThanOrEqualTo>
|
||||
<ogc:PropertyIsLessThanOrEqualTo>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>2</ogc:Literal>
|
||||
</ogc:PropertyIsLessThanOrEqualTo>
|
||||
</ogc:And>
|
||||
</ogc:Filter>
|
||||
<se:PointSymbolizer>
|
||||
<se:Graphic>
|
||||
<se:Mark>
|
||||
<se:WellKnownName>square</se:WellKnownName>
|
||||
<se:Fill>
|
||||
<se:SvgParameter name="fill">#649632</se:SvgParameter>
|
||||
</se:Fill>
|
||||
<se:Stroke>
|
||||
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
|
||||
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
|
||||
</se:Stroke>
|
||||
</se:Mark>
|
||||
<se:Size>11</se:Size>
|
||||
</se:Graphic>
|
||||
</se:PointSymbolizer>
|
||||
</se:Rule>
|
||||
<se:Rule>
|
||||
<se:Name>b</se:Name>
|
||||
<se:Description>
|
||||
<se:Title>b</se:Title>
|
||||
</se:Description>
|
||||
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
|
||||
<ogc:And>
|
||||
<ogc:PropertyIsGreaterThan>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>5</ogc:Literal>
|
||||
</ogc:PropertyIsGreaterThan>
|
||||
<ogc:PropertyIsLessThanOrEqualTo>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>6</ogc:Literal>
|
||||
</ogc:PropertyIsLessThanOrEqualTo>
|
||||
</ogc:And>
|
||||
</ogc:Filter>
|
||||
<se:PointSymbolizer>
|
||||
<se:Graphic>
|
||||
<se:Mark>
|
||||
<se:WellKnownName>square</se:WellKnownName>
|
||||
<se:Fill>
|
||||
<se:SvgParameter name="fill">#649632</se:SvgParameter>
|
||||
</se:Fill>
|
||||
<se:Stroke>
|
||||
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
|
||||
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
|
||||
</se:Stroke>
|
||||
</se:Mark>
|
||||
<se:Size>11</se:Size>
|
||||
</se:Graphic>
|
||||
</se:PointSymbolizer>
|
||||
</se:Rule>
|
||||
<se:Rule>
|
||||
<se:Name>c</se:Name>
|
||||
<se:Description>
|
||||
<se:Title>c</se:Title>
|
||||
</se:Description>
|
||||
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
|
||||
<ogc:And>
|
||||
<ogc:PropertyIsGreaterThan>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>15.5</ogc:Literal>
|
||||
</ogc:PropertyIsGreaterThan>
|
||||
<ogc:PropertyIsLessThanOrEqualTo>
|
||||
<ogc:PropertyName>field_name</ogc:PropertyName>
|
||||
<ogc:Literal>16.5</ogc:Literal>
|
||||
</ogc:PropertyIsLessThanOrEqualTo>
|
||||
</ogc:And>
|
||||
</ogc:Filter>
|
||||
<se:PointSymbolizer>
|
||||
<se:Graphic>
|
||||
<se:Mark>
|
||||
<se:WellKnownName>square</se:WellKnownName>
|
||||
<se:Fill>
|
||||
<se:SvgParameter name="fill">#649632</se:SvgParameter>
|
||||
</se:Fill>
|
||||
<se:Stroke>
|
||||
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
|
||||
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
|
||||
</se:Stroke>
|
||||
</se:Mark>
|
||||
<se:Size>11</se:Size>
|
||||
</se:Graphic>
|
||||
</se:PointSymbolizer>
|
||||
</se:Rule>
|
||||
</FakeRoot>
|
||||
"""
|
||||
|
||||
self.assertEqual(dom.toString(), expected)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
133
tests/src/python/test_qgsrulebasedrenderer.py
Normal file
133
tests/src/python/test_qgsrulebasedrenderer.py
Normal file
@ -0,0 +1,133 @@
|
||||
"""QGIS Unit tests for QgsRuleBasedRenderer
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
|
||||
from qgis.PyQt.QtCore import Qt
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
from qgis.core import (
|
||||
QgsMarkerSymbol,
|
||||
QgsFillSymbol,
|
||||
QgsRuleBasedRenderer
|
||||
)
|
||||
import unittest
|
||||
from qgis.testing import start_app, QgisTestCase
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
# ===========================================================
|
||||
# Utility functions
|
||||
|
||||
|
||||
def createMarkerSymbol():
|
||||
symbol = QgsMarkerSymbol.createSimple({
|
||||
"color": "100,150,50",
|
||||
"name": "square",
|
||||
"size": "3.0"
|
||||
})
|
||||
return symbol
|
||||
|
||||
|
||||
def createFillSymbol():
|
||||
symbol = QgsFillSymbol.createSimple({
|
||||
"color": "100,150,50"
|
||||
})
|
||||
return symbol
|
||||
|
||||
|
||||
class TestQgsRuleBasedSymbolRenderer(QgisTestCase):
|
||||
|
||||
def test_to_sld(self):
|
||||
root_rule = QgsRuleBasedRenderer.Rule(None)
|
||||
symbol_a = createMarkerSymbol()
|
||||
root_rule.appendChild(
|
||||
QgsRuleBasedRenderer.Rule(symbol_a, filterExp='"something"=1', label="label a", description="rule a")
|
||||
)
|
||||
symbol_b = createMarkerSymbol()
|
||||
root_rule.appendChild(
|
||||
QgsRuleBasedRenderer.Rule(symbol_b, filterExp='"something"=2', label="label b", description="rule b")
|
||||
)
|
||||
|
||||
# this rule should NOT be included in the SLD, as it would otherwise result
|
||||
# in an invalid se:rule with no symbolizer element
|
||||
symbol_which_is_empty_in_sld = createFillSymbol()
|
||||
symbol_which_is_empty_in_sld[0].setBrushStyle(Qt.NoBrush)
|
||||
symbol_which_is_empty_in_sld[0].setStrokeStyle(Qt.NoPen)
|
||||
root_rule.appendChild(
|
||||
QgsRuleBasedRenderer.Rule(symbol_which_is_empty_in_sld, filterExp='"something"=3', label="label c", description="rule c"))
|
||||
|
||||
renderer = QgsRuleBasedRenderer(root_rule)
|
||||
|
||||
dom = QDomDocument()
|
||||
root = dom.createElement("FakeRoot")
|
||||
dom.appendChild(root)
|
||||
renderer.toSld(dom, root, {})
|
||||
|
||||
expected = """<FakeRoot>
|
||||
<se:Rule>
|
||||
<se:Name>label a</se:Name>
|
||||
<se:Description>
|
||||
<se:Title>label a</se:Title>
|
||||
<se:Abstract>rule a</se:Abstract>
|
||||
</se:Description>
|
||||
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
|
||||
<ogc:PropertyIsEqualTo>
|
||||
<ogc:PropertyName>something</ogc:PropertyName>
|
||||
<ogc:Literal>1</ogc:Literal>
|
||||
</ogc:PropertyIsEqualTo>
|
||||
</ogc:Filter>
|
||||
<se:PointSymbolizer>
|
||||
<se:Graphic>
|
||||
<se:Mark>
|
||||
<se:WellKnownName>square</se:WellKnownName>
|
||||
<se:Fill>
|
||||
<se:SvgParameter name="fill">#649632</se:SvgParameter>
|
||||
</se:Fill>
|
||||
<se:Stroke>
|
||||
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
|
||||
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
|
||||
</se:Stroke>
|
||||
</se:Mark>
|
||||
<se:Size>11</se:Size>
|
||||
</se:Graphic>
|
||||
</se:PointSymbolizer>
|
||||
</se:Rule>
|
||||
<se:Rule>
|
||||
<se:Name>label b</se:Name>
|
||||
<se:Description>
|
||||
<se:Title>label b</se:Title>
|
||||
<se:Abstract>rule b</se:Abstract>
|
||||
</se:Description>
|
||||
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
|
||||
<ogc:PropertyIsEqualTo>
|
||||
<ogc:PropertyName>something</ogc:PropertyName>
|
||||
<ogc:Literal>2</ogc:Literal>
|
||||
</ogc:PropertyIsEqualTo>
|
||||
</ogc:Filter>
|
||||
<se:PointSymbolizer>
|
||||
<se:Graphic>
|
||||
<se:Mark>
|
||||
<se:WellKnownName>square</se:WellKnownName>
|
||||
<se:Fill>
|
||||
<se:SvgParameter name="fill">#649632</se:SvgParameter>
|
||||
</se:Fill>
|
||||
<se:Stroke>
|
||||
<se:SvgParameter name="stroke">#232323</se:SvgParameter>
|
||||
<se:SvgParameter name="stroke-width">0.5</se:SvgParameter>
|
||||
</se:Stroke>
|
||||
</se:Mark>
|
||||
<se:Size>11</se:Size>
|
||||
</se:Graphic>
|
||||
</se:PointSymbolizer>
|
||||
</se:Rule>
|
||||
</FakeRoot>
|
||||
"""
|
||||
self.assertEqual(dom.toString(), expected)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user