Skip to content

Commit 2ed6c67

Browse files
committed
QgsGmlStreamingParser: fix parsing of GML geometries with srsDimension='3' set on posList element (fixes #21335)
1 parent 1991ce6 commit 2ed6c67

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/core/qgsgml.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -812,11 +812,14 @@ void QgsGmlStreamingParser::startElement( const XML_Char *el, const XML_Char **a
812812
}
813813
}
814814

815-
if ( elDimension != 0 )
815+
if ( elDimension != 0 || mDimensionStack.isEmpty() )
816816
{
817-
mDimension = elDimension;
817+
mDimensionStack.push( elDimension );
818+
}
819+
else
820+
{
821+
mDimensionStack.push( mDimensionStack.back() );
818822
}
819-
mDimensionStack.push( mDimension );
820823

821824
if ( mEpsg == 0 && isGeom )
822825
{
@@ -844,7 +847,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
844847
const int localNameLen = ( pszSep ) ? ( int )( elLen - nsLen ) - 1 : elLen;
845848
ParseMode parseMode( mParseModeStack.isEmpty() ? None : mParseModeStack.top() );
846849

847-
mDimension = mDimensionStack.isEmpty() ? 0 : mDimensionStack.pop();
850+
int lastDimension = mDimensionStack.isEmpty() ? 0 : mDimensionStack.pop();
848851

849852
const bool isGMLNS = ( nsLen == mGMLNameSpaceURI.size() && mGMLNameSpaceURIPtr && memcmp( el, mGMLNameSpaceURIPtr, nsLen ) == 0 );
850853

@@ -855,6 +858,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
855858
else if ( parseMode == PosList && isGMLNS &&
856859
( LOCALNAME_EQUALS( "pos" ) || LOCALNAME_EQUALS( "posList" ) ) )
857860
{
861+
mDimension = lastDimension;
858862
mParseModeStack.pop();
859863
}
860864
else if ( parseMode == AttributeTuple &&

tests/src/core/testqgsgml.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class TestQgsGML : public QObject
6464
void testLineStringGML3_LineStringSegment();
6565
void testPolygonGML3();
6666
void testPolygonGML3_srsDimension_on_Polygon();
67+
void testPolygonGML3_srsDimension_on_posList();
6768
void testMultiLineStringGML3();
6869
void testMultiPolygonGML3();
6970
void testPointGML3_2();
@@ -660,6 +661,38 @@ void TestQgsGML::testPolygonGML3_srsDimension_on_Polygon()
660661
delete features[0].first;
661662
}
662663

664+
void TestQgsGML::testPolygonGML3_srsDimension_on_posList()
665+
{
666+
QgsFields fields;
667+
QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields );
668+
QCOMPARE( gmlParser.processData( QByteArray( "<myns:FeatureCollection "
669+
"xmlns:myns='http://myns' "
670+
"xmlns:gml='http://www.opengis.net/gml'>"
671+
"<gml:featureMember>"
672+
"<myns:mytypename fid='mytypename.1'>"
673+
"<myns:mygeom>"
674+
"<gml:Polygon srsName='EPSG:27700'>"
675+
"<gml:exterior>"
676+
"<gml:LinearRing>"
677+
"<gml:posList srsDimension='3'>0 0 -100 0 10 -100 10 10 -100 10 0 -100 0 0 -100</gml:posList>"
678+
"</gml:LinearRing>"
679+
"</gml:exterior>"
680+
"</gml:Polygon>"
681+
"</myns:mygeom>"
682+
"</myns:mytypename>"
683+
"</gml:featureMember>"
684+
"</myns:FeatureCollection>" ), true ), true );
685+
QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon );
686+
QVector<QgsGmlStreamingParser::QgsGmlFeaturePtrGmlIdPair> features = gmlParser.getAndStealReadyFeatures();
687+
QCOMPARE( features.size(), 1 );
688+
QVERIFY( features[0].first->hasGeometry() );
689+
QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon );
690+
QgsPolygonXY poly = features[0].first->geometry().asPolygon();
691+
QCOMPARE( poly.size(), 1 );
692+
QCOMPARE( poly[0].size(), 5 );
693+
delete features[0].first;
694+
}
695+
663696
void TestQgsGML::testMultiLineStringGML3()
664697
{
665698
QgsFields fields;

0 commit comments

Comments
 (0)