diff --git a/autotest/ogr/ogr_gml_geom.py b/autotest/ogr/ogr_gml_geom.py
index 9d7d52145a80..41d0380aa552 100755
--- a/autotest/ogr/ogr_gml_geom.py
+++ b/autotest/ogr/ogr_gml_geom.py
@@ -1740,16 +1740,16 @@ def test_gml_CircleByCenterPoint():
assert ogrtest.check_feature_geometry(geom, ogr.CreateGeometryFromWkt('CIRCULARSTRING (-1 2,3 2,-1 2)')) == 0
###############################################################################
-# Test GML CircleByCenterPoint with uom="m"
+# Test GML CircleByCenterPoint with uom="m" and uom="km"
-def test_gml_CircleByCenterPoint_srs_geog_uom_m():
+def test_gml_CircleByCenterPoint_srs_geog_uom_m_km():
gml = '49 22000'
geom1 = ogr.CreateGeometryFromGML(gml)
geom1.SwapXY()
- gml = '2 492000'
+ gml = '2 492'
geom2 = ogr.CreateGeometryFromGML(gml)
assert ogrtest.check_feature_geometry(geom1, geom2) == 0
diff --git a/gdal/ogr/gml2ogrgeometry.cpp b/gdal/ogr/gml2ogrgeometry.cpp
index 7e67a37d7333..2e63319bc1db 100644
--- a/gdal/ogr/gml2ogrgeometry.cpp
+++ b/gdal/ogr/gml2ogrgeometry.cpp
@@ -850,6 +850,31 @@ bool GML2OGRGeometry_AddToMultiSurface( OGRMultiSurface* poMS,
return true;
}
+/************************************************************************/
+/* GetDistanceInMetre() */
+/************************************************************************/
+
+static double GetDistanceInMetre(double dfDistance, const char* pszUnits)
+{
+ if( EQUAL(pszUnits, "m") )
+ return dfDistance;
+
+ if( EQUAL(pszUnits, "km") )
+ return dfDistance * 1000;
+
+ if( EQUAL(pszUnits, "nm") || EQUAL(pszUnits, "[nmi_i]") )
+ return dfDistance * CPLAtof(SRS_UL_INTL_NAUT_MILE_CONV);
+
+ if( EQUAL(pszUnits, "mi") )
+ return dfDistance * CPLAtof(SRS_UL_INTL_STAT_MILE_CONV);
+
+ if( EQUAL(pszUnits, "ft") )
+ return dfDistance * CPLAtof(SRS_UL_INTL_FOOT_CONV);
+
+ CPLDebug("GML2OGRGeometry", "Unhandled unit: %s", pszUnits);
+ return -1;
+}
+
/************************************************************************/
/* GML2OGRGeometry_XMLNode() */
/* */
@@ -1211,19 +1236,9 @@ OGRGeometry *GML2OGRGeometry_XMLNode_Internal(
}
}
if( bSRSUnitIsDegree && pszUnits != nullptr &&
- (EQUAL(pszUnits, "m") ||
- EQUAL(pszUnits, "nm") ||
- EQUAL(pszUnits, "[nmi_i]") ||
- EQUAL(pszUnits, "mi") ||
- EQUAL(pszUnits, "ft")) )
+ (dfRadius = GetDistanceInMetre(dfRadius, pszUnits)) > 0 )
{
bIsApproximateArc = true;
- if( EQUAL(pszUnits, "nm") || EQUAL(pszUnits, "[nmi_i]"))
- dfRadius *= CPLAtof(SRS_UL_INTL_NAUT_MILE_CONV);
- else if( EQUAL(pszUnits, "mi") )
- dfRadius *= CPLAtof(SRS_UL_INTL_STAT_MILE_CONV);
- else if( EQUAL(pszUnits, "ft") )
- dfRadius *= CPLAtof(SRS_UL_INTL_FOOT_CONV);
dfLastCurveApproximateArcRadius = dfRadius;
bLastCurveWasApproximateArcInvertedAxisOrder =
bInvertedAxisOrder;
@@ -1806,24 +1821,14 @@ OGRGeometry *GML2OGRGeometry_XMLNode_Internal(
const double dfCenterX = p.getX();
const double dfCenterY = p.getY();
+ double dfDistance;
if( bSRSUnitIsDegree && pszUnits != nullptr &&
- (EQUAL(pszUnits, "m") ||
- EQUAL(pszUnits, "nm") ||
- EQUAL(pszUnits, "[nmi_i]") ||
- EQUAL(pszUnits, "mi") ||
- EQUAL(pszUnits, "ft")) )
+ (dfDistance = GetDistanceInMetre(dfRadius, pszUnits)) > 0 )
{
OGRLineString* poLS = new OGRLineString();
// coverity[tainted_data]
const double dfStep =
CPLAtof(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
- double dfDistance = dfRadius;
- if( EQUAL(pszUnits, "nm") || EQUAL(pszUnits, "[nmi_i]") )
- dfDistance *= CPLAtof(SRS_UL_INTL_NAUT_MILE_CONV);
- else if( EQUAL(pszUnits, "mi") )
- dfDistance *= CPLAtof(SRS_UL_INTL_STAT_MILE_CONV);
- else if( EQUAL(pszUnits, "ft") )
- dfDistance *= CPLAtof(SRS_UL_INTL_FOOT_CONV);
const double dfSign = dfStartAngle < dfEndAngle ? 1 : -1;
for( double dfAngle = dfStartAngle;
(dfAngle - dfEndAngle) * dfSign < 0;
@@ -1935,23 +1940,13 @@ OGRGeometry *GML2OGRGeometry_XMLNode_Internal(
const double dfCenterX = p.getX();
const double dfCenterY = p.getY();
+ double dfDistance;
if( bSRSUnitIsDegree && pszUnits != nullptr &&
- (EQUAL(pszUnits, "m") ||
- EQUAL(pszUnits, "nm") ||
- EQUAL(pszUnits, "[nmi_i]") ||
- EQUAL(pszUnits, "mi") ||
- EQUAL(pszUnits, "ft")) )
+ (dfDistance = GetDistanceInMetre(dfRadius, pszUnits)) > 0 )
{
OGRLineString* poLS = new OGRLineString();
const double dfStep =
CPLAtof(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
- double dfDistance = dfRadius;
- if( EQUAL(pszUnits, "nm") || EQUAL(pszUnits, "[nmi_i]") )
- dfDistance *= CPLAtof(SRS_UL_INTL_NAUT_MILE_CONV);
- else if( EQUAL(pszUnits, "mi") )
- dfDistance *= CPLAtof(SRS_UL_INTL_STAT_MILE_CONV);
- else if( EQUAL(pszUnits, "ft") )
- dfDistance *= CPLAtof(SRS_UL_INTL_FOOT_CONV);
for( double dfAngle = 0; dfAngle < 360; dfAngle += dfStep )
{
double dfLong = 0.0;