aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-08-26 16:27:38 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-08-26 16:27:38 +0200
commita667e86dd482795d4b5118935538cecbc852f608 (patch)
treece98c1c51e01961f9436cb569303f91e8be72cc3 /src
parentdb5a6e683bdd80dedc7140b8f8af65e586b72e02 (diff)
downloadPROJ-a667e86dd482795d4b5118935538cecbc852f608.tar.gz
PROJ-a667e86dd482795d4b5118935538cecbc852f608.zip
WKT importer: detect ESRI WKT even when datum name doesn't start with D_ (fixes #2822)
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/io.cpp68
1 files changed, 51 insertions, 17 deletions
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 35249d16..ccfc4488 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -1239,6 +1239,7 @@ struct WKTParser::Private {
std::vector<double> toWGS84Parameters_{};
std::string datumPROJ4Grids_{};
bool esriStyle_ = false;
+ bool maybeEsriStyle_ = false;
DatabaseContextPtr dbContext_{};
static constexpr int MAX_PROPERTY_SIZE = 1024;
@@ -2203,17 +2204,39 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
// Remap GDAL WGS_1984 to EPSG v9 "World Geodetic System 1984" official
// name.
// Also remap EPSG v10 datum ensemble names to non-ensemble EPSG v9
+ bool nameSet = false;
if (name == "WGS_1984" || name == "World Geodetic System 1984 ensemble") {
+ nameSet = true;
properties.set(IdentifiedObject::NAME_KEY,
GeodeticReferenceFrame::EPSG_6326->nameStr());
} else if (name == "European Terrestrial Reference System 1989 ensemble") {
+ nameSet = true;
properties.set(IdentifiedObject::NAME_KEY,
"European Terrestrial Reference System 1989");
- } else if (starts_with(name, "D_")) {
+ }
+
+ // If we got hints this might be a ESRI WKT, then check in the DB to
+ // confirm
+ std::string officialName;
+ std::string authNameFromAlias;
+ std::string codeFromAlias;
+ if (!nameSet && maybeEsriStyle_ && dbContext_ &&
+ !(starts_with(name, "D_") || esriStyle_)) {
+ std::string outTableName;
+ auto authFactory =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext_), std::string());
+ officialName = authFactory->getOfficialNameFromAlias(
+ name, "geodetic_datum", "ESRI", false, outTableName,
+ authNameFromAlias, codeFromAlias);
+ if (!officialName.empty()) {
+ maybeEsriStyle_ = false;
+ esriStyle_ = true;
+ }
+ }
+
+ if (!nameSet && (starts_with(name, "D_") || esriStyle_)) {
esriStyle_ = true;
const char *tableNameForAlias = nullptr;
- std::string authNameFromAlias;
- std::string codeFromAlias;
if (name == "D_WGS_1984") {
name = "World Geodetic System 1984";
authNameFromAlias = Identifier::EPSG;
@@ -2228,18 +2251,23 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
bool setNameAndId = true;
if (dbContext_ && tableNameForAlias) {
- std::string outTableName;
- auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
- std::string());
- auto officialName = authFactory->getOfficialNameFromAlias(
- name, tableNameForAlias, "ESRI", false, outTableName,
- authNameFromAlias, codeFromAlias);
if (officialName.empty()) {
- // For the case of "D_GDA2020" where there is no D_GDA2020 ESRI
- // alias, so just try without the D_ prefix.
- const auto nameWithoutDPrefix = name.substr(2);
- if (identifyFromName(nameWithoutDPrefix)) {
- setNameAndId = false; // already done in identifyFromName()
+ std::string outTableName;
+ auto authFactory = AuthorityFactory::create(
+ NN_NO_CHECK(dbContext_), std::string());
+ officialName = authFactory->getOfficialNameFromAlias(
+ name, tableNameForAlias, "ESRI", false, outTableName,
+ authNameFromAlias, codeFromAlias);
+ }
+ if (officialName.empty()) {
+ if (starts_with(name, "D_")) {
+ // For the case of "D_GDA2020" where there is no D_GDA2020
+ // ESRI alias, so just try without the D_ prefix.
+ const auto nameWithoutDPrefix = name.substr(2);
+ if (identifyFromName(nameWithoutDPrefix)) {
+ setNameAndId =
+ false; // already done in identifyFromName()
+ }
}
} else {
if (primeMeridian->nameStr() !=
@@ -2266,7 +2294,7 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
properties.set(IdentifiedObject::IDENTIFIERS_KEY, identifiers);
}
}
- } else if (name.find('_') != std::string::npos) {
+ } else if (!nameSet && name.find('_') != std::string::npos) {
// Likely coming from WKT1
identifyFromName(name);
}
@@ -6988,6 +7016,10 @@ BaseObjectNNPtr createFromUserInput(const std::string &text, PJ_CONTEXT *ctx) {
* @throw ParsingException
*/
BaseObjectNNPtr WKTParser::createFromWKT(const std::string &wkt) {
+
+ const auto dialect = guessDialect(wkt);
+ d->maybeEsriStyle_ = (dialect == WKTGuessedDialect::WKT1_ESRI);
+
const auto build = [this, &wkt]() -> BaseObjectNNPtr {
size_t indexEnd;
WKTNodeNNPtr root = WKTNode::createFrom(wkt, 0, 0, indexEnd);
@@ -7047,7 +7079,6 @@ BaseObjectNNPtr WKTParser::createFromWKT(const std::string &wkt) {
auto obj = build();
- const auto dialect = guessDialect(wkt);
if (dialect == WKTGuessedDialect::WKT1_GDAL ||
dialect == WKTGuessedDialect::WKT1_ESRI) {
auto errorMsg = pj_wkt1_parse(wkt);
@@ -7090,7 +7121,10 @@ WKTParser::guessDialect(const std::string &wkt) noexcept {
for (const auto &pointerKeyword : wkt1_keywords) {
if (ci_starts_with(wkt, *pointerKeyword)) {
- if (ci_find(wkt, "GEOGCS[\"GCS_") != std::string::npos) {
+ if (ci_find(wkt, "GEOGCS[\"GCS_") != std::string::npos ||
+ (!ci_starts_with(wkt, WKTConstants::LOCAL_CS) &&
+ ci_find(wkt, "AXIS[") == std::string::npos &&
+ ci_find(wkt, "AUTHORITY[") == std::string::npos)) {
return WKTGuessedDialect::WKT1_ESRI;
}