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;