Skip to content

Commit 466dc35

Browse files
committed
QgsGmlStreamingParser: fix parsing of GML geometries with srsDimension='3' set on posList element (fixes #21335)
1 parent 377040a commit 466dc35

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
@@ -815,11 +815,14 @@ void QgsGmlStreamingParser::startElement( const XML_Char *el, const XML_Char **a
815815
}
816816
}
817817

818-
if ( elDimension != 0 )
818+
if ( elDimension != 0 || mDimensionStack.isEmpty() )
819819
{
820-
mDimension = elDimension;
820+
mDimensionStack.push( elDimension );
821+
}
822+
else
823+
{
824+
mDimensionStack.push( mDimensionStack.back() );
821825
}
822-
mDimensionStack.push( mDimension );
823826

824827
if ( mEpsg == 0 && isGeom )
825828
{
@@ -847,7 +850,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
847850
const int localNameLen = ( pszSep ) ? ( int )( elLen - nsLen ) - 1 : elLen;
848851
ParseMode parseMode( mParseModeStack.isEmpty() ? None : mParseModeStack.top() );
849852

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

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

@@ -858,6 +861,7 @@ void QgsGmlStreamingParser::endElement( const XML_Char *el )
858861
else if ( parseMode == PosList && isGMLNS &&
859862
( LOCALNAME_EQUALS( "pos" ) || LOCALNAME_EQUALS( "posList" ) ) )
860863
{
864+
mDimension = lastDimension;
861865
mParseModeStack.pop();
862866
}
863867
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)