diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-10-09 12:53:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-09 12:53:17 +0200 |
| commit | fdaf93449faebc80b53b09208f9766bca68a084b (patch) | |
| tree | 11a87a09aaa7150304532414534b5d01c6f65994 | |
| parent | 02225ff0bb11ea137751d9694978e61060f829bd (diff) | |
| parent | 371a926b398876e534f7289189266506d27fcddc (diff) | |
| download | PROJ-fdaf93449faebc80b53b09208f9766bca68a084b.tar.gz PROJ-fdaf93449faebc80b53b09208f9766bca68a084b.zip | |
Merge pull request #2893 from rouault/fix_2892
WKT1 parser: recognize Lambert_Conformal_Conic as projection name for LCC 1SP or 2SP (fixes #2892)
| -rw-r--r-- | src/iso19111/io.cpp | 47 | ||||
| -rw-r--r-- | src/iso19111/operation/parammappings.cpp | 5 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 31 |
3 files changed, 65 insertions, 18 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 24201ee1..9ce642e7 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -3800,6 +3800,39 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard( tryToIdentifyWKT1Method ? getMappingFromWKT1(projectionName) : nullptr; if (mapping) { mapping = selectSphericalOrEllipsoidal(mapping, baseGeodCRS); + } else if (metadata::Identifier::isEquivalentName( + projectionName.c_str(), "Lambert Conformal Conic")) { + // Lambert Conformal Conic or Lambert_Conformal_Conic are respectively + // used by Oracle WKT and Trimble for either LCC 1SP or 2SP, so we + // have to look at parameters to figure out the variant. + bool found2ndStdParallel = false; + bool foundScaleFactor = false; + for (const auto &childNode : projCRSNode->GP()->children()) { + if (ci_equal(childNode->GP()->value(), WKTConstants::PARAMETER)) { + const auto &childNodeChildren = childNode->GP()->children(); + if (childNodeChildren.size() < 2) { + ThrowNotEnoughChildren(WKTConstants::PARAMETER); + } + const std::string wkt1ParameterName( + stripQuotes(childNodeChildren[0])); + if (metadata::Identifier::isEquivalentName( + wkt1ParameterName.c_str(), WKT1_STANDARD_PARALLEL_2)) { + found2ndStdParallel = true; + } else if (metadata::Identifier::isEquivalentName( + wkt1ParameterName.c_str(), WKT1_SCALE_FACTOR)) { + foundScaleFactor = true; + } + } + } + if (found2ndStdParallel && !foundScaleFactor) { + mapping = getMapping(EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP); + } else if (!found2ndStdParallel && foundScaleFactor) { + mapping = getMapping(EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP); + } else if (found2ndStdParallel && foundScaleFactor) { + // Not sure if that happens + mapping = getMapping( + EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN); + } } // For Krovak, we need to look at axis to decide between the Krovak and @@ -3833,7 +3866,7 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard( } foundParameters.resize(countParams); } - bool found2ndStdParallel = false; + for (const auto &childNode : projCRSNode->GP()->children()) { if (ci_equal(childNode->GP()->value(), WKTConstants::PARAMETER)) { const auto &childNodeChildren = childNode->GP()->children(); @@ -3886,10 +3919,6 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard( propertiesParameter.set(Identifier::CODESPACE_KEY, Identifier::EPSG); } - if (paramMapping->epsg_code == - EPSG_CODE_PARAMETER_LATITUDE_2ND_STD_PARALLEL) { - found2ndStdParallel = true; - } } propertiesParameter.set(IdentifiedObject::NAME_KEY, parameterName); parameters.push_back( @@ -3906,14 +3935,6 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard( } } - // Oracle WKT: make sure that the 2nd std parallel parameter is found to - // select the LCC_2SP mapping - if (metadata::Identifier::isEquivalentName(wkt1ProjectionName.c_str(), - "Lambert Conformal Conic") && - !found2ndStdParallel) { - propertiesMethod.set(IdentifiedObject::NAME_KEY, wkt1ProjectionName); - } - // Add back important parameters that should normally be present, but // are sometimes missing. Currently we only deal with Scale factor at // natural origin. This is to avoid a default value of 0 to slip in later. diff --git a/src/iso19111/operation/parammappings.cpp b/src/iso19111/operation/parammappings.cpp index df5ae7c5..240a2b50 100644 --- a/src/iso19111/operation/parammappings.cpp +++ b/src/iso19111/operation/parammappings.cpp @@ -598,11 +598,6 @@ static const MethodMapping projectionMethodMappings[] = { EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP, "Lambert_Conformal_Conic_2SP", "lcc", nullptr, paramsLCC2SP}, - // Oracle WKT - {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP, - EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP, "Lambert Conformal Conic", - "lcc", nullptr, paramsLCC2SP}, - {EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN, EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP_MICHIGAN, nullptr, // no mapping to WKT1_GDAL diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 4e888f2c..196552d4 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -6394,6 +6394,37 @@ TEST(wkt_parse, wkt1_oracle) { // --------------------------------------------------------------------------- +TEST(wkt_parse, wkt1_lcc_1sp_without_1sp_suffix) { + // WKT from Trimble + auto wkt = "PROJCS[\"TWM-Madison Co LDP\"," + "GEOGCS[\"WGS 1984\"," + "DATUM[\"WGS 1984\"," + "SPHEROID[\"World Geodetic System 1984\"," + "6378137,298.257223563]]," + "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]]," + "UNIT[\"Degree\",0.01745329251994," + "AUTHORITY[\"EPSG\",\"9102\"]]," + "AXIS[\"Long\",EAST],AXIS[\"Lat\",NORTH]]," + "PROJECTION[\"Lambert_Conformal_Conic\"]," + "PARAMETER[\"False_Easting\",103000.0000035]," + "PARAMETER[\"False_Northing\",79000.00007055]," + "PARAMETER[\"Latitude_Of_Origin\",38.83333333333]," + "PARAMETER[\"Central_Meridian\",-89.93333333333]," + "PARAMETER[\"Scale_Factor\",1.000019129]," + "UNIT[\"Foot_US\",0.3048006096012,AUTHORITY[\"EPSG\",\"9003\"]]," + "AXIS[\"East\",EAST],AXIS[\"North\",NORTH]]"; + + auto dbContext = DatabaseContext::create(); + auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); + ASSERT_TRUE(crs != nullptr); + + EXPECT_EQ(crs->derivingConversion()->method()->nameStr(), + "Lambert Conic Conformal (1SP)"); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, invalid) { EXPECT_THROW(WKTParser().createFromWKT(""), ParsingException); EXPECT_THROW(WKTParser().createFromWKT("A"), ParsingException); |
