diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-03-06 14:11:31 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2020-03-06 14:11:31 +0100 |
| commit | 6512ef2427ed6b303ae1c03b91907020cb5366d8 (patch) | |
| tree | 2d6f318b8f1700ebcb35dbfd7791c038d7b2a212 | |
| parent | 2dbca196a0c73972a0cc70856a42f01765868145 (diff) | |
| download | PROJ-6512ef2427ed6b303ae1c03b91907020cb5366d8.tar.gz PROJ-6512ef2427ed6b303ae1c03b91907020cb5366d8.zip | |
WKT import/export: add support for WKT1_ESRI VERTCS syntax
| -rw-r--r-- | include/proj/internal/io_internal.hpp | 3 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 19 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 6 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 49 | ||||
| -rw-r--r-- | src/iso19111/static.cpp | 1 | ||||
| -rw-r--r-- | src/wkt1_generated_parser.c | 406 | ||||
| -rw-r--r-- | src/wkt1_generated_parser.h | 26 | ||||
| -rw-r--r-- | src/wkt1_grammar.y | 8 | ||||
| -rw-r--r-- | src/wkt1_parser.cpp | 7 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 30 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 39 |
11 files changed, 378 insertions, 216 deletions
diff --git a/include/proj/internal/io_internal.hpp b/include/proj/internal/io_internal.hpp index 1e2508cc..617dffab 100644 --- a/include/proj/internal/io_internal.hpp +++ b/include/proj/internal/io_internal.hpp @@ -62,6 +62,7 @@ class WKTConstants { static const std::string PROJECTION; static const std::string PARAMETER; // WKT2 too static const std::string VERT_CS; + static const std::string VERTCS; // WKT1 ESRI static const std::string VERT_DATUM; static const std::string COMPD_CS; static const std::string TOWGS84; // WKT1 only @@ -95,7 +96,7 @@ class WKTConstants { static const std::string CITATION; static const std::string URI; static const std::string VERTCRS; - static const std::string VDATUM; + static const std::string VDATUM; // WKT2 and WKT1 ESRI static const std::string COMPOUNDCRS; static const std::string PARAMETERFILE; static const std::string COORDINATEOPERATION; diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 45e2309c..e1181d43 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2548,12 +2548,29 @@ const cs::VerticalCSNNPtr VerticalCRS::coordinateSystem() const { void VerticalCRS::_exportToWKT(io::WKTFormatter *formatter) const { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; formatter->startNode(isWKT2 ? io::WKTConstants::VERTCRS - : io::WKTConstants::VERT_CS, + : formatter->useESRIDialect() + ? io::WKTConstants::VERTCS + : io::WKTConstants::VERT_CS, !identifiers().empty()); formatter->addQuotedString(nameStr()); exportDatumOrDatumEnsembleToWkt(formatter); const auto &cs = SingleCRS::getPrivate()->coordinateSystem; const auto &axisList = cs->axisList(); + + if (formatter->useESRIDialect()) { + // Seems to be a constant value... + formatter->startNode(io::WKTConstants::PARAMETER, false); + formatter->addQuotedString("Vertical_Shift"); + formatter->add(0.0); + formatter->endNode(); + + formatter->startNode(io::WKTConstants::PARAMETER, false); + formatter->addQuotedString("Direction"); + formatter->add( + axisList[0]->direction() == cs::AxisDirection::UP ? 1.0 : -1.0); + formatter->endNode(); + } + if (!isWKT2) { axisList[0]->unit()._exportToWKT(formatter); } diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index d9d9c261..ad287e73 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1846,7 +1846,9 @@ void VerticalReferenceFrame::_exportToWKT( { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; formatter->startNode(isWKT2 ? io::WKTConstants::VDATUM - : io::WKTConstants::VERT_DATUM, + : formatter->useESRIDialect() + ? io::WKTConstants::VDATUM + : io::WKTConstants::VERT_DATUM, !identifiers().empty()); const auto &l_name = nameStr(); if (!l_name.empty()) { @@ -1856,7 +1858,7 @@ void VerticalReferenceFrame::_exportToWKT( } if (isWKT2) { Datum::getPrivate()->exportAnchorDefinition(formatter); - } else { + } else if (!formatter->useESRIDialect()) { formatter->add(2005); // CS_VD_GeoidModelDerived from OGC 01-009 const auto &extension = formatter->getVDatumExtension(); if (!extension.empty()) { diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 861aadbf..c57014d9 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2463,18 +2463,57 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */ return CartesianCS::createEastingNorthing(unit); } } else if (ci_equal(parentNodeName, WKTConstants::VERT_CS) || + ci_equal(parentNodeName, WKTConstants::VERTCS) || ci_equal(parentNodeName, WKTConstants::BASEVERTCRS)) { csTypeCStr = "vertical"; + + bool downDirection = false; + if (ci_equal(parentNodeName, WKTConstants::VERTCS)) // ESRI + { + for (const auto &childNode : parentNode->GP()->children()) { + const auto &childNodeChildren = childNode->GP()->children(); + if (childNodeChildren.size() == 2 && + ci_equal(childNode->GP()->value(), + WKTConstants::PARAMETER) && + childNodeChildren[0]->GP()->value() == + "\"Direction\"") { + const auto ¶mValue = + childNodeChildren[1]->GP()->value(); + try { + double val = asDouble(childNodeChildren[1]); + if (val == 1.0) { + // ok + } else if (val == -1.0) { + downDirection = true; + } + } catch (const std::exception &) { + throw ParsingException( + concat("unhandled parameter value type : ", + paramValue)); + } + } + } + } + if (axisCount == 0) { auto unit = buildUnitInSubNode(parentNode, UnitOfMeasure::Type::LINEAR); if (unit == UnitOfMeasure::NONE) { - if (ci_equal(parentNodeName, WKTConstants::VERT_CS)) { + if (ci_equal(parentNodeName, WKTConstants::VERT_CS) || + ci_equal(parentNodeName, WKTConstants::VERTCS)) { ThrowParsingExceptionMissingUNIT(); } else { unit = UnitOfMeasure::METRE; } } + if (downDirection) { + return VerticalCS::create( + util::PropertyMap(), + CoordinateSystemAxis::create( + util::PropertyMap().set(IdentifiedObject::NAME_KEY, + "depth"), + "D", AxisDirection::DOWN, unit)); + } return VerticalCS::createGravityRelatedHeight(unit); } } else if (ci_equal(parentNodeName, WKTConstants::LOCAL_CS)) { @@ -3890,6 +3929,7 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { auto &csNode = nodeP->lookForChild(WKTConstants::CS_); const auto &nodeValue = nodeP->value(); if (isNull(csNode) && !ci_equal(nodeValue, WKTConstants::VERT_CS) && + !ci_equal(nodeValue, WKTConstants::VERTCS) && !ci_equal(nodeValue, WKTConstants::BASEVERTCRS)) { ThrowMissing(WKTConstants::CS_); } @@ -3905,7 +3945,8 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { // following conventions from // https://pubs.usgs.gov/tm/11b4/pdf/tm11-B4.pdf // page 9 - if (ci_equal(nodeValue, WKTConstants::VERT_CS)) { + if (ci_equal(nodeValue, WKTConstants::VERT_CS) || + ci_equal(nodeValue, WKTConstants::VERTCS)) { std::string name; if (props.getStringValue(IdentifiedObject::NAME_KEY, name)) { std::string geoidName; @@ -4404,6 +4445,7 @@ CRSPtr WKTParser::Private::buildCRS(const WKTNodeNNPtr &node) { } if (ci_equal(name, WKTConstants::VERT_CS) || + ci_equal(name, WKTConstants::VERTCS) || ci_equal(name, WKTConstants::VERTCRS) || ci_equal(name, WKTConstants::VERTICALCRS)) { if (!isNull(nodeP->lookForChild(WKTConstants::BASEVERTCRS))) { @@ -6165,6 +6207,9 @@ WKTParser::attachDatabaseContext(const DatabaseContextPtr &dbContext) { */ WKTParser::WKTGuessedDialect WKTParser::guessDialect(const std::string &wkt) noexcept { + if (ci_starts_with(wkt, WKTConstants::VERTCS)) { + return WKTGuessedDialect::WKT1_ESRI; + } const std::string *const wkt1_keywords[] = { &WKTConstants::GEOCCS, &WKTConstants::GEOGCS, &WKTConstants::COMPD_CS, &WKTConstants::PROJCS, &WKTConstants::VERT_CS, &WKTConstants::LOCAL_CS}; diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp index da399288..11306e35 100644 --- a/src/iso19111/static.cpp +++ b/src/iso19111/static.cpp @@ -204,6 +204,7 @@ DEFINE_WKT_CONSTANT(PROJCS); DEFINE_WKT_CONSTANT(PROJECTION); DEFINE_WKT_CONSTANT(PARAMETER); DEFINE_WKT_CONSTANT(VERT_CS); +DEFINE_WKT_CONSTANT(VERTCS); DEFINE_WKT_CONSTANT(VERT_DATUM); DEFINE_WKT_CONSTANT(COMPD_CS); DEFINE_WKT_CONSTANT(TOWGS84); diff --git a/src/wkt1_generated_parser.c b/src/wkt1_generated_parser.c index 7a590f80..2785ec9f 100644 --- a/src/wkt1_generated_parser.c +++ b/src/wkt1_generated_parser.c @@ -150,18 +150,20 @@ extern int pj_wkt1_debug; T_GEOCCS = 269, T_AUTHORITY = 270, T_VERT_CS = 271, - T_VERT_DATUM = 272, - T_COMPD_CS = 273, - T_AXIS = 274, - T_TOWGS84 = 275, - T_FITTED_CS = 276, - T_LOCAL_CS = 277, - T_LOCAL_DATUM = 278, - T_PARAMETER = 279, - T_EXTENSION = 280, - T_STRING = 281, - T_NUMBER = 282, - T_IDENTIFIER = 283 + T_VERTCS = 272, + T_VERT_DATUM = 273, + T_VDATUM = 274, + T_COMPD_CS = 275, + T_AXIS = 276, + T_TOWGS84 = 277, + T_FITTED_CS = 278, + T_LOCAL_CS = 279, + T_LOCAL_DATUM = 280, + T_PARAMETER = 281, + T_EXTENSION = 282, + T_STRING = 283, + T_NUMBER = 284, + T_IDENTIFIER = 285 }; #endif @@ -420,23 +422,23 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 28 +#define YYFINAL 30 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 215 +#define YYLAST 222 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 34 +#define YYNTOKENS 36 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 66 +#define YYNNTS 67 /* YYNRULES -- Number of rules. */ -#define YYNRULES 99 +#define YYNRULES 101 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 257 +#define YYNSTATES 267 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 283 +#define YYMAXUTOK 285 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -449,12 +451,12 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 30, 32, 2, 2, 33, 2, 2, 2, 2, 2, + 32, 34, 2, 2, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 29, 2, 31, 2, 2, 2, 2, 2, 2, + 2, 31, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -473,23 +475,24 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28 + 25, 26, 27, 28, 29, 30 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 76, 76, 88, 88, 91, 94, 94, 97, 97, - 97, 97, 100, 103, 105, 106, 109, 111, 112, 115, - 118, 122, 127, 127, 127, 127, 127, 127, 130, 130, - 134, 138, 139, 142, 143, 145, 146, 147, 148, 150, - 151, 154, 157, 160, 164, 166, 167, 168, 169, 172, - 176, 179, 182, 185, 188, 191, 194, 197, 200, 203, - 204, 205, 206, 209, 212, 215, 217, 218, 219, 222, - 224, 225, 226, 229, 232, 235, 238, 240, 243, 248, - 251, 253, 256, 259, 262, 265, 268, 271, 274, 277, - 280, 283, 286, 289, 292, 294, 296, 297, 298, 301 + 0, 80, 80, 92, 92, 95, 98, 98, 101, 101, + 101, 101, 104, 107, 109, 110, 113, 115, 116, 119, + 122, 126, 131, 131, 131, 131, 131, 131, 134, 134, + 138, 142, 143, 146, 147, 149, 150, 151, 152, 154, + 155, 158, 161, 164, 168, 170, 171, 172, 173, 176, + 180, 183, 186, 189, 192, 195, 198, 201, 204, 207, + 208, 209, 210, 213, 216, 219, 220, 222, 223, 224, + 227, 230, 232, 233, 234, 237, 240, 243, 246, 248, + 251, 256, 259, 261, 264, 267, 270, 273, 276, 279, + 282, 285, 288, 291, 294, 297, 300, 302, 304, 305, + 306, 309 }; #endif @@ -502,25 +505,27 @@ static const char *const yytname[] = "\"CONCAT_MT\"", "\"INVERSE_MT\"", "\"PASSTHROUGH_MT\"", "\"PROJCS\"", "\"PROJECTION\"", "\"GEOGCS\"", "\"DATUM\"", "\"SPHEROID\"", "\"PRIMEM\"", "\"UNIT\"", "\"GEOCCS\"", "\"AUTHORITY\"", "\"VERT_CS\"", - "\"VERT_DATUM\"", "\"COMPD_CS\"", "\"AXIS\"", "\"TOWGS84\"", - "\"FITTED_CS\"", "\"LOCAL_CS\"", "\"LOCAL_DATUM\"", "\"PARAMETER\"", - "\"EXTENSION\"", "\"string\"", "\"number\"", "\"identifier\"", "'['", - "'('", "']'", "')'", "','", "$accept", "input", "begin_node", - "begin_node_name", "end_node", "math_transform", "param_mt", "parameter", - "opt_parameter_list", "concat_mt", "opt_math_transform_list", "inv_mt", - "passthrough_mt", "integer", "coordinate_system", "horz_cs", - "projected_cs", "opt_parameter_list_linear_unit", - "parameter_list_linear_unit", "opt_twin_axis_extension_authority", - "opt_authority", "extension", "projection", "geographic_cs", "datum", + "\"VERTCS\"", "\"VERT_DATUM\"", "\"VDATUM\"", "\"COMPD_CS\"", "\"AXIS\"", + "\"TOWGS84\"", "\"FITTED_CS\"", "\"LOCAL_CS\"", "\"LOCAL_DATUM\"", + "\"PARAMETER\"", "\"EXTENSION\"", "\"string\"", "\"number\"", + "\"identifier\"", "'['", "'('", "']'", "')'", "','", "$accept", "input", + "begin_node", "begin_node_name", "end_node", "math_transform", + "param_mt", "parameter", "opt_parameter_list", "concat_mt", + "opt_math_transform_list", "inv_mt", "passthrough_mt", "integer", + "coordinate_system", "horz_cs", "projected_cs", + "opt_parameter_list_linear_unit", "parameter_list_linear_unit", + "opt_twin_axis_extension_authority", "opt_authority", "extension", + "projection", "geographic_cs", "datum", "opt_towgs84_authority_extension", "spheroid", "semi_major_axis", "inverse_flattening", "prime_meridian", "longitude", "angular_unit", "linear_unit", "unit", "conversion_factor", "geocentric_cs", "opt_three_axis_extension_authority", "three_axis", "authority", - "vert_cs", "opt_axis_authority", "vert_datum", "opt_extension_authority", - "datum_type", "compd_cs", "head_cs", "tail_cs", "twin_axis", "axis", - "towgs84", "towgs84_parameters", "three_parameters", "seven_parameters", - "dx", "dy", "dz", "ex", "ey", "ez", "ppm", "fitted_cs", "to_base", - "base_cs", "local_cs", "opt_axis_list_authority", "local_datum", YY_NULLPTR + "vert_cs", "opt_axis_authority", "vert_datum", "vdatum", + "opt_extension_authority", "datum_type", "compd_cs", "head_cs", + "tail_cs", "twin_axis", "axis", "towgs84", "towgs84_parameters", + "three_parameters", "seven_parameters", "dx", "dy", "dz", "ex", "ey", + "ez", "ppm", "fitted_cs", "to_base", "base_cs", "local_cs", + "opt_axis_list_authority", "local_datum", YY_NULLPTR }; #endif @@ -531,8 +536,8 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 91, - 40, 93, 41, 44 + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 91, 40, 93, 41, 44 }; # endif @@ -550,32 +555,33 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 136, 2, 2, 2, 2, 2, 2, 2, 26, -127, + 125, 1, 1, 1, 1, 1, 1, 1, 1, 25, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, - 11, 5, 18, 32, 36, 40, 42, 53, -127, -127, - 35, 66, 66, 61, 136, 85, -127, -127, 59, -127, - 67, 2, 68, 69, 2, 70, -127, 72, 2, 2, - 2, 2, -127, -127, -127, -127, -127, 76, 2, 77, - 84, 79, 87, 87, 82, 105, 136, 88, 85, 85, - 93, 136, 89, 105, 2, 90, 113, 2, 95, 96, - 103, 2, 98, -127, -127, 99, 109, 25, 101, 25, - -127, 107, -127, 25, 103, 111, 114, 1, 2, 115, - 120, 105, 105, -127, 99, 122, 14, 25, 34, 25, - 2, 88, -127, 85, 25, -127, 85, -127, 114, 119, - 141, 25, 126, 127, -127, -127, 128, 15, 25, 135, - 127, -127, 130, 25, 137, 2, 2, -127, 114, -127, - 2, 114, -127, -127, 132, -127, 101, -127, 25, 25, - 133, -127, -127, 1, 33, 25, 140, 2, 114, -127, - 99, -127, -127, 114, 25, 33, 25, -127, -127, 114, - 138, 139, -127, 142, -127, 143, -127, -127, -127, 14, - 25, -127, -127, 114, -127, 99, 144, -127, -127, 145, - 146, -127, -127, 25, -127, 114, 99, -127, 147, -127, - 25, 148, 151, 150, 25, -127, 133, -127, -127, -127, - 119, 154, -127, 25, -127, -127, 149, -127, -127, -127, - 119, -127, 25, 25, 25, -127, -127, -127, -127, 114, - -127, 156, 153, -127, -127, -127, 25, -127, 155, 119, - -127, 157, -127, -127, 158, 160, -127, 159, 162, -127, - 161, 163, -127, 164, 166, -127, -127 + -127, 8, 9, 18, 28, 37, 46, 50, 51, 43, + -127, -127, 61, 77, 77, 71, 74, 125, 132, -127, + -127, 65, -127, 60, 1, 64, 66, 1, 67, 1, + 69, -127, 70, 1, 1, 1, 1, -127, -127, -127, + -127, -127, 72, 1, 76, 88, 83, 97, 97, 85, + 99, 33, -7, 125, 86, 132, 132, 95, 125, 90, + 99, 1, 91, 118, 1, 96, 108, 101, 1, 109, + -127, -127, 1, 112, 33, -127, -127, -127, 115, 126, + 33, 116, 33, -127, 119, -127, 33, 101, 120, 121, + -7, 1, 122, 123, 99, 99, -127, 115, 124, -3, + 33, 130, -7, -127, 0, 33, 86, -127, 132, 33, + -127, 132, -127, 121, 139, 146, 33, 131, 133, -1, + 33, 138, 131, -127, 134, 33, 141, 1, 1, -127, + 121, -127, 142, -127, -127, 1, 121, -127, -127, -127, + 116, -127, 33, 33, 137, -127, -127, 7, 33, 144, + 1, 121, -127, 115, -127, -127, 121, 33, 7, 33, + -127, -127, 121, 143, 145, -127, 33, 149, -127, -127, + -127, -127, -3, 33, 121, -127, 115, 150, -127, -127, + 151, 147, -127, -127, 33, -127, 121, 115, -127, 152, + -127, 33, 153, 158, -127, 161, -127, 137, -127, -127, + -127, 139, 148, -127, 33, -127, -127, 156, -127, -127, + -127, 139, -127, 33, 33, 33, -127, -127, -127, 121, + -127, 163, 159, -127, -127, -127, 33, -127, 160, 139, + -127, 164, -127, -127, 162, 167, -127, 165, 169, -127, + 166, 170, -127, 168, 173, -127, -127 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -583,158 +589,163 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, - 22, 29, 28, 23, 24, 25, 26, 27, 3, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, - 0, 0, 0, 0, 0, 0, 6, 7, 0, 95, - 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, - 0, 0, 92, 8, 9, 10, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66, 55, 76, 70, 0, 0, 17, 0, - 21, 0, 93, 0, 0, 0, 39, 0, 0, 45, - 0, 0, 0, 73, 70, 0, 0, 0, 0, 0, - 0, 14, 12, 0, 0, 19, 0, 91, 39, 0, - 0, 0, 0, 35, 32, 31, 0, 0, 0, 0, - 35, 54, 59, 0, 0, 0, 0, 68, 39, 65, - 0, 39, 72, 74, 0, 15, 17, 16, 0, 0, - 96, 40, 42, 0, 0, 0, 0, 0, 39, 48, - 70, 44, 53, 39, 0, 0, 0, 69, 57, 39, - 0, 0, 67, 0, 71, 0, 18, 20, 99, 0, - 0, 33, 34, 39, 38, 70, 0, 30, 50, 0, - 0, 47, 46, 0, 43, 39, 70, 62, 0, 58, - 0, 0, 0, 0, 0, 97, 96, 94, 37, 36, - 0, 0, 84, 0, 81, 80, 0, 52, 61, 60, - 0, 56, 0, 0, 0, 13, 98, 77, 51, 39, - 79, 0, 0, 64, 78, 41, 0, 85, 0, 0, - 49, 0, 63, 86, 82, 0, 87, 0, 0, 88, - 0, 0, 89, 0, 0, 90, 83 + 2, 22, 29, 28, 23, 24, 25, 26, 27, 3, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 5, 0, 0, 0, 0, 0, 0, 0, 6, + 7, 0, 97, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 0, 0, 0, 0, 0, 94, 8, 9, + 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, + 55, 71, 0, 0, 0, 32, 31, 78, 72, 0, + 0, 17, 0, 21, 0, 95, 0, 0, 0, 39, + 0, 0, 45, 0, 0, 0, 75, 72, 0, 0, + 0, 0, 0, 66, 0, 0, 14, 12, 0, 0, + 19, 0, 93, 39, 0, 0, 0, 35, 0, 0, + 0, 0, 35, 54, 59, 0, 0, 0, 0, 69, + 39, 65, 0, 33, 34, 0, 39, 74, 76, 15, + 17, 16, 0, 0, 98, 40, 42, 0, 0, 0, + 0, 39, 48, 72, 44, 53, 39, 0, 0, 0, + 70, 57, 39, 0, 0, 68, 0, 0, 73, 18, + 20, 101, 0, 0, 39, 38, 72, 0, 30, 50, + 0, 0, 47, 46, 0, 43, 39, 72, 62, 0, + 58, 0, 0, 0, 13, 0, 99, 98, 96, 37, + 36, 0, 0, 86, 0, 83, 82, 0, 52, 61, + 60, 0, 56, 0, 0, 0, 100, 79, 51, 39, + 81, 0, 0, 64, 80, 41, 0, 87, 0, 0, + 49, 0, 63, 88, 84, 0, 89, 0, 0, 90, + 0, 0, 91, 0, 0, 92, 85 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -127, -127, -46, 6, -87, -50, -127, 83, 57, -127, - 49, -127, -127, -127, -11, -127, -127, -127, 43, 71, - -44, -126, -127, 168, 167, -127, -127, -127, -127, 152, - -127, -127, -81, -56, -127, -127, -127, -127, -84, -127, - -127, -127, -89, 106, -127, -127, -127, -127, -112, -127, + -127, -127, -53, 35, -71, -67, -127, 75, 53, -127, + 44, -127, -127, -127, -26, -127, -127, 98, 84, 63, + -126, -64, -127, 175, 176, -127, -127, -127, -127, 154, + -127, -127, -60, -63, -127, -127, -127, -127, -119, -127, + -127, -127, -127, -113, 102, -127, -127, -127, -127, -121, -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, - -127, -127, -127, -127, -4, -127 + -127, -127, -127, -127, -127, -6, -127 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 8, 20, 21, 39, 52, 53, 122, 87, 54, - 114, 55, 56, 91, 9, 10, 11, 123, 124, 155, - 121, 141, 75, 12, 42, 128, 99, 189, 229, 78, - 163, 130, 82, 83, 169, 13, 166, 196, 137, 14, - 107, 45, 109, 104, 15, 47, 85, 185, 138, 160, - 213, 214, 215, 216, 238, 244, 247, 250, 253, 256, - 16, 57, 93, 17, 180, 59 + -1, 9, 21, 22, 42, 57, 58, 93, 100, 59, + 129, 60, 61, 104, 10, 11, 12, 94, 95, 168, + 136, 156, 82, 13, 45, 140, 112, 200, 239, 85, + 176, 142, 96, 90, 182, 14, 179, 207, 149, 15, + 120, 48, 50, 125, 117, 16, 52, 98, 196, 150, + 173, 224, 225, 226, 227, 248, 254, 257, 260, 263, + 266, 17, 62, 106, 18, 193, 64 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_uint8 yytable[] = +static const yytype_uint16 yytable[] = { - 112, 158, 115, 68, 69, 70, 117, 150, 22, 23, - 24, 25, 26, 27, 81, 133, 125, 95, 88, 89, - 139, 132, 143, 46, 142, 110, 28, 147, 183, 135, - 135, 18, 19, 136, 152, 157, 151, 29, 30, 195, - 140, 161, 186, 159, 2, 131, 167, 61, 135, 135, - 64, 31, 136, 198, 67, 84, 36, 37, 140, 140, - 92, 177, 178, 146, 72, 32, 148, 206, 187, 33, - 184, 192, 182, 34, 149, 35, 41, 194, 44, 199, - 96, 197, 58, 100, 36, 37, 38, 105, 48, 49, - 50, 51, 74, 207, 172, 205, 209, 174, 227, 77, - 60, 62, 63, 65, 126, 66, 217, 219, 232, 71, - 73, 190, 76, 221, 191, 80, 144, 225, 81, 193, - 90, 86, 94, 97, 98, 200, 230, 242, 101, 102, - 103, 106, 108, 110, 113, 233, 234, 235, 136, 208, - 116, 170, 171, 1, 119, 2, 173, 120, 127, 240, - 3, 218, 4, 129, 5, 134, 135, 6, 7, 153, - 154, 156, 162, 165, 168, 175, 179, 188, 145, 111, - 204, 201, 202, 212, 222, 203, 224, 210, 211, 223, - 220, 228, 231, 237, 243, 236, 239, 246, 241, 249, - 252, 245, 248, 255, 251, 176, 181, 254, 40, 43, - 118, 164, 226, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 79 + 91, 75, 76, 77, 145, 157, 88, 163, 101, 102, + 89, 51, 147, 164, 147, 147, 165, 108, 148, 92, + 172, 170, 147, 123, 185, 30, 155, 155, 148, 127, + 188, 130, 19, 20, 155, 132, 31, 23, 24, 25, + 26, 27, 28, 29, 32, 202, 197, 97, 195, 151, + 204, 143, 105, 33, 158, 144, 211, 209, 161, 208, + 203, 160, 154, 34, 162, 166, 39, 40, 219, 174, + 2, 217, 35, 216, 180, 171, 39, 40, 41, 66, + 229, 36, 69, 220, 71, 37, 38, 44, 74, 47, + 63, 190, 191, 49, 230, 65, 81, 198, 79, 67, + 237, 68, 70, 194, 72, 73, 205, 78, 210, 84, + 242, 80, 88, 246, 206, 214, 109, 201, 83, 113, + 87, 99, 218, 118, 103, 107, 110, 121, 252, 111, + 116, 114, 1, 228, 2, 53, 54, 55, 56, 3, + 232, 4, 5, 115, 119, 6, 138, 122, 7, 8, + 124, 128, 92, 240, 131, 134, 135, 139, 141, 146, + 148, 147, 243, 244, 245, 152, 167, 175, 169, 178, + 181, 186, 192, 199, 126, 250, 223, 238, 212, 159, + 213, 233, 183, 184, 215, 221, 222, 231, 234, 235, + 187, 241, 247, 253, 249, 251, 256, 255, 259, 262, + 258, 261, 265, 264, 189, 177, 153, 43, 137, 133, + 46, 236, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86 }; static const yytype_int16 yycheck[] = { - 87, 127, 89, 49, 50, 51, 93, 119, 2, 3, - 4, 5, 6, 7, 13, 104, 97, 73, 68, 69, - 107, 102, 109, 34, 108, 24, 0, 114, 154, 15, - 15, 29, 30, 19, 121, 20, 120, 26, 33, 165, - 25, 128, 154, 127, 9, 101, 133, 41, 15, 15, - 44, 33, 19, 165, 48, 66, 31, 32, 25, 25, - 71, 148, 149, 113, 58, 33, 116, 179, 155, 33, - 154, 160, 153, 33, 118, 33, 10, 164, 17, 166, - 74, 165, 23, 77, 31, 32, 33, 81, 3, 4, - 5, 6, 8, 180, 138, 179, 185, 141, 210, 12, - 33, 33, 33, 33, 98, 33, 193, 196, 220, 33, - 33, 157, 33, 200, 158, 33, 110, 204, 13, 163, - 27, 33, 33, 33, 11, 169, 213, 239, 33, 33, - 27, 33, 33, 24, 33, 222, 223, 224, 19, 183, - 33, 135, 136, 7, 33, 9, 140, 33, 33, 236, - 14, 195, 16, 33, 18, 33, 15, 21, 22, 33, - 33, 33, 27, 33, 27, 33, 33, 27, 111, 86, - 27, 33, 33, 27, 26, 33, 26, 33, 33, 28, - 33, 27, 33, 27, 27, 229, 33, 27, 33, 27, - 27, 33, 33, 27, 33, 146, 153, 33, 30, 32, - 94, 130, 206, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 63 + 71, 54, 55, 56, 117, 124, 13, 133, 75, 76, + 70, 37, 15, 134, 15, 15, 135, 80, 21, 26, + 139, 22, 15, 94, 150, 0, 27, 27, 21, 100, + 156, 102, 31, 32, 27, 106, 28, 2, 3, 4, + 5, 6, 7, 8, 35, 171, 167, 73, 167, 120, + 176, 114, 78, 35, 125, 115, 182, 178, 129, 178, + 173, 128, 122, 35, 131, 136, 33, 34, 194, 140, + 9, 192, 35, 192, 145, 139, 33, 34, 35, 44, + 206, 35, 47, 196, 49, 35, 35, 10, 53, 18, + 25, 162, 163, 19, 207, 35, 8, 168, 63, 35, + 221, 35, 35, 167, 35, 35, 177, 35, 179, 12, + 231, 35, 13, 239, 178, 186, 81, 170, 35, 84, + 35, 35, 193, 88, 29, 35, 35, 92, 249, 11, + 29, 35, 7, 204, 9, 3, 4, 5, 6, 14, + 211, 16, 17, 35, 35, 20, 111, 35, 23, 24, + 35, 35, 26, 224, 35, 35, 35, 35, 35, 35, + 21, 15, 233, 234, 235, 35, 35, 29, 35, 35, + 29, 29, 35, 29, 99, 246, 29, 29, 35, 126, + 35, 28, 147, 148, 35, 35, 35, 35, 30, 28, + 155, 35, 29, 29, 35, 35, 29, 35, 29, 29, + 35, 35, 29, 35, 160, 142, 122, 32, 110, 107, + 34, 217, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 68 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 7, 9, 14, 16, 18, 21, 22, 35, 48, - 49, 50, 57, 69, 73, 78, 94, 97, 29, 30, - 36, 37, 37, 37, 37, 37, 37, 37, 0, 26, - 33, 33, 33, 33, 33, 33, 31, 32, 33, 38, - 57, 10, 58, 58, 17, 75, 48, 79, 3, 4, - 5, 6, 39, 40, 43, 45, 46, 95, 23, 99, - 33, 37, 33, 33, 37, 33, 33, 37, 36, 36, - 36, 33, 37, 33, 8, 56, 33, 12, 63, 63, - 33, 13, 66, 67, 48, 80, 33, 42, 39, 39, - 27, 47, 48, 96, 33, 67, 37, 33, 11, 60, - 37, 33, 33, 27, 77, 37, 33, 74, 33, 76, - 24, 41, 38, 33, 44, 38, 33, 38, 77, 33, - 33, 54, 41, 51, 52, 66, 37, 33, 59, 33, - 65, 67, 66, 76, 33, 15, 19, 72, 82, 38, - 25, 55, 72, 38, 37, 42, 39, 38, 39, 54, - 82, 72, 38, 33, 33, 53, 33, 20, 55, 72, - 83, 38, 27, 64, 53, 33, 70, 38, 27, 68, - 37, 37, 54, 37, 54, 33, 44, 38, 38, 33, - 98, 52, 66, 55, 72, 81, 82, 38, 27, 61, - 36, 54, 76, 54, 38, 55, 71, 72, 82, 38, - 54, 33, 33, 33, 27, 72, 82, 38, 54, 76, - 33, 33, 27, 84, 85, 86, 87, 38, 54, 76, - 33, 38, 26, 28, 26, 38, 98, 82, 27, 62, - 38, 33, 82, 38, 38, 38, 54, 27, 88, 33, - 38, 33, 82, 27, 89, 33, 27, 90, 33, 27, - 91, 33, 27, 92, 33, 27, 93 + 0, 7, 9, 14, 16, 17, 20, 23, 24, 37, + 50, 51, 52, 59, 71, 75, 81, 97, 100, 31, + 32, 38, 39, 39, 39, 39, 39, 39, 39, 39, + 0, 28, 35, 35, 35, 35, 35, 35, 35, 33, + 34, 35, 40, 59, 10, 60, 60, 18, 77, 19, + 78, 50, 82, 3, 4, 5, 6, 41, 42, 45, + 47, 48, 98, 25, 102, 35, 39, 35, 35, 39, + 35, 39, 35, 35, 39, 38, 38, 38, 35, 39, + 35, 8, 58, 35, 12, 65, 65, 35, 13, 68, + 69, 40, 26, 43, 53, 54, 68, 50, 83, 35, + 44, 41, 41, 29, 49, 50, 99, 35, 69, 39, + 35, 11, 62, 39, 35, 35, 29, 80, 39, 35, + 76, 39, 35, 40, 35, 79, 43, 40, 35, 46, + 40, 35, 40, 80, 35, 35, 56, 53, 39, 35, + 61, 35, 67, 69, 68, 79, 35, 15, 21, 74, + 85, 40, 35, 54, 68, 27, 57, 74, 40, 44, + 41, 40, 41, 56, 85, 74, 40, 35, 55, 35, + 22, 57, 74, 86, 40, 29, 66, 55, 35, 72, + 40, 29, 70, 39, 39, 56, 29, 39, 56, 46, + 40, 40, 35, 101, 57, 74, 84, 85, 40, 29, + 63, 38, 56, 79, 56, 40, 57, 73, 74, 85, + 40, 56, 35, 35, 40, 35, 74, 85, 40, 56, + 79, 35, 35, 29, 87, 88, 89, 90, 40, 56, + 79, 35, 40, 28, 30, 28, 101, 85, 29, 64, + 40, 35, 85, 40, 40, 40, 56, 29, 91, 35, + 40, 35, 85, 29, 92, 35, 29, 93, 35, 29, + 94, 35, 29, 95, 35, 29, 96 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 34, 35, 36, 36, 37, 38, 38, 39, 39, - 39, 39, 40, 41, 42, 42, 43, 44, 44, 45, - 46, 47, 48, 48, 48, 48, 48, 48, 49, 49, - 50, 51, 51, 52, 52, 53, 53, 53, 53, 54, - 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 70, 70, 70, 71, 72, 73, 74, 74, 74, 75, - 76, 76, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 97, 98, 98, 98, 99 + 0, 36, 37, 38, 38, 39, 40, 40, 41, 41, + 41, 41, 42, 43, 44, 44, 45, 46, 46, 47, + 48, 49, 50, 50, 50, 50, 50, 50, 51, 51, + 52, 53, 53, 54, 54, 55, 55, 55, 55, 56, + 56, 57, 58, 59, 60, 61, 61, 61, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 72, 72, 72, 73, 74, 75, 75, 76, 76, 76, + 77, 78, 79, 79, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 100, 101, 101, + 101, 102 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -746,10 +757,11 @@ static const yytype_uint8 yyr2[] = 10, 1, 1, 3, 3, 0, 3, 3, 2, 0, 2, 5, 4, 10, 6, 0, 3, 3, 2, 8, 1, 1, 6, 1, 1, 1, 6, 1, 10, 0, - 3, 3, 2, 5, 5, 8, 0, 3, 2, 6, - 0, 3, 2, 1, 8, 1, 1, 3, 5, 4, - 1, 1, 5, 13, 1, 1, 1, 1, 1, 1, - 1, 7, 1, 1, 10, 3, 0, 2, 3, 6 + 3, 3, 2, 5, 5, 8, 7, 0, 3, 2, + 6, 3, 0, 3, 2, 1, 8, 1, 1, 3, + 5, 4, 1, 1, 5, 13, 1, 1, 1, 1, + 1, 1, 1, 7, 1, 1, 10, 3, 0, 2, + 3, 6 }; diff --git a/src/wkt1_generated_parser.h b/src/wkt1_generated_parser.h index 989f1f32..53180dec 100644 --- a/src/wkt1_generated_parser.h +++ b/src/wkt1_generated_parser.h @@ -60,18 +60,20 @@ extern int pj_wkt1_debug; T_GEOCCS = 269, T_AUTHORITY = 270, T_VERT_CS = 271, - T_VERT_DATUM = 272, - T_COMPD_CS = 273, - T_AXIS = 274, - T_TOWGS84 = 275, - T_FITTED_CS = 276, - T_LOCAL_CS = 277, - T_LOCAL_DATUM = 278, - T_PARAMETER = 279, - T_EXTENSION = 280, - T_STRING = 281, - T_NUMBER = 282, - T_IDENTIFIER = 283 + T_VERTCS = 272, + T_VERT_DATUM = 273, + T_VDATUM = 274, + T_COMPD_CS = 275, + T_AXIS = 276, + T_TOWGS84 = 277, + T_FITTED_CS = 278, + T_LOCAL_CS = 279, + T_LOCAL_DATUM = 280, + T_PARAMETER = 281, + T_EXTENSION = 282, + T_STRING = 283, + T_NUMBER = 284, + T_IDENTIFIER = 285 }; #endif diff --git a/src/wkt1_grammar.y b/src/wkt1_grammar.y index 28ff7a6e..e17135c6 100644 --- a/src/wkt1_grammar.y +++ b/src/wkt1_grammar.y @@ -53,7 +53,11 @@ %token T_GEOCCS "GEOCCS" %token T_AUTHORITY "AUTHORITY" %token T_VERT_CS "VERT_CS" +// ESRI variation +%token T_VERTCS "VERTCS" %token T_VERT_DATUM "VERT_DATUM" +// ESRI variation +%token T_VDATUM "VDATUM" %token T_COMPD_CS "COMPD_CS" %token T_AXIS "AXIS" %token T_TOWGS84 "TOWGS84" @@ -213,6 +217,7 @@ authority: vert_cs: T_VERT_CS begin_node_name ',' vert_datum ',' linear_unit opt_axis_authority end_node + | T_VERTCS begin_node_name ',' vdatum ',' opt_parameter_list_linear_unit end_node opt_axis_authority: | ',' axis opt_authority @@ -221,6 +226,9 @@ opt_axis_authority: vert_datum: T_VERT_DATUM begin_node_name ',' datum_type opt_extension_authority end_node +vdatum: + T_VDATUM begin_node_name end_node + opt_extension_authority: | ',' extension opt_authority | ',' authority diff --git a/src/wkt1_parser.cpp b/src/wkt1_parser.cpp index 9db7d4bd..5aa898b1 100644 --- a/src/wkt1_parser.cpp +++ b/src/wkt1_parser.cpp @@ -81,7 +81,12 @@ static const osr_cs_wkt_tokens tokens[] = { PAIR(PROJCS), PAIR(PROJECTION), PAIR(GEOGCS), PAIR(DATUM), PAIR(SPHEROID), PAIR(PRIMEM), PAIR(UNIT), PAIR(GEOCCS), - PAIR(AUTHORITY), PAIR(VERT_CS), PAIR(VERT_DATUM), PAIR(COMPD_CS), + PAIR(AUTHORITY), + PAIR(VERT_CS), + PAIR(VERTCS), + PAIR(VERT_DATUM), + PAIR(VDATUM), + PAIR(COMPD_CS), PAIR(AXIS), PAIR(TOWGS84), PAIR(FITTED_CS), PAIR(LOCAL_CS), PAIR(LOCAL_DATUM), diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index c988080b..6ab60270 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -3157,6 +3157,36 @@ TEST(crs, verticalCRS_as_WKT1_GDAL) { // --------------------------------------------------------------------------- +TEST(crs, verticalCRS_as_WKT1_ESRI) { + auto crs = createVerticalCRS(); + auto expected = "VERTCS[\"ODN height\",VDATUM[\"Ordnance Datum Newlyn\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",1.0]," + "UNIT[\"Meter\",1.0]]"; + + EXPECT_EQ( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI).get()), + expected); +} +// --------------------------------------------------------------------------- + +TEST(crs, verticalCRS_down_as_WKT1_ESRI) { + auto wkt = "VERTCS[\"Caspian\",VDATUM[\"Caspian_Sea\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",-1.0],UNIT[\"Meter\",1.0]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI).get()), + wkt); +} + +// --------------------------------------------------------------------------- + TEST(crs, verticalCRS_identify_db) { auto dbContext = DatabaseContext::create(); auto factory = AuthorityFactory::create(dbContext, "EPSG"); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 581083b3..767c39e9 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -2061,6 +2061,45 @@ TEST(wkt_parse, vertcrs_WKT1_GDAL_minimum) { // --------------------------------------------------------------------------- +TEST(wkt_parse, VERTCS_WKT1_ESRI) { + auto wkt = "VERTCS[\"EGM2008_Geoid\",VDATUM[\"EGM2008_Geoid\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",1.0],UNIT[\"Meter\",1.0]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->nameStr(), "EGM2008_Geoid"); + + auto datum = crs->datum(); + EXPECT_EQ(datum->nameStr(), "EGM2008_Geoid"); + + auto cs = crs->coordinateSystem(); + ASSERT_EQ(cs->axisList().size(), 1U); + EXPECT_EQ(cs->axisList()[0]->direction(), AxisDirection::UP); + + EXPECT_EQ(WKTParser().guessDialect(wkt), + WKTParser::WKTGuessedDialect::WKT1_ESRI); +} + +// --------------------------------------------------------------------------- + +TEST(wkt_parse, VERTCS_WKT1_ESRI_down) { + auto wkt = "VERTCS[\"Caspian\",VDATUM[\"Caspian_Sea\"]," + "PARAMETER[\"Vertical_Shift\",0.0]," + "PARAMETER[\"Direction\",-1.0],UNIT[\"Meter\",1.0]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); + ASSERT_TRUE(crs != nullptr); + + auto cs = crs->coordinateSystem(); + ASSERT_EQ(cs->axisList().size(), 1U); + EXPECT_EQ(cs->axisList()[0]->direction(), AxisDirection::DOWN); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, vertcrs_WKT1_LAS_ftUS) { auto wkt = "VERT_CS[\"NAVD88 - Geoid03 (Feet)\"," " VERT_DATUM[\"unknown\",2005]," |
