aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-05-25 19:47:43 +0200
committerEven Rouault <even.rouault@spatialys.com>2020-05-25 19:47:51 +0200
commit172744361c83d2a40c11600a398a0e1668052031 (patch)
tree84a034e942372ada367eb832b48061ee6d11e11b /src
parentcfdd474dd8aef197297c488c6133f7484fe421fd (diff)
downloadPROJ-172744361c83d2a40c11600a398a0e1668052031.tar.gz
PROJ-172744361c83d2a40c11600a398a0e1668052031.zip
Fix identification of (one of the) ESRI WKT formulations of EPSG:3035
Fixes https://github.com/qgis/QGIS/issues/36111
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/crs.cpp9
-rw-r--r--src/iso19111/factory.cpp116
2 files changed, 83 insertions, 42 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 35e11d84..b0ec35b9 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -3927,15 +3927,16 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
} else if (!unsignificantName) {
for (int ipass = 0; ipass < 2; ipass++) {
const bool approximateMatch = ipass == 1;
- auto objects = authorityFactory->createObjectsFromName(
+ auto objects = authorityFactory->createObjectsFromNameEx(
thisName, {io::AuthorityFactory::ObjectType::PROJECTED_CRS},
approximateMatch);
- for (const auto &obj : objects) {
- auto crs = util::nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ for (const auto &pairObjName : objects) {
+ auto crs = util::nn_dynamic_pointer_cast<ProjectedCRS>(
+ pairObjName.first);
assert(crs);
auto crsNN = NN_NO_CHECK(crs);
const bool eqName = metadata::Identifier::isEquivalentName(
- thisName.c_str(), crs->nameStr().c_str());
+ thisName.c_str(), pairObjName.second.c_str());
foundEquivalentName |= eqName;
addCRS(crsNN, eqName);
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 8fa5a24d..de8e1362 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -56,6 +56,7 @@
#include <map>
#include <memory>
#include <sstream> // std::ostringstream
+#include <stdexcept>
#include <string>
#include "proj_constants.h"
@@ -5452,7 +5453,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias(
// ---------------------------------------------------------------------------
-/** \brief Return a list of objects by their name
+/** \brief Return a list of objects, identified by their name
*
* @param searchedName Searched name. Must be at least 2 character long.
* @param allowedObjectTypes List of object types into which to search. If
@@ -5468,7 +5469,39 @@ AuthorityFactory::createObjectsFromName(
const std::string &searchedName,
const std::vector<ObjectType> &allowedObjectTypes, bool approximateMatch,
size_t limitResultCount) const {
+ std::list<common::IdentifiedObjectNNPtr> res;
+ const auto resTmp(createObjectsFromNameEx(
+ searchedName, allowedObjectTypes, approximateMatch, limitResultCount));
+ for (const auto &pair : resTmp) {
+ res.emplace_back(pair.first);
+ }
+ return res;
+}
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+/** \brief Return a list of objects, identifier by their name, with the name
+ * on which the match occured.
+ *
+ * The name on which the match occured might be different from the object name,
+ * if the match has been done on an alias name of that object.
+ *
+ * @param searchedName Searched name. Must be at least 2 character long.
+ * @param allowedObjectTypes List of object types into which to search. If
+ * empty, all object types will be searched.
+ * @param approximateMatch Whether approximate name identification is allowed.
+ * @param limitResultCount Maximum number of results to return.
+ * Or 0 for unlimited.
+ * @return list of matched objects.
+ * @throw FactoryException
+ */
+std::list<AuthorityFactory::PairObjectName>
+AuthorityFactory::createObjectsFromNameEx(
+ const std::string &searchedName,
+ const std::vector<ObjectType> &allowedObjectTypes, bool approximateMatch,
+ size_t limitResultCount) const {
std::string searchedNameWithoutDeprecated(searchedName);
bool deprecated = false;
if (ends_with(searchedNameWithoutDeprecated, " (deprecated)")) {
@@ -5657,7 +5690,7 @@ AuthorityFactory::createObjectsFromName(
sql += toString(static_cast<int>(limitResultCount));
}
- std::list<common::IdentifiedObjectNNPtr> res;
+ std::list<PairObjectName> res;
std::set<std::pair<std::string, std::string>> setIdentified;
// Querying geodetic datum is a super hot path when importing from WKT1
@@ -5693,7 +5726,9 @@ AuthorityFactory::createObjectsFromName(
}
setIdentified.insert(key);
auto factory = d->createFactory(auth_name);
- res.emplace_back(factory->createGeodeticDatum(code));
+ const auto &name = row[3];
+ res.emplace_back(
+ PairObjectName(factory->createGeodeticDatum(code), name));
if (limitResultCount > 0 && res.size() == limitResultCount) {
break;
}
@@ -5724,7 +5759,8 @@ AuthorityFactory::createObjectsFromName(
}
setIdentified.insert(key);
auto factory = d->createFactory(auth_name);
- res.emplace_back(factory->createGeodeticDatum(code));
+ res.emplace_back(PairObjectName(
+ factory->createGeodeticDatum(code), name));
if (limitResultCount > 0 &&
res.size() == limitResultCount) {
break;
@@ -5773,43 +5809,45 @@ AuthorityFactory::createObjectsFromName(
break;
}
auto factory = d->createFactory(auth_name);
- if (table_name == "prime_meridian") {
- res.emplace_back(factory->createPrimeMeridian(code));
- } else if (table_name == "ellipsoid") {
- res.emplace_back(factory->createEllipsoid(code));
- } else if (table_name == "geodetic_datum") {
- res.emplace_back(factory->createGeodeticDatum(code));
- } else if (table_name == "vertical_datum") {
- res.emplace_back(factory->createVerticalDatum(code));
- } else if (table_name == "geodetic_crs") {
- res.emplace_back(factory->createGeodeticCRS(code));
- } else if (table_name == "projected_crs") {
- res.emplace_back(factory->createProjectedCRS(code));
- } else if (table_name == "vertical_crs") {
- res.emplace_back(factory->createVerticalCRS(code));
- } else if (table_name == "compound_crs") {
- res.emplace_back(factory->createCompoundCRS(code));
- } else if (table_name == "conversion") {
- res.emplace_back(factory->createConversion(code));
- } else if (table_name == "grid_transformation" ||
- table_name == "helmert_transformation" ||
- table_name == "other_transformation" ||
- table_name == "concatenated_operation") {
- res.emplace_back(
- factory->createCoordinateOperation(code, true));
- } else {
- assert(false);
- }
+ auto getObject = [&factory](
+ const std::string &l_table_name,
+ const std::string &l_code) -> common::IdentifiedObjectNNPtr {
+ if (l_table_name == "prime_meridian") {
+ return factory->createPrimeMeridian(l_code);
+ } else if (l_table_name == "ellipsoid") {
+ return factory->createEllipsoid(l_code);
+ } else if (l_table_name == "geodetic_datum") {
+ return factory->createGeodeticDatum(l_code);
+ } else if (l_table_name == "vertical_datum") {
+ return factory->createVerticalDatum(l_code);
+ } else if (l_table_name == "geodetic_crs") {
+ return factory->createGeodeticCRS(l_code);
+ } else if (l_table_name == "projected_crs") {
+ return factory->createProjectedCRS(l_code);
+ } else if (l_table_name == "vertical_crs") {
+ return factory->createVerticalCRS(l_code);
+ } else if (l_table_name == "compound_crs") {
+ return factory->createCompoundCRS(l_code);
+ } else if (l_table_name == "conversion") {
+ return factory->createConversion(l_code);
+ } else if (l_table_name == "grid_transformation" ||
+ l_table_name == "helmert_transformation" ||
+ l_table_name == "other_transformation" ||
+ l_table_name == "concatenated_operation") {
+ return factory->createCoordinateOperation(l_code, true);
+ }
+ throw std::runtime_error("Unsupported table_name");
+ };
+ res.emplace_back(PairObjectName(getObject(table_name, code), name));
if (limitResultCount > 0 && res.size() == limitResultCount) {
break;
}
}
}
- auto sortLambda = [](const common::IdentifiedObjectNNPtr &a,
- const common::IdentifiedObjectNNPtr &b) {
- const auto &aName = a->nameStr();
- const auto &bName = b->nameStr();
+ auto sortLambda = [](const PairObjectName &a, const PairObjectName &b) {
+ const auto &aName = a.first->nameStr();
+ const auto &bName = b.first->nameStr();
if (aName.size() < bName.size()) {
return true;
}
@@ -5817,8 +5855,8 @@ AuthorityFactory::createObjectsFromName(
return false;
}
- const auto &aIds = a->identifiers();
- const auto &bIds = b->identifiers();
+ const auto &aIds = a.first->identifiers();
+ const auto &bIds = b.first->identifiers();
if (aIds.size() < bIds.size()) {
return true;
}
@@ -5845,13 +5883,15 @@ AuthorityFactory::createObjectsFromName(
return false;
}
}
- return strcmp(typeid(a.get()).name(), typeid(b.get()).name()) < 0;
+ return strcmp(typeid(a.first.get()).name(),
+ typeid(b.first.get()).name()) < 0;
};
res.sort(sortLambda);
return res;
}
+//! @endcond
// ---------------------------------------------------------------------------