Skip to content

Commit

Permalink
OGRSpatialReference: workaround bug of PROJ < 9.5 regarding wrong con…
Browse files Browse the repository at this point in the history
…version id for UTM south

Complement fix of OSGeo/PROJ#4166 for PROJ < 9.5
Fixes https://gis.stackexchange.com/questions/482037/what-is-epsg17056
  • Loading branch information
rouault authored and github-actions[bot] committed Jun 10, 2024
1 parent c7f44e8 commit 5208523
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
16 changes: 16 additions & 0 deletions autotest/osr/osr_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
# DEALINGS IN THE SOFTWARE.
###############################################################################

import json
import os
import subprocess
import sys
Expand Down Expand Up @@ -2478,3 +2479,18 @@ def test_osr_basic_has_point_motion_operation():
srs = osr.SpatialReference()
srs.ImportFromEPSG(8255) # NAD83(CSRS)v7
assert srs.HasPointMotionOperation()


###############################################################################


# Test workaround for /~https://github.com/OSGeo/PROJ/pull/4166
def test_osr_basic_export_wkt_utm_south():

srs = osr.SpatialReference()
srs.SetFromUserInput("+proj=utm +zone=1 +south +datum=WGS84")

assert 'ID["EPSG",16101]' in srs.ExportToWkt(["FORMAT=WKT2_2019"])

j = json.loads(srs.ExportToPROJJSON())
assert j["conversion"]["id"]["code"] == 16101
134 changes: 134 additions & 0 deletions ogr/ogrspatialreference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1751,6 +1751,71 @@ OGRErr OGRSpatialReference::exportToWkt(char **ppszResult,
}

*ppszResult = CPLStrdup(pszWKT);

#if !(PROJ_AT_LEAST_VERSION(9, 5, 0))
if (wktFormat == PJ_WKT2_2018)
{
// Works around bug fixed per /~https://github.com/OSGeo/PROJ/pull/4166
// related to a wrong EPSG code assigned to UTM South conversions
char *pszPtr = strstr(*ppszResult, "CONVERSION[\"UTM zone ");
if (pszPtr)
{
pszPtr += strlen("CONVERSION[\"UTM zone ");
const int nZone = atoi(pszPtr);
while (*pszPtr >= '0' && *pszPtr <= '9')
++pszPtr;
if (nZone >= 1 && nZone <= 60 && *pszPtr == 'S' &&
pszPtr[1] == '"' && pszPtr[2] == ',')
{
pszPtr += 3;
int nLevel = 0;
bool bInString = false;
// Find the ID node corresponding to this CONVERSION node
while (*pszPtr)
{
if (bInString)
{
if (*pszPtr == '"' && pszPtr[1] == '"')
{
++pszPtr;
}
else if (*pszPtr == '"')
{
bInString = false;
}
}
else if (nLevel == 0 && STARTS_WITH_CI(pszPtr, "ID["))
{
if (STARTS_WITH_CI(pszPtr, CPLSPrintf("ID[\"EPSG\",%d]",
17000 + nZone)))
{
CPLAssert(pszPtr[11] == '7');
CPLAssert(pszPtr[12] == '0');
pszPtr[11] = '6';
pszPtr[12] = '1';
}
break;
}
else if (*pszPtr == '"')
{
bInString = true;
}
else if (*pszPtr == '[')
{
++nLevel;
}
else if (*pszPtr == ']')
{
--nLevel;
}

++pszPtr;
}
}
}
}
#endif

proj_destroy(boundCRS);
return OGRERR_NONE;
}
Expand Down Expand Up @@ -1901,6 +1966,75 @@ OGRErr OGRSpatialReference::exportToPROJJSON(
}

*ppszResult = CPLStrdup(pszPROJJSON);

#if !(PROJ_AT_LEAST_VERSION(9, 5, 0))
{
// Works around bug fixed per /~https://github.com/OSGeo/PROJ/pull/4166
// related to a wrong EPSG code assigned to UTM South conversions
char *pszPtr = strstr(*ppszResult, "\"name\": \"UTM zone ");
if (pszPtr)
{
pszPtr += strlen("\"name\": \"UTM zone ");
const int nZone = atoi(pszPtr);
while (*pszPtr >= '0' && *pszPtr <= '9')
++pszPtr;
if (nZone >= 1 && nZone <= 60 && *pszPtr == 'S' && pszPtr[1] == '"')
{
pszPtr += 2;
int nLevel = 0;
bool bInString = false;
// Find the id node corresponding to this conversion node
while (*pszPtr)
{
if (bInString)
{
if (*pszPtr == '\\')
{
++pszPtr;
}
else if (*pszPtr == '"')
{
bInString = false;
}
}
else if (nLevel == 0 && STARTS_WITH(pszPtr, "\"id\": {"))
{
const char *pszNextEndCurl = strchr(pszPtr, '}');
const char *pszAuthEPSG =
strstr(pszPtr, "\"authority\": \"EPSG\"");
char *pszCode = strstr(
pszPtr, CPLSPrintf("\"code\": %d", 17000 + nZone));
if (pszAuthEPSG && pszCode && pszNextEndCurl &&
pszNextEndCurl - pszAuthEPSG > 0 &&
pszNextEndCurl - pszCode > 0)
{
CPLAssert(pszCode[9] == '7');
CPLAssert(pszCode[10] == '0');
pszCode[9] = '6';
pszCode[10] = '1';
}
break;
}
else if (*pszPtr == '"')
{
bInString = true;
}
else if (*pszPtr == '{' || *pszPtr == '[')
{
++nLevel;
}
else if (*pszPtr == '}' || *pszPtr == ']')
{
--nLevel;
}

++pszPtr;
}
}
}
}
#endif

return OGRERR_NONE;
}

Expand Down

0 comments on commit 5208523

Please sign in to comment.