Skip to content

Commit

Permalink
QgsCurvePolygon::asGml3(): make output compliant when ring is not a L…
Browse files Browse the repository at this point in the history
…inearRing

that is when it is a ring made of a CircularString or a ring made of a CompoundCurve

Fixes #57355
  • Loading branch information
rouault authored and nyalldawson committed May 19, 2024
1 parent 134e990 commit 2f2ceed
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
36 changes: 24 additions & 12 deletions src/core/geometry/qgscurvepolygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,24 +356,36 @@ QDomElement QgsCurvePolygon::asGml3( QDomDocument &doc, int precision, const QSt
if ( isEmpty() )
return elemCurvePolygon;

QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
QDomElement curveElem = exteriorRing()->asGml3( doc, precision, ns, axisOrder );
if ( curveElem.tagName() == QLatin1String( "LineString" ) )
const auto exportRing = [&doc, precision, &ns, axisOrder]( const QgsCurve * ring )
{
curveElem.setTagName( QStringLiteral( "LinearRing" ) );
}
elemExterior.appendChild( curveElem );
QDomElement ringElem = ring->asGml3( doc, precision, ns, axisOrder );
if ( ringElem.tagName() == QLatin1String( "LineString" ) )
{
ringElem.setTagName( QStringLiteral( "LinearRing" ) );
}
else if ( ringElem.tagName() == QLatin1String( "CompositeCurve" ) )
{
ringElem.setTagName( QStringLiteral( "Ring" ) );
}
else if ( ringElem.tagName() == QLatin1String( "Curve" ) )
{
QDomElement ringElemNew = doc.createElementNS( ns, QStringLiteral( "Ring" ) );
QDomElement curveMemberElem = doc.createElementNS( ns, QStringLiteral( "curveMember" ) );
ringElemNew.appendChild( curveMemberElem );
curveMemberElem.appendChild( ringElem );
ringElem = std::move( ringElemNew );
}
return ringElem;
};

QDomElement elemExterior = doc.createElementNS( ns, QStringLiteral( "exterior" ) );
elemExterior.appendChild( exportRing( exteriorRing() ) );
elemCurvePolygon.appendChild( elemExterior );

for ( int i = 0, n = numInteriorRings(); i < n; ++i )
{
QDomElement elemInterior = doc.createElementNS( ns, QStringLiteral( "interior" ) );
QDomElement innerRing = interiorRing( i )->asGml3( doc, precision, ns, axisOrder );
if ( innerRing.tagName() == QLatin1String( "LineString" ) )
{
innerRing.setTagName( QStringLiteral( "LinearRing" ) );
}
elemInterior.appendChild( innerRing );
elemInterior.appendChild( exportRing( interiorRing( i ) ) );
elemCurvePolygon.appendChild( elemInterior );
}
return elemCurvePolygon;
Expand Down
19 changes: 16 additions & 3 deletions tests/src/core/geometry/testqgscurvepolygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class TestQgsCurvePolygon: public QObject
void testWKB();
void testWKT();
void testExport();
void testExportOfCompoundCurveRing();
void testCast();
void removeInteriorRings_github_issue_49578();
};
Expand Down Expand Up @@ -1738,7 +1739,7 @@ void TestQgsCurvePolygon::testExport()
QGSCOMPAREGML( elemToString( QgsCurvePolygon().asGml2( doc ) ), expectedGML2empty );

// as GML3
QString expectedSimpleGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior></Polygon>" ) );
QString expectedSimpleGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></curveMember></Ring></exterior></Polygon>" ) );
res = elemToString( exportPolygon.asGml3( doc, 2 ) );
QCOMPARE( elemToString( exportPolygon.asGml3( doc ) ), expectedSimpleGML3 );

Expand Down Expand Up @@ -1793,15 +1794,27 @@ void TestQgsCurvePolygon::testExport()
QGSCOMPAREGML( res, expectedGML2prec2 );

// as GML3
QString expectedGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior><interior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.10000000000000001 0 11 0.20000000000000001 0 12 0.10000000000000001 0.05 13 0 0 10</posList></ArcString></segments></Curve></interior></Polygon>" ) );
QString expectedGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></curveMember></Ring></exterior><interior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.10000000000000001 0 11 0.20000000000000001 0 12 0.10000000000000001 0.05 13 0 0 10</posList></ArcString></segments></Curve></curveMember></Ring></interior></Polygon>" ) );
res = elemToString( exportPolygon.asGml3( doc ) );
QCOMPARE( res, expectedGML3 );

QString expectedGML3prec3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></exterior><interior xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.1 0 11 0.2 0 12 0.1 0.05 13 0 0 10</posList></ArcString></segments></Curve></interior></Polygon>" ) );
QString expectedGML3prec3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 1 0 11 2 0 12 1 0.5 13 0 0 10</posList></ArcString></segments></Curve></curveMember></Ring></exterior><interior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"3\">0 0 10 0.1 0 11 0.2 0 12 0.1 0.05 13 0 0 10</posList></ArcString></segments></Curve></curveMember></Ring></interior></Polygon>" ) );
res = elemToString( exportPolygon.asGml3( doc, 3 ) );
QCOMPARE( res, expectedGML3prec3 );
}

void TestQgsCurvePolygon::testExportOfCompoundCurveRing()
{
QgsCurvePolygon curvePoly;
curvePoly.fromWkt( QStringLiteral( "CURVEPOLYGON (COMPOUNDCURVE ((0 -1,0 1),CIRCULARSTRING (0 1,1 0,0 -1)))" ) );

// as GML3
QString expectedGML3( QStringLiteral( "<Polygon xmlns=\"gml\"><exterior xmlns=\"gml\"><Ring xmlns=\"gml\"><curveMember xmlns=\"gml\"><LineString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 -1 0 1</posList></LineString></curveMember><curveMember xmlns=\"gml\"><Curve xmlns=\"gml\"><segments xmlns=\"gml\"><ArcString xmlns=\"gml\"><posList xmlns=\"gml\" srsDimension=\"2\">0 1 1 0 0 -1</posList></ArcString></segments></Curve></curveMember></Ring></exterior></Polygon>" ) );
QDomDocument doc( QStringLiteral( "gml" ) );
QString res = elemToString( curvePoly.asGml3( doc ) );
QCOMPARE( res, expectedGML3 );
}

void TestQgsCurvePolygon::testCast()
{
QVERIFY( !QgsCurvePolygon().cast( nullptr ) );
Expand Down

0 comments on commit 2f2ceed

Please sign in to comment.