aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-10-09 12:53:17 +0200
committerGitHub <noreply@github.com>2021-10-09 12:53:17 +0200
commitfdaf93449faebc80b53b09208f9766bca68a084b (patch)
tree11a87a09aaa7150304532414534b5d01c6f65994
parent02225ff0bb11ea137751d9694978e61060f829bd (diff)
parent371a926b398876e534f7289189266506d27fcddc (diff)
downloadPROJ-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.cpp47
-rw-r--r--src/iso19111/operation/parammappings.cpp5
-rw-r--r--test/unit/test_io.cpp31
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);