aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-08-13 18:06:22 +0200
committerGitHub <noreply@github.com>2020-08-13 18:06:22 +0200
commitb8c198897da30e59d41f7b9ccb66bc1b0079e5d8 (patch)
tree043294bf305c46986a0fc3e268efda0c264455d0 /src
parent9701afb98c93fd575982265428af53849ee213b6 (diff)
downloadPROJ-b8c198897da30e59d41f7b9ccb66bc1b0079e5d8.tar.gz
PROJ-b8c198897da30e59d41f7b9ccb66bc1b0079e5d8.zip
WKT importer: tune for Oracle WKT and 'Lambert Conformal Conic' (#2321)
Fixes https://github.com/qgis/QGIS/issues/37898
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/io.cpp57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 57f358df..6680ab00 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -1535,6 +1535,19 @@ PropertyMap &WKTParser::Private::buildProperties(const WKTNodeNNPtr &node,
std::string codeFromAlias;
const auto *nodeP = node->GP();
const auto &nodeChildren = nodeP->children();
+
+ auto identifiers = ArrayOfBaseObject::create();
+ for (const auto &subNode : nodeChildren) {
+ const auto &subNodeName(subNode->GP()->value());
+ if (ci_equal(subNodeName, WKTConstants::ID) ||
+ ci_equal(subNodeName, WKTConstants::AUTHORITY)) {
+ auto id = buildId(subNode, true, removeInverseOf);
+ if (id) {
+ identifiers->add(NN_NO_CHECK(id));
+ }
+ }
+ }
+
if (!nodeChildren.empty()) {
const auto &nodeName(nodeP->value());
auto name(stripQuotes(nodeChildren[0]));
@@ -1547,6 +1560,26 @@ PropertyMap &WKTParser::Private::buildProperties(const WKTNodeNNPtr &node,
properties->set(common::IdentifiedObject::DEPRECATED_KEY, true);
}
+ // Oracle WKT can contain names like
+ // "Reseau Geodesique Francais 1993 (EPSG ID 6171)"
+ // for WKT attributes to the auth_name = "IGN - Paris"
+ // Strip that suffix from the name and assign a true EPSG code to the
+ // object
+ if (identifiers->empty()) {
+ const auto pos = name.find(" (EPSG ID ");
+ if (pos != std::string::npos && name.back() == ')') {
+ const auto code =
+ name.substr(pos + strlen(" (EPSG ID "),
+ name.size() - 1 - pos - strlen(" (EPSG ID "));
+ name.resize(pos);
+
+ PropertyMap propertiesId;
+ propertiesId.set(Identifier::CODESPACE_KEY, Identifier::EPSG);
+ propertiesId.set(Identifier::AUTHORITY_KEY, Identifier::EPSG);
+ identifiers->add(Identifier::create(code, propertiesId));
+ }
+ }
+
const char *tableNameForAlias = nullptr;
if (ci_equal(nodeName, WKTConstants::GEOGCS)) {
if (starts_with(name, "GCS_")) {
@@ -1589,17 +1622,6 @@ PropertyMap &WKTParser::Private::buildProperties(const WKTNodeNNPtr &node,
properties->set(IdentifiedObject::NAME_KEY, name);
}
- auto identifiers = ArrayOfBaseObject::create();
- for (const auto &subNode : nodeChildren) {
- const auto &subNodeName(subNode->GP()->value());
- if (ci_equal(subNodeName, WKTConstants::ID) ||
- ci_equal(subNodeName, WKTConstants::AUTHORITY)) {
- auto id = buildId(subNode, true, removeInverseOf);
- if (id) {
- identifiers->add(NN_NO_CHECK(id));
- }
- }
- }
if (identifiers->empty() && !authNameFromAlias.empty()) {
identifiers->add(Identifier::create(
codeFromAlias,
@@ -3606,6 +3628,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();
@@ -3658,6 +3681,10 @@ 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(
@@ -3674,6 +3701,14 @@ 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.