qgsogcutils: Fix axis inversion in geometryFromGML

`QgsOgcUtils::geometryFromGML` converts a GML to a QgsGeometry. in the
GML3 case, this checks if the X/Y coordinates need to be inverted only
if a context is provided and the destination crs is different from the
source crs.

However, the check for axis inversion should be done whether a context
is provided or not. This issue is fixed by the moving the `srsName`
and `swapXy` logic before the context check.
This commit is contained in:
Jean Felder 2025-09-03 17:50:05 +02:00
parent 41ad493cbd
commit 9f64afe421
No known key found for this signature in database
GPG Key ID: 12722DC64D3F429E
2 changed files with 57 additions and 36 deletions

View File

@ -156,11 +156,9 @@ QgsGeometry QgsOgcUtils::geometryFromGML( const QDomNode &geometryNode, const Co
return geometry;
}
// Handle srsName if context has information about the layer and the transformation context
if ( context.layer )
{
// Handle srsName
// Check if the XY coordinates of geometry need to be swapped by checking the srs from the GML
QgsCoordinateReferenceSystem geomSrs;
if ( geometryTypeElement.hasAttribute( QStringLiteral( "srsName" ) ) )
{
QString srsName { geometryTypeElement.attribute( QStringLiteral( "srsName" ) ) };
@ -179,12 +177,15 @@ QgsGeometry QgsOgcUtils::geometryFromGML( const QDomNode &geometryNode, const Co
}
}
geomSrs.createFromUserInput( srsName );
if ( geomSrs.isValid() && geomSrs != context.layer->crs() )
{
if ( geomSrs.hasAxisInverted() && ! ignoreAxisOrientation )
if ( geomSrs.isValid() && geomSrs.hasAxisInverted() && !ignoreAxisOrientation )
{
geometry.get()->swapXy();
}
}
// Apply a coordinate transformation if context has information about the layer and the transformation context
if ( geomSrs.isValid() && context.layer && geomSrs != context.layer->crs() )
{
const QgsCoordinateTransform transformer { geomSrs, context.layer->crs(), context.transformContext };
try
{
@ -199,8 +200,6 @@ QgsGeometry QgsOgcUtils::geometryFromGML( const QDomNode &geometryNode, const Co
QgsDebugMsgLevel( QStringLiteral( "CS error transforming geometry" ), 2 );
}
}
}
}
return geometry;
}

View File

@ -105,6 +105,13 @@ void TestQgsOgcUtils::testGeometryFromGML()
QVERIFY( !geomBox.isNull() );
QVERIFY( geomBox.wkbType() == Qgis::WkbType::Polygon );
// Test point GML2 with EPSG:4326
// X/Y coordinates are not inverted
geom = QgsOgcUtils::geometryFromGML( QStringLiteral( "<gml:Point srsName=\"EPSG:4326\"><gml:coordinates>4,45</gml:coordinates></gml:Point>" ) );
QVERIFY( !geom.isNull() );
QVERIFY( geom.wkbType() == Qgis::WkbType::Point );
QVERIFY( geom.equals( QgsGeometry::fromWkt( QStringLiteral( "POINT (4 45)" ) ) ) );
// Test GML3
geom = QgsOgcUtils::geometryFromGML( QStringLiteral( "<Point><pos>123 456</pos></Point>" ) );
@ -133,6 +140,21 @@ void TestQgsOgcUtils::testGeometryFromGML()
QVERIFY( !geom.isNull() );
QVERIFY( geom.wkbType() == Qgis::WkbType::LineStringZ );
QVERIFY( geom.equals( QgsGeometry::fromWkt( QStringLiteral( "LINESTRINGZ(0 0 1200, 0 1 1250, 1 1 1230, 1 0 1210)" ) ) ) );
// Test point GML3 with urn:ogc:def:crs:EPSG::4326
// X/Y coordinates are inverted
geom = QgsOgcUtils::geometryFromGML( QStringLiteral( "<gml:Point srsName=\"urn:ogc:def:crs:EPSG::4326\"><gml:pos>45 4</gml:pos></gml:Point>" ) );
QVERIFY( !geom.isNull() );
QVERIFY( geom.wkbType() == Qgis::WkbType::Point );
QVERIFY( geom.equals( QgsGeometry::fromWkt( QStringLiteral( "POINT (4 45)" ) ) ) );
// Test point GML3 with urn:ogc:def:crs:EPSG::3857
// X/Y coordinates are not inverted
geom = QgsOgcUtils::geometryFromGML( QStringLiteral( "<gml:Point srsName=\"urn:ogc:def:crs:EPSG::3857\"><gml:pos>32 2</gml:pos></gml:Point>" ) );
QVERIFY( !geom.isNull() );
QVERIFY( geom.wkbType() == Qgis::WkbType::Point );
QVERIFY( geom.equals( QgsGeometry::fromWkt( QStringLiteral( "POINT (32 2)" ) ) ) );
}
void TestQgsOgcUtils::testGeometryFromGMLWithZ_data()