From da21da63d68f08de87b75149396308c451bbc347 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 9 Jul 2022 17:26:51 +0200 Subject: [PATCH] WKT ESRI import: support LINUNIT node inside GEOGCS which indicates a geographic 3D CRS --- include/proj/internal/io_internal.hpp | 1 + src/iso19111/io.cpp | 11 + src/iso19111/static.cpp | 1 + src/lib_proj.cmake | 2 +- src/wkt1_generated_parser.c | 432 +++++++++++++------------- src/wkt1_generated_parser.h | 41 +-- src/wkt1_grammar.y | 13 +- src/wkt1_parser.cpp | 1 + test/unit/test_io.cpp | 22 ++ 9 files changed, 293 insertions(+), 231 deletions(-) diff --git a/include/proj/internal/io_internal.hpp b/include/proj/internal/io_internal.hpp index e0426b59d2..2c18add0f4 100644 --- a/include/proj/internal/io_internal.hpp +++ b/include/proj/internal/io_internal.hpp @@ -69,6 +69,7 @@ class WKTConstants { static const std::string EXTENSION; // WKT1 only - GDAL specific static const std::string LOCAL_CS; // WKT1 only static const std::string LOCAL_DATUM; // WKT1 only + static const std::string LINUNIT; // WKT1 ESRI (ArcGIS Pro >= 2.7) // WKT2 preferred static const std::string GEODCRS; diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index f4cd39a422..318673f155 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2663,6 +2663,17 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */ if (unit == UnitOfMeasure::NONE) { ThrowParsingExceptionMissingUNIT(); } + + // ESRI WKT for geographic 3D CRS + auto &linUnitNode = + parentNode->GP()->lookForChild(WKTConstants::LINUNIT); + if (!isNull(linUnitNode)) { + return EllipsoidalCS:: + createLongitudeLatitudeEllipsoidalHeight( + unit, buildUnit(linUnitNode, + UnitOfMeasure::Type::LINEAR)); + } + // WKT1 --> long/lat return EllipsoidalCS::createLongitudeLatitude(unit); } diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp index f78e00febf..cad8486aea 100644 --- a/src/iso19111/static.cpp +++ b/src/iso19111/static.cpp @@ -212,6 +212,7 @@ DEFINE_WKT_CONSTANT(TOWGS84); DEFINE_WKT_CONSTANT(EXTENSION); DEFINE_WKT_CONSTANT(LOCAL_CS); DEFINE_WKT_CONSTANT(LOCAL_DATUM); +DEFINE_WKT_CONSTANT(LINUNIT); DEFINE_WKT_CONSTANT(GEODCRS); DEFINE_WKT_CONSTANT(LENGTHUNIT); diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 1e29656e24..965112de53 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -314,7 +314,7 @@ add_custom_target(check_wkt1_grammar_md5 ALL COMMAND ${CMAKE_COMMAND} "-DIN_FILE=wkt1_grammar.y" "-DTARGET=generate_wkt1_parser" - "-DEXPECTED_MD5SUM=3a1720c3fa1b759719e33dd558603efb" + "-DEXPECTED_MD5SUM=04ba1095339aeac27105f5782d6297de" -P "${CMAKE_CURRENT_SOURCE_DIR}/check_md5sum.cmake" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/wkt1_grammar.y" diff --git a/src/wkt1_generated_parser.c b/src/wkt1_generated_parser.c index 12ca7d8857..d5c4984b9d 100644 --- a/src/wkt1_generated_parser.c +++ b/src/wkt1_generated_parser.c @@ -134,8 +134,8 @@ /* Use api.header.include to #include this header instead of duplicating it here. */ -#ifndef YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED -# define YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED +#ifndef YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED +# define YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -161,23 +161,24 @@ extern int pj_wkt1_debug; T_SPHEROID = 266, T_PRIMEM = 267, T_UNIT = 268, - T_GEOCCS = 269, - T_AUTHORITY = 270, - T_VERT_CS = 271, - 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 + T_LINUNIT = 269, + T_GEOCCS = 270, + T_AUTHORITY = 271, + T_VERT_CS = 272, + T_VERTCS = 273, + T_VERT_DATUM = 274, + T_VDATUM = 275, + T_COMPD_CS = 276, + T_AXIS = 277, + T_TOWGS84 = 278, + T_FITTED_CS = 279, + T_LOCAL_CS = 280, + T_LOCAL_DATUM = 281, + T_PARAMETER = 282, + T_EXTENSION = 283, + T_STRING = 284, + T_NUMBER = 285, + T_IDENTIFIER = 286 }; #endif @@ -192,7 +193,7 @@ typedef int YYSTYPE; int pj_wkt1_parse (pj_wkt1_parse_context *context); -#endif /* !YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED */ +#endif /* !YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED */ @@ -498,19 +499,19 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 32 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 230 +#define YYLAST 252 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 36 +#define YYNTOKENS 37 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 70 +#define YYNNTS 72 /* YYNRULES -- Number of rules. */ -#define YYNRULES 107 +#define YYNRULES 113 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 274 +#define YYNSTATES 288 #define YYUNDEFTOK 2 -#define YYMAXUTOK 285 +#define YYMAXUTOK 286 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -526,12 +527,12 @@ static const yytype_int8 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, - 32, 34, 2, 2, 35, 2, 2, 2, 2, 2, + 33, 35, 2, 2, 36, 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, 31, 2, 33, 2, 2, 2, 2, 2, 2, + 2, 32, 2, 34, 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, @@ -550,24 +551,25 @@ static const yytype_int8 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, 29, 30 + 25, 26, 27, 28, 29, 30, 31 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 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, 135, - 138, 138, 142, 146, 147, 150, 151, 153, 154, 155, - 156, 158, 159, 162, 165, 168, 172, 174, 175, 176, - 177, 180, 184, 187, 190, 193, 196, 199, 202, 205, - 208, 211, 212, 213, 214, 217, 220, 223, 224, 227, - 229, 230, 231, 234, 236, 236, 239, 241, 242, 243, - 246, 249, 252, 257, 257, 259, 262, 267, 270, 272, - 275, 278, 281, 284, 287, 290, 293, 296, 299, 302, - 305, 308, 311, 313, 315, 316, 317, 320 + 0, 81, 81, 93, 93, 96, 99, 99, 102, 102, + 102, 102, 105, 108, 110, 111, 114, 116, 117, 120, + 123, 127, 132, 132, 132, 132, 132, 132, 135, 136, + 139, 139, 143, 147, 148, 151, 152, 154, 155, 156, + 157, 159, 160, 163, 166, 169, 174, 176, 177, 178, + 179, 180, 183, 185, 186, 187, 188, 191, 195, 198, + 201, 204, 207, 210, 213, 216, 219, 222, 223, 224, + 225, 228, 231, 234, 235, 238, 240, 241, 242, 245, + 247, 247, 250, 252, 253, 254, 257, 260, 263, 268, + 268, 270, 273, 278, 281, 283, 286, 289, 292, 295, + 298, 301, 304, 307, 310, 313, 316, 319, 322, 324, + 326, 327, 328, 331 }; #endif @@ -579,18 +581,19 @@ static const char *const yytname[] = "\"end of string\"", "error", "$undefined", "\"PARAM_MT\"", "\"CONCAT_MT\"", "\"INVERSE_MT\"", "\"PASSTHROUGH_MT\"", "\"PROJCS\"", "\"PROJECTION\"", "\"GEOGCS\"", "\"DATUM\"", "\"SPHEROID\"", - "\"PRIMEM\"", "\"UNIT\"", "\"GEOCCS\"", "\"AUTHORITY\"", "\"VERT_CS\"", - "\"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_with_opt_esri_vertcs", "horz_cs", - "projected_cs", "opt_parameter_list_linear_unit", + "\"PRIMEM\"", "\"UNIT\"", "\"LINUNIT\"", "\"GEOCCS\"", "\"AUTHORITY\"", + "\"VERT_CS\"", "\"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_with_opt_esri_vertcs", + "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_authority", "extension", "projection", "geographic_cs", "linunit", + "opt_linunit_or_twin_axis_extension_authority", "datum", "opt_towgs84_authority_extension", "spheroid", "semi_major_axis", "inverse_flattening", "prime_meridian", "longitude", "angular_unit", "linear_unit", "unit", "conversion_factor", "geocentric_cs", @@ -612,11 +615,11 @@ static const yytype_int16 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, 284, - 285, 91, 40, 93, 41, 44 + 285, 286, 91, 40, 93, 41, 44 }; # endif -#define YYPACT_NINF (-141) +#define YYPACT_NINF (-131) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -630,34 +633,35 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 119, 41, 41, 41, 41, 41, 41, 41, 41, 31, - -141, -141, 6, -141, -141, -141, -141, -141, -141, -141, - -141, -141, -141, 16, 32, 34, 42, 55, 68, 69, - 70, 23, -141, 37, -141, 99, 101, 101, 95, 19, - 4, 141, -141, -141, 89, -141, -141, 80, 41, 82, - 85, 41, 86, 41, -141, 87, -141, -141, 90, 41, - 41, 41, 41, -141, -141, -141, -141, -141, 92, 41, - 94, 123, 97, 125, 125, 103, 127, 63, -4, 30, - 113, 141, 141, 120, 119, 115, 127, 41, 116, 142, - 41, 117, 121, 126, 41, 124, -141, -141, 41, 133, - 63, -141, -141, -141, -141, 134, 132, 63, 135, 63, - -141, 136, -141, 63, 126, 137, 138, -4, 41, 140, - 143, 127, 127, -141, 134, 144, 28, 63, 145, -4, - -141, -3, 63, 113, -141, 141, 63, -141, 141, -141, - 138, 139, 146, 63, 147, 148, 13, 63, 152, 147, - -141, 149, 63, 156, 41, 41, -141, 138, -141, 157, - -141, -141, 41, 138, -141, -141, -141, 135, -141, 63, - 63, 153, -141, -141, 61, 63, 158, 41, 138, -141, - 134, -141, -141, 138, 63, 61, 63, -141, -141, 138, - 154, 155, -141, 63, 159, -141, -141, -141, -141, 28, - 63, 138, -141, 134, 160, -141, -141, 161, 162, -141, - -141, 63, -141, 138, 134, -141, 163, -141, 63, 164, - 167, -141, 165, -141, 153, -141, -141, -141, 139, 170, - -141, 63, -141, -141, 166, -141, -141, -141, 139, -141, - 63, 63, 63, -141, -141, -141, 138, -141, 171, 168, - -141, -141, -141, 63, -141, 169, 139, -141, 173, -141, - -141, 172, 176, -141, 174, 177, -141, 175, 179, -141, - 178, 182, -141, -141 + 97, 33, 33, 33, 33, 33, 33, 33, 33, 10, + -131, -131, 2, -131, -131, -131, -131, -131, -131, -131, + -131, -131, -131, 40, 12, 38, 47, 69, 92, 93, + 95, 89, -131, 109, -131, 102, 122, 122, 116, 1, + 22, 134, -131, -131, 115, -131, -131, 106, 33, 107, + 110, 33, 112, 33, -131, 113, -131, -131, 114, 33, + 33, 33, 33, -131, -131, -131, -131, -131, 119, 33, + 121, 137, 123, 139, 139, 125, 145, 55, 6, 91, + 126, 134, 134, 133, 97, 128, 145, 33, 129, 155, + 33, 131, 132, 140, 33, 135, -131, -131, 33, 136, + 55, -131, -131, -131, -131, 138, 146, 55, 141, 55, + -131, 142, -131, 55, 140, 143, 144, 6, 33, 149, + 150, 145, 145, -131, 138, 151, 18, 55, 152, 6, + -131, 19, 55, 126, -131, 134, 55, -131, 134, -131, + 144, 153, 160, 55, 154, 156, 75, 55, 159, 157, + -131, 158, 55, 161, 33, 33, -131, 144, -131, 165, + -131, -131, 33, 144, -131, -131, -131, 141, -131, 55, + 55, 162, -131, -131, 65, 55, 167, 33, 144, -131, + 138, -131, -131, 144, 14, 55, 65, 55, -131, -131, + 144, 163, 164, -131, 55, 166, -131, -131, -131, -131, + 18, 55, 144, -131, 138, 168, -131, -131, 169, 171, + -131, -131, 55, 33, 144, 144, -131, 138, -131, 144, + 138, -131, 170, -131, 55, 178, 177, -131, 180, -131, + 162, -131, -131, -131, 153, 182, -131, 55, -131, -131, + 174, -131, 179, -131, -131, -131, -131, -131, 153, -131, + 55, 55, 55, -131, -131, -131, 144, -131, 183, 161, + 181, -131, -131, -131, 55, -131, 184, 144, 153, -131, + 186, 55, -131, -131, 185, -131, 188, -131, 187, 189, + -131, 190, 192, -131, 191, 194, -131, -131 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -666,45 +670,47 @@ static const yytype_int16 yypact[] = static const yytype_int8 yydefact[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 22, 28, 31, 30, 23, 24, 68, 25, 26, + 2, 22, 28, 31, 30, 23, 24, 74, 25, 26, 27, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 6, 7, 0, 103, 29, 0, 0, 0, - 0, 0, 0, 0, 75, 0, 74, 82, 0, 0, - 0, 0, 0, 100, 8, 9, 10, 11, 0, 0, + 0, 0, 6, 7, 0, 109, 29, 0, 0, 0, + 0, 0, 0, 0, 81, 0, 80, 88, 0, 0, + 0, 0, 0, 106, 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, 70, 57, 76, 0, 0, - 0, 34, 33, 83, 84, 77, 0, 0, 17, 0, - 21, 0, 101, 0, 0, 0, 41, 0, 0, 47, - 0, 0, 0, 80, 77, 0, 0, 0, 0, 0, - 69, 0, 0, 14, 12, 0, 0, 19, 0, 99, - 41, 0, 0, 0, 37, 0, 0, 0, 0, 37, - 56, 61, 0, 0, 0, 0, 72, 41, 67, 0, - 35, 36, 0, 41, 79, 81, 15, 17, 16, 0, - 0, 104, 42, 44, 0, 0, 0, 0, 41, 50, - 77, 46, 55, 41, 0, 0, 0, 73, 59, 41, - 0, 0, 71, 0, 0, 78, 18, 20, 107, 0, - 0, 41, 40, 77, 0, 32, 52, 0, 0, 49, - 48, 0, 45, 41, 77, 64, 0, 60, 0, 0, - 0, 13, 0, 105, 104, 102, 39, 38, 0, 0, - 92, 0, 89, 88, 0, 54, 63, 62, 0, 58, - 0, 0, 0, 106, 85, 53, 41, 87, 0, 0, - 66, 86, 43, 0, 93, 0, 0, 51, 0, 65, - 94, 90, 0, 95, 0, 0, 96, 0, 0, 97, - 0, 0, 98, 91 + 0, 0, 0, 0, 0, 76, 63, 82, 0, 0, + 0, 34, 33, 89, 90, 83, 0, 0, 17, 0, + 21, 0, 107, 0, 0, 0, 41, 0, 0, 53, + 0, 0, 0, 86, 83, 0, 0, 0, 0, 0, + 75, 0, 0, 14, 12, 0, 0, 19, 0, 105, + 41, 0, 0, 0, 37, 0, 0, 0, 0, 47, + 62, 67, 0, 0, 0, 0, 78, 41, 73, 0, + 35, 36, 0, 41, 85, 87, 15, 17, 16, 0, + 0, 110, 42, 44, 0, 0, 0, 0, 41, 56, + 83, 52, 61, 41, 0, 0, 0, 0, 79, 65, + 41, 0, 0, 77, 0, 0, 84, 18, 20, 113, + 0, 0, 41, 40, 83, 0, 32, 58, 0, 0, + 55, 54, 0, 0, 41, 41, 51, 83, 45, 41, + 83, 70, 0, 66, 0, 0, 0, 13, 0, 111, + 110, 108, 39, 38, 0, 0, 98, 0, 95, 94, + 0, 60, 0, 50, 48, 49, 69, 68, 0, 64, + 0, 0, 0, 112, 91, 59, 41, 93, 0, 0, + 0, 72, 92, 43, 0, 99, 0, 41, 0, 57, + 0, 0, 71, 100, 96, 46, 0, 101, 0, 0, + 102, 0, 0, 103, 0, 0, 104, 97 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -141, -141, -59, 12, -77, -55, -141, 56, 44, -141, - 45, -141, -141, -141, 130, -141, 180, -141, 98, 88, - 67, -89, -140, -141, -27, 48, -141, -141, -141, -141, - 150, -141, -141, -43, -79, -141, -141, -141, -141, -121, - 151, 185, -141, -141, -141, -141, -119, 105, -141, -141, - -141, -141, -137, -141, -141, -141, -141, -141, -141, -141, - -141, -141, -141, -141, -141, -141, -141, -141, -2, -141 + -131, -131, -47, -2, -68, -58, -131, 108, 48, -131, + 58, -131, -131, -131, 147, -131, 193, -131, 111, 100, + -131, -120, -130, -131, -27, -131, -131, 16, -131, -131, + -131, -131, 172, -131, -131, -51, -60, -29, -131, -131, + -131, -124, 173, 199, -131, -131, -131, -131, -107, 120, + -131, -131, -131, 51, -114, -131, -131, -131, -131, -131, + -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, + 7, -131 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -712,11 +718,12 @@ static const yytype_int16 yydefgoto[] = { -1, 9, 23, 24, 45, 63, 64, 99, 107, 65, 136, 66, 67, 111, 10, 11, 12, 13, 100, 101, - 175, 143, 163, 88, 14, 49, 147, 119, 207, 246, - 91, 183, 149, 102, 96, 189, 15, 186, 214, 156, - 16, 17, 127, 52, 55, 56, 132, 124, 18, 58, - 105, 203, 157, 180, 231, 232, 233, 234, 255, 261, - 264, 267, 270, 273, 19, 68, 113, 20, 200, 70 + 175, 143, 163, 88, 14, 215, 185, 49, 147, 119, + 208, 256, 91, 183, 149, 102, 96, 190, 15, 187, + 220, 156, 16, 17, 127, 52, 55, 56, 132, 124, + 18, 58, 105, 204, 205, 180, 237, 238, 239, 240, + 266, 274, 278, 281, 284, 287, 19, 68, 113, 20, + 201, 70 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -724,108 +731,114 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 97, 81, 82, 83, 171, 152, 178, 115, 47, 94, - 164, 1, 154, 2, 25, 26, 27, 28, 29, 30, - 31, 172, 98, 130, 162, 179, 108, 109, 154, 48, - 134, 32, 137, 95, 201, 177, 139, 204, 53, 2, - 162, 33, 150, 154, 34, 213, 4, 5, 216, 155, - 158, 170, 103, 202, 5, 165, 42, 43, 44, 168, - 72, 210, 224, 75, 215, 77, 173, 35, 192, 36, - 181, 80, 21, 22, 195, 187, 154, 37, 223, 151, - 167, 85, 155, 169, 227, 50, 161, 54, 162, 209, - 38, 244, 197, 198, 211, 237, 42, 43, 205, 116, - 218, 249, 120, 39, 40, 41, 125, 212, 2, 217, - 128, 48, 226, 51, 69, 71, 221, 73, 208, 259, - 74, 76, 78, 225, 236, 79, 1, 84, 2, 86, - 145, 87, 89, 3, 235, 4, 5, 90, 93, 6, - 94, 239, 7, 8, 59, 60, 61, 62, 106, 110, - 114, 117, 121, 118, 247, 123, 122, 253, 98, 126, - 155, 154, 133, 250, 251, 252, 190, 191, 129, 131, - 135, 138, 141, 142, 194, 146, 257, 166, 148, 153, - 159, 182, 174, 176, 185, 188, 193, 206, 199, 219, - 220, 230, 240, 242, 222, 228, 229, 241, 238, 245, - 254, 248, 260, 256, 258, 263, 266, 262, 269, 265, - 268, 272, 196, 271, 112, 144, 184, 160, 46, 140, - 57, 0, 243, 0, 92, 0, 0, 0, 0, 0, - 104 + 25, 26, 27, 28, 29, 30, 31, 164, 47, 97, + 32, 48, 157, 81, 82, 83, 178, 152, 172, 94, + 170, 53, 179, 108, 109, 95, 115, 171, 213, 1, + 154, 2, 130, 98, 154, 154, 155, 193, 33, 134, + 155, 137, 162, 196, 202, 139, 72, 162, 35, 75, + 203, 77, 103, 50, 214, 54, 219, 80, 210, 158, + 216, 150, 221, 212, 165, 21, 22, 85, 168, 34, + 224, 151, 222, 211, 36, 173, 229, 167, 161, 181, + 169, 154, 232, 37, 188, 116, 230, 155, 120, 42, + 43, 154, 125, 162, 243, 244, 128, 233, 177, 246, + 2, 198, 199, 162, 1, 38, 2, 206, 4, 5, + 245, 2, 3, 247, 4, 5, 145, 218, 6, 223, + 254, 7, 8, 42, 43, 44, 227, 5, 39, 40, + 209, 41, 48, 231, 260, 51, 264, 59, 60, 61, + 62, 69, 71, 73, 241, 87, 74, 271, 76, 78, + 79, 90, 191, 192, 272, 84, 249, 86, 94, 89, + 195, 93, 106, 110, 114, 117, 118, 121, 122, 257, + 123, 126, 129, 98, 131, 155, 154, 135, 138, 141, + 142, 166, 261, 262, 263, 146, 148, 153, 159, 182, + 174, 189, 176, 184, 186, 194, 269, 207, 200, 225, + 226, 236, 228, 275, 234, 235, 248, 250, 251, 252, + 258, 242, 255, 265, 133, 259, 273, 268, 277, 280, + 270, 276, 283, 279, 286, 197, 282, 285, 144, 160, + 267, 112, 46, 57, 140, 217, 0, 253, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 104 }; static const yytype_int16 yycheck[] = { - 77, 60, 61, 62, 141, 124, 146, 86, 35, 13, - 131, 7, 15, 9, 2, 3, 4, 5, 6, 7, - 8, 142, 26, 100, 27, 146, 81, 82, 15, 10, - 107, 0, 109, 76, 174, 22, 113, 174, 19, 9, - 27, 35, 121, 15, 28, 185, 16, 17, 185, 21, - 127, 140, 79, 174, 17, 132, 33, 34, 35, 136, - 48, 180, 199, 51, 185, 53, 143, 35, 157, 35, - 147, 59, 31, 32, 163, 152, 15, 35, 199, 122, - 135, 69, 21, 138, 203, 37, 129, 39, 27, 178, - 35, 228, 169, 170, 183, 214, 33, 34, 175, 87, - 189, 238, 90, 35, 35, 35, 94, 184, 9, 186, - 98, 10, 201, 18, 25, 35, 193, 35, 177, 256, - 35, 35, 35, 200, 213, 35, 7, 35, 9, 35, - 118, 8, 35, 14, 211, 16, 17, 12, 35, 20, - 13, 218, 23, 24, 3, 4, 5, 6, 35, 29, - 35, 35, 35, 11, 231, 29, 35, 246, 26, 35, - 21, 15, 106, 240, 241, 242, 154, 155, 35, 35, - 35, 35, 35, 35, 162, 35, 253, 133, 35, 35, - 35, 29, 35, 35, 35, 29, 29, 29, 35, 35, - 35, 29, 28, 28, 35, 35, 35, 30, 35, 29, - 29, 35, 29, 35, 35, 29, 29, 35, 29, 35, - 35, 29, 167, 35, 84, 117, 149, 129, 33, 114, - 40, -1, 224, -1, 74, -1, -1, -1, -1, -1, - 79 + 2, 3, 4, 5, 6, 7, 8, 131, 35, 77, + 0, 10, 126, 60, 61, 62, 146, 124, 142, 13, + 140, 20, 146, 81, 82, 76, 86, 141, 14, 7, + 16, 9, 100, 27, 16, 16, 22, 157, 36, 107, + 22, 109, 28, 163, 174, 113, 48, 28, 36, 51, + 174, 53, 79, 37, 184, 39, 186, 59, 178, 127, + 184, 121, 186, 183, 132, 32, 33, 69, 136, 29, + 190, 122, 186, 180, 36, 143, 200, 135, 129, 147, + 138, 16, 202, 36, 152, 87, 200, 22, 90, 34, + 35, 16, 94, 28, 214, 215, 98, 204, 23, 219, + 9, 169, 170, 28, 7, 36, 9, 175, 17, 18, + 217, 9, 15, 220, 17, 18, 118, 185, 21, 187, + 234, 24, 25, 34, 35, 36, 194, 18, 36, 36, + 177, 36, 10, 201, 248, 19, 256, 3, 4, 5, + 6, 26, 36, 36, 212, 8, 36, 267, 36, 36, + 36, 12, 154, 155, 268, 36, 224, 36, 13, 36, + 162, 36, 36, 30, 36, 36, 11, 36, 36, 237, + 30, 36, 36, 27, 36, 22, 16, 36, 36, 36, + 36, 133, 250, 251, 252, 36, 36, 36, 36, 30, + 36, 30, 36, 36, 36, 30, 264, 30, 36, 36, + 36, 30, 36, 271, 36, 36, 36, 29, 31, 29, + 36, 213, 30, 30, 106, 36, 30, 36, 30, 30, + 36, 36, 30, 36, 30, 167, 36, 36, 117, 129, + 259, 84, 33, 40, 114, 184, -1, 230, -1, -1, + -1, -1, -1, -1, -1, -1, 74, -1, -1, -1, + -1, -1, 79 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 7, 9, 14, 16, 17, 20, 23, 24, 37, - 50, 51, 52, 53, 60, 72, 76, 77, 84, 100, - 103, 31, 32, 38, 39, 39, 39, 39, 39, 39, - 39, 39, 0, 35, 28, 35, 35, 35, 35, 35, - 35, 35, 33, 34, 35, 40, 77, 60, 10, 61, - 61, 18, 79, 19, 61, 80, 81, 52, 85, 3, - 4, 5, 6, 41, 42, 45, 47, 48, 101, 25, - 105, 35, 39, 35, 35, 39, 35, 39, 35, 35, - 39, 38, 38, 38, 35, 39, 35, 8, 59, 35, - 12, 66, 66, 35, 13, 69, 70, 40, 26, 43, - 54, 55, 69, 60, 76, 86, 35, 44, 41, 41, - 29, 49, 50, 102, 35, 70, 39, 35, 11, 63, - 39, 35, 35, 29, 83, 39, 35, 78, 39, 35, - 40, 35, 82, 43, 40, 35, 46, 40, 35, 40, - 83, 35, 35, 57, 54, 39, 35, 62, 35, 68, - 70, 69, 82, 35, 15, 21, 75, 88, 40, 35, - 55, 69, 27, 58, 75, 40, 44, 41, 40, 41, - 57, 88, 75, 40, 35, 56, 35, 22, 58, 75, - 89, 40, 29, 67, 56, 35, 73, 40, 29, 71, - 39, 39, 57, 29, 39, 57, 46, 40, 40, 35, - 104, 58, 75, 87, 88, 40, 29, 64, 38, 57, - 82, 57, 40, 58, 74, 75, 88, 40, 57, 35, - 35, 40, 35, 75, 88, 40, 57, 82, 35, 35, - 29, 90, 91, 92, 93, 40, 57, 82, 35, 40, - 28, 30, 28, 104, 88, 29, 65, 40, 35, 88, - 40, 40, 40, 57, 29, 94, 35, 40, 35, 88, - 29, 95, 35, 29, 96, 35, 29, 97, 35, 29, - 98, 35, 29, 99 + 0, 7, 9, 15, 17, 18, 21, 24, 25, 38, + 51, 52, 53, 54, 61, 75, 79, 80, 87, 103, + 106, 32, 33, 39, 40, 40, 40, 40, 40, 40, + 40, 40, 0, 36, 29, 36, 36, 36, 36, 36, + 36, 36, 34, 35, 36, 41, 80, 61, 10, 64, + 64, 19, 82, 20, 64, 83, 84, 53, 88, 3, + 4, 5, 6, 42, 43, 46, 48, 49, 104, 26, + 108, 36, 40, 36, 36, 40, 36, 40, 36, 36, + 40, 39, 39, 39, 36, 40, 36, 8, 60, 36, + 12, 69, 69, 36, 13, 72, 73, 41, 27, 44, + 55, 56, 72, 61, 79, 89, 36, 45, 42, 42, + 30, 50, 51, 105, 36, 73, 40, 36, 11, 66, + 40, 36, 36, 30, 86, 40, 36, 81, 40, 36, + 41, 36, 85, 44, 41, 36, 47, 41, 36, 41, + 86, 36, 36, 58, 55, 40, 36, 65, 36, 71, + 73, 72, 85, 36, 16, 22, 78, 91, 41, 36, + 56, 72, 28, 59, 78, 41, 45, 42, 41, 42, + 58, 91, 78, 41, 36, 57, 36, 23, 59, 78, + 92, 41, 30, 70, 36, 63, 36, 76, 41, 30, + 74, 40, 40, 58, 30, 40, 58, 47, 41, 41, + 36, 107, 59, 78, 90, 91, 41, 30, 67, 39, + 58, 85, 58, 14, 59, 62, 78, 90, 41, 59, + 77, 78, 91, 41, 58, 36, 36, 41, 36, 78, + 91, 41, 58, 85, 36, 36, 30, 93, 94, 95, + 96, 41, 40, 58, 58, 85, 58, 85, 36, 41, + 29, 31, 29, 107, 91, 30, 68, 41, 36, 36, + 91, 41, 41, 41, 58, 30, 97, 74, 36, 41, + 36, 58, 91, 30, 98, 41, 36, 30, 99, 36, + 30, 100, 36, 30, 101, 36, 30, 102 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { - 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, 52, 53, 54, 54, 55, 55, 56, 56, 56, - 56, 57, 57, 58, 59, 60, 61, 62, 62, 62, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 73, 73, 73, 74, 75, 76, 76, 77, - 78, 78, 78, 79, 80, 80, 81, 82, 82, 82, - 83, 84, 85, 86, 86, 87, 88, 89, 90, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 103, 104, 104, 104, 105 + 0, 37, 38, 39, 39, 40, 41, 41, 42, 42, + 42, 42, 43, 44, 45, 45, 46, 47, 47, 48, + 49, 50, 51, 51, 51, 51, 51, 51, 52, 52, + 53, 53, 54, 55, 55, 56, 56, 57, 57, 57, + 57, 58, 58, 59, 60, 61, 62, 63, 63, 63, + 63, 63, 64, 65, 65, 65, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 76, 76, + 76, 77, 78, 79, 79, 80, 81, 81, 81, 82, + 83, 83, 84, 85, 85, 85, 86, 87, 88, 89, + 89, 90, 91, 92, 93, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 106, + 107, 107, 107, 108 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -836,12 +849,13 @@ static const yytype_int8 yyr2[] = 6, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 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, 1, 7, - 0, 3, 2, 6, 1, 1, 3, 0, 3, 2, - 1, 8, 1, 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, 2, 6, 0, 3, 3, 2, 8, 1, 1, + 6, 1, 1, 1, 6, 1, 10, 0, 3, 3, + 2, 5, 5, 8, 1, 7, 0, 3, 2, 6, + 1, 1, 3, 0, 3, 2, 1, 8, 1, 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 2522743eb1..758838560a 100644 --- a/src/wkt1_generated_parser.h +++ b/src/wkt1_generated_parser.h @@ -34,8 +34,8 @@ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ -#ifndef YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED -# define YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED +#ifndef YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED +# define YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -61,23 +61,24 @@ extern int pj_wkt1_debug; T_SPHEROID = 266, T_PRIMEM = 267, T_UNIT = 268, - T_GEOCCS = 269, - T_AUTHORITY = 270, - T_VERT_CS = 271, - 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 + T_LINUNIT = 269, + T_GEOCCS = 270, + T_AUTHORITY = 271, + T_VERT_CS = 272, + T_VERTCS = 273, + T_VERT_DATUM = 274, + T_VDATUM = 275, + T_COMPD_CS = 276, + T_AXIS = 277, + T_TOWGS84 = 278, + T_FITTED_CS = 279, + T_LOCAL_CS = 280, + T_LOCAL_DATUM = 281, + T_PARAMETER = 282, + T_EXTENSION = 283, + T_STRING = 284, + T_NUMBER = 285, + T_IDENTIFIER = 286 }; #endif @@ -92,4 +93,4 @@ typedef int YYSTYPE; int pj_wkt1_parse (pj_wkt1_parse_context *context); -#endif /* !YY_PJ_WKT1_SRC_WKT1_GENERATED_PARSER_H_INCLUDED */ +#endif /* !YY_PJ_WKT1_WKT1_GENERATED_PARSER_H_INCLUDED */ diff --git a/src/wkt1_grammar.y b/src/wkt1_grammar.y index b5f27e6109..f3e9dba962 100644 --- a/src/wkt1_grammar.y +++ b/src/wkt1_grammar.y @@ -50,6 +50,7 @@ %token T_SPHEROID "SPHEROID" %token T_PRIMEM "PRIMEM" %token T_UNIT "UNIT" +%token T_LINUNIT "LINUNIT" %token T_GEOCCS "GEOCCS" %token T_AUTHORITY "AUTHORITY" %token T_VERT_CS "VERT_CS" @@ -166,7 +167,17 @@ projection: geographic_cs: T_GEOGCS begin_node_name',' datum ',' prime_meridian ',' - angular_unit opt_twin_axis_extension_authority end_node + angular_unit opt_linunit_or_twin_axis_extension_authority end_node + +/* ESRI extension for geographic 3D CRS */ +linunit: + T_LINUNIT begin_node_name',' conversion_factor opt_authority end_node + +opt_linunit_or_twin_axis_extension_authority: + | ',' linunit opt_authority + | ',' twin_axis opt_extension_authority + | ',' extension opt_authority + | ',' authority datum: T_DATUM begin_node_name ',' spheroid opt_towgs84_authority_extension end_node diff --git a/src/wkt1_parser.cpp b/src/wkt1_parser.cpp index 5aa898b19a..0d75f84a0e 100644 --- a/src/wkt1_parser.cpp +++ b/src/wkt1_parser.cpp @@ -89,6 +89,7 @@ static const osr_cs_wkt_tokens tokens[] = { PAIR(COMPD_CS), PAIR(AXIS), PAIR(TOWGS84), PAIR(FITTED_CS), PAIR(LOCAL_CS), PAIR(LOCAL_DATUM), + PAIR(LINUNIT), PAIR(EXTENSION)}; diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 9e1be09211..d6632770ec 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -509,6 +509,28 @@ TEST(wkt_parse, wkt1_esri_EPSG_4901_grad) { // --------------------------------------------------------------------------- +TEST(wkt_parse, wkt1_esri_LINUNIT) { + const auto wkt = "GEOGCS[\"WGS_1984_3D\",DATUM[\"D_WGS_1984\"," + "SPHEROID[\"WGS_1984\",6378137.0,298.257223563]]," + "PRIMEM[\"Greenwich\",0.0]," + "UNIT[\"Degree\",0.0174532925199433]," + "LINUNIT[\"Meter\",1.0]]"; + auto obj = WKTParser() + .attachDatabaseContext(DatabaseContext::create()) + .createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + const auto &axisList = crs->coordinateSystem()->axisList(); + ASSERT_EQ(axisList.size(), 3U); + EXPECT_NEAR(axisList[0]->unit().conversionToSI(), 0.0174532925199433, + 1e-15); + EXPECT_NEAR(axisList[1]->unit().conversionToSI(), 0.0174532925199433, + 1e-15); + EXPECT_EQ(axisList[2]->unit(), UnitOfMeasure::METRE); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, wkt2_epsg_org_EPSG_4901_PRIMEM_weird_sexagesimal_DMS) { // Current epsg.org output may use the EPSG:9110 "sexagesimal DMS" // unit and a DD.MMSSsss value, but this will likely be changed to