1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Improve WKT parsing compatability

This commit is contained in:
Martin Tůma 2021-06-21 23:35:31 +02:00
parent 47d9eea1af
commit 057c625283
2 changed files with 125 additions and 5 deletions

View File

@ -78,6 +78,7 @@ PRJFile::Token PRJFile::keyword(CTX &ctx)
Token token; Token token;
QString name; QString name;
} keywords[] = { } keywords[] = {
{COMPD_CS, "COMPD_CS"},
{PROJCS, "PROJCS"}, {PROJCS, "PROJCS"},
{PROJECTION, "PROJECTION"}, {PROJECTION, "PROJECTION"},
{PARAMETER, "PARAMETER"}, {PARAMETER, "PARAMETER"},
@ -95,7 +96,12 @@ PRJFile::Token PRJFile::keyword(CTX &ctx)
{WEST, "WEST"}, {WEST, "WEST"},
{UP, "UP"}, {UP, "UP"},
{DOWN, "DOWN"}, {DOWN, "DOWN"},
{OTHER, "OTHER"} {OTHER, "OTHER"},
{VERT_CS, "VERT_CS"},
{VERT_DATUM, "VERT_DATUM"},
{GEOCCS, "GEOCCS"},
{FITTED_CS, "FITTED_CS"},
{LOCAL_CS, "LOCAL_CS"}
}; };
for (size_t i = 0; i < ARRAY_SIZE(keywords); i++) for (size_t i = 0; i < ARRAY_SIZE(keywords); i++)
@ -188,7 +194,7 @@ void PRJFile::nextToken(CTX &ctx)
return; return;
case 2: case 2:
if (isalnum(c)) { if (isalnum(c) || c == '_') {
ctx.string += QChar(c); ctx.string += QChar(c);
break; break;
} }
@ -531,6 +537,7 @@ void PRJFile::projectedCS(CTX &ctx, PCS *pcs)
parameter(ctx, &setup); parameter(ctx, &setup);
linearUnit(ctx, &lu); linearUnit(ctx, &lu);
optProjectedCS(ctx, &epsg); optProjectedCS(ctx, &epsg);
compare(ctx, RBRK);
*pcs = (epsg > 0) ? PCS::pcs(epsg) : PCS(gcs, method, setup, lu, cs); *pcs = (epsg > 0) ? PCS::pcs(epsg) : PCS(gcs, method, setup, lu, cs);
} }
@ -648,6 +655,111 @@ void PRJFile::horizontalCS(CTX &ctx)
} }
} }
void PRJFile::verticalDatum(CTX &ctx)
{
int epsg;
compare(ctx, VERT_DATUM);
compare(ctx, LBRK);
compare(ctx, STRING);
compare(ctx, COMMA);
compare(ctx, NUMBER);
optAuthority(ctx, &epsg);
compare(ctx, RBRK);
}
void PRJFile::optVerticalCS2(CTX &ctx, int *epsg)
{
switch (ctx.token) {
case AXIS:
axis(ctx);
optAuthority(ctx, epsg);
break;
case AUTHORITY:
authority(ctx, epsg);
break;
default:
error(ctx);
}
}
void PRJFile::optVerticalCS(CTX &ctx, int *epsg)
{
if (ctx.token == COMMA) {
nextToken(ctx);
optVerticalCS2(ctx, epsg);
}
}
void PRJFile::verticalCS(CTX &ctx)
{
int luEpsg, vcsEpsg;
double lu;
compare(ctx, VERT_CS);
compare(ctx, LBRK);
compare(ctx, STRING);
compare(ctx, COMMA);
verticalDatum(ctx);
compare(ctx, COMMA);
unit(ctx, &lu, &luEpsg);
optVerticalCS(ctx, &vcsEpsg);
compare(ctx, RBRK);
}
void PRJFile::optCS(CTX &ctx, int *epsg)
{
if (ctx.token == COMMA) {
nextToken(ctx);
authority(ctx, epsg);
}
}
void PRJFile::compdCS(CTX &ctx)
{
int epsg = -1;
compare(ctx, COMPD_CS);
compare(ctx, LBRK);
compare(ctx, STRING);
compare(ctx, COMMA);
CS(ctx);
compare(ctx, COMMA);
CS(ctx);
optCS(ctx, &epsg);
compare(ctx, RBRK);
}
void PRJFile::CS(CTX &ctx)
{
switch (ctx.token) {
case COMPD_CS:
compdCS(ctx);
break;
case PROJCS:
case GEOGCS:
horizontalCS(ctx);
break;
case VERT_CS:
verticalCS(ctx);
break;
case GEOCCS:
_errorString = "geocentric coordinate systems not supported";
ctx.token = ERROR;
break;
case FITTED_CS:
_errorString = "fitted coordinate systems not supported";
ctx.token = ERROR;
break;
case LOCAL_CS:
_errorString = "local coordinate systems not supported";
ctx.token = ERROR;
break;
default:
error(ctx);
}
}
PRJFile::PRJFile(const QString &fileName) PRJFile::PRJFile(const QString &fileName)
{ {
CTX ctx(fileName); CTX ctx(fileName);
@ -658,7 +770,7 @@ PRJFile::PRJFile(const QString &fileName)
} }
nextToken(ctx); nextToken(ctx);
horizontalCS(ctx); CS(ctx);
if (ctx.token != ERROR && !_projection.isValid()) if (ctx.token != ERROR && !_projection.isValid())
_errorString = "invalid/incomplete projection"; _errorString = "invalid/incomplete projection";

View File

@ -30,8 +30,9 @@ private:
COMMA, /* ',' */ COMMA, /* ',' */
/* Keywords */ /* Keywords */
PROJCS, PROJECTION, GEOGCS, DATUM, SPHEROID, PRIMEM, UNIT, AUTHORITY, COMPD_CS, PROJCS, PROJECTION, GEOGCS, DATUM, SPHEROID, PRIMEM, UNIT,
AXIS, TOWGS84, PARAMETER, NORTH, SOUTH, EAST, WEST, UP, DOWN, OTHER AUTHORITY, AXIS, TOWGS84, PARAMETER, NORTH, SOUTH, EAST, WEST, UP, DOWN,
OTHER, VERT_CS, VERT_DATUM, GEOCCS, FITTED_CS, LOCAL_CS
}; };
struct CTX { struct CTX {
@ -49,12 +50,16 @@ private:
void nextToken(CTX &ctx); void nextToken(CTX &ctx);
void compare(CTX &ctx, Token token); void compare(CTX &ctx, Token token);
void CS(CTX &ctx);
void horizontalCS(CTX &ctx); void horizontalCS(CTX &ctx);
void verticalCS(CTX &ctx);
void geographicCS(CTX &ctx, GCS *gcs); void geographicCS(CTX &ctx, GCS *gcs);
void projectedCS(CTX &ctx, PCS *pcs); void projectedCS(CTX &ctx, PCS *pcs);
void compdCS(CTX &ctx);
void projection(CTX &ctx, Projection::Method *method); void projection(CTX &ctx, Projection::Method *method);
void parameter(CTX &ctx, Projection::Setup *setup); void parameter(CTX &ctx, Projection::Setup *setup);
void datum(CTX &ctx, Datum *dtm, int *epsg); void datum(CTX &ctx, Datum *dtm, int *epsg);
void verticalDatum(CTX &ctx);
void unit(CTX &ctx, double *val, int *epsg); void unit(CTX &ctx, double *val, int *epsg);
void angularUnit(CTX &ctx, AngularUnits *au, int *epsg); void angularUnit(CTX &ctx, AngularUnits *au, int *epsg);
void primeMeridian(CTX &ctx, PrimeMeridian *pm, int *epsg); void primeMeridian(CTX &ctx, PrimeMeridian *pm, int *epsg);
@ -75,6 +80,9 @@ private:
void optGeographicCS2(CTX &ctx, int *epsg); void optGeographicCS2(CTX &ctx, int *epsg);
void optProjectedCS(CTX &ctx, int *epsg); void optProjectedCS(CTX &ctx, int *epsg);
void optProjectedCS2(CTX &ctx, int *epsg); void optProjectedCS2(CTX &ctx, int *epsg);
void optCS(CTX &ctx, int *epsg);
void optVerticalCS(CTX &ctx, int *epsg);
void optVerticalCS2(CTX &ctx, int *epsg);
Projection _projection; Projection _projection;
QString _errorString; QString _errorString;