aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/factory.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-06 23:34:09 +0100
committerEven Rouault <even.rouault@spatialys.com>2020-01-07 12:17:13 +0100
commit699b92250a90e5c333572245cf3d09c9e00e50e5 (patch)
tree613a0e59b73861a16fc21c7a41b70245e297452c /src/iso19111/factory.cpp
parent529eb50f5d7e817dd27674984050a9bf1a6dce55 (diff)
downloadPROJ-699b92250a90e5c333572245cf3d09c9e00e50e5.tar.gz
PROJ-699b92250a90e5c333572245cf3d09c9e00e50e5.zip
createObjectsFromName(): make it look up in the alias_name table too (fixes #1823)
Diffstat (limited to 'src/iso19111/factory.cpp')
-rw-r--r--src/iso19111/factory.cpp252
1 files changed, 152 insertions, 100 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 0bd44308..33fce593 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -5248,13 +5248,12 @@ static void addToListString(std::string &out, const char *in) {
out += in;
}
-static void addToListStringWithOR(std::string &out, const char *in) {
+static void addToListStringWithOR(std::string &out, const std::string &in) {
if (!out.empty()) {
out += " OR ";
}
out += in;
}
-
//! @endcond
// ---------------------------------------------------------------------------
@@ -5291,6 +5290,7 @@ AuthorityFactory::createObjectsFromName(
}
std::string sql(
+ "SELECT table_name, auth_name, code, name, deprecated FROM ("
"SELECT table_name, auth_name, code, name, deprecated FROM object_view "
"WHERE ");
if (deprecated) {
@@ -5306,108 +5306,141 @@ AuthorityFactory::createObjectsFromName(
params.emplace_back(d->authority());
}
- if (allowedObjectTypes.empty()) {
- sql += "table_name IN ("
- "'prime_meridian','ellipsoid','geodetic_datum',"
- "'vertical_datum','geodetic_crs','projected_crs',"
- "'vertical_crs','compound_crs','conversion',"
- "'helmert_transformation','grid_transformation',"
- "'other_transformation','concatenated_operation'"
- ")";
- } else {
- std::string tableNameList;
- std::string otherConditions;
- for (const auto type : allowedObjectTypes) {
- switch (type) {
- case ObjectType::PRIME_MERIDIAN:
- addToListString(tableNameList, "'prime_meridian'");
- break;
- case ObjectType::ELLIPSOID:
- addToListString(tableNameList, "'ellipsoid'");
- break;
- case ObjectType::DATUM:
- addToListString(tableNameList,
- "'geodetic_datum','vertical_datum'");
- break;
- case ObjectType::GEODETIC_REFERENCE_FRAME:
- addToListString(tableNameList, "'geodetic_datum'");
- break;
- case ObjectType::VERTICAL_REFERENCE_FRAME:
- addToListString(tableNameList, "'vertical_datum'");
- break;
- case ObjectType::CRS:
- addToListString(tableNameList, "'geodetic_crs','projected_crs',"
- "'vertical_crs','compound_crs'");
- break;
- case ObjectType::GEODETIC_CRS:
- addToListString(tableNameList, "'geodetic_crs'");
- break;
- case ObjectType::GEOCENTRIC_CRS:
- addToListStringWithOR(otherConditions,
- "(table_name = " GEOCENTRIC_SINGLE_QUOTED
- " AND "
- "type = " GEOCENTRIC_SINGLE_QUOTED ")");
- break;
- case ObjectType::GEOGRAPHIC_CRS:
- addToListStringWithOR(otherConditions,
- "(table_name = 'geodetic_crs' AND "
- "type IN (" GEOG_2D_SINGLE_QUOTED
- "," GEOG_3D_SINGLE_QUOTED "))");
- break;
- case ObjectType::GEOGRAPHIC_2D_CRS:
- addToListStringWithOR(otherConditions,
- "(table_name = 'geodetic_crs' AND "
- "type = " GEOG_2D_SINGLE_QUOTED ")");
- break;
- case ObjectType::GEOGRAPHIC_3D_CRS:
- addToListStringWithOR(otherConditions,
- "(table_name = 'geodetic_crs' AND "
- "type = " GEOG_3D_SINGLE_QUOTED ")");
- break;
- case ObjectType::PROJECTED_CRS:
- addToListString(tableNameList, "'projected_crs'");
- break;
- case ObjectType::VERTICAL_CRS:
- addToListString(tableNameList, "'vertical_crs'");
- break;
- case ObjectType::COMPOUND_CRS:
- addToListString(tableNameList, "'compound_crs'");
- break;
- case ObjectType::COORDINATE_OPERATION:
- addToListString(tableNameList,
- "'conversion','helmert_transformation',"
- "'grid_transformation','other_transformation',"
- "'concatenated_operation'");
- break;
- case ObjectType::CONVERSION:
- addToListString(tableNameList, "'conversion'");
- break;
- case ObjectType::TRANSFORMATION:
- addToListString(tableNameList,
- "'helmert_transformation',"
- "'grid_transformation','other_transformation'");
- break;
- case ObjectType::CONCATENATED_OPERATION:
- addToListString(tableNameList, "'concatenated_operation'");
- break;
+ const auto getTableNameConstraint = [&allowedObjectTypes](
+ const std::string &colName) {
+ if (allowedObjectTypes.empty()) {
+ return colName + " IN ("
+ "'prime_meridian','ellipsoid','geodetic_datum',"
+ "'vertical_datum','geodetic_crs','projected_crs',"
+ "'vertical_crs','compound_crs','conversion',"
+ "'helmert_transformation','grid_transformation',"
+ "'other_transformation','concatenated_operation'"
+ ")";
+ } else {
+ std::string tableNameList;
+ std::string otherConditions;
+ for (const auto type : allowedObjectTypes) {
+ switch (type) {
+ case ObjectType::PRIME_MERIDIAN:
+ addToListString(tableNameList, "'prime_meridian'");
+ break;
+ case ObjectType::ELLIPSOID:
+ addToListString(tableNameList, "'ellipsoid'");
+ break;
+ case ObjectType::DATUM:
+ addToListString(tableNameList,
+ "'geodetic_datum','vertical_datum'");
+ break;
+ case ObjectType::GEODETIC_REFERENCE_FRAME:
+ addToListString(tableNameList, "'geodetic_datum'");
+ break;
+ case ObjectType::VERTICAL_REFERENCE_FRAME:
+ addToListString(tableNameList, "'vertical_datum'");
+ break;
+ case ObjectType::CRS:
+ addToListString(tableNameList,
+ "'geodetic_crs','projected_crs',"
+ "'vertical_crs','compound_crs'");
+ break;
+ case ObjectType::GEODETIC_CRS:
+ addToListString(tableNameList, "'geodetic_crs'");
+ break;
+ case ObjectType::GEOCENTRIC_CRS:
+ addToListStringWithOR(
+ otherConditions,
+ "(" + colName + " = " GEOCENTRIC_SINGLE_QUOTED " AND "
+ "type = " GEOCENTRIC_SINGLE_QUOTED ")");
+ break;
+ case ObjectType::GEOGRAPHIC_CRS:
+ addToListStringWithOR(otherConditions,
+ "(" + colName +
+ " = 'geodetic_crs' AND "
+ "type IN (" GEOG_2D_SINGLE_QUOTED
+ "," GEOG_3D_SINGLE_QUOTED "))");
+ break;
+ case ObjectType::GEOGRAPHIC_2D_CRS:
+ addToListStringWithOR(
+ otherConditions,
+ "(" + colName + " = 'geodetic_crs' AND "
+ "type = " GEOG_2D_SINGLE_QUOTED ")");
+ break;
+ case ObjectType::GEOGRAPHIC_3D_CRS:
+ addToListStringWithOR(
+ otherConditions,
+ "(" + colName + " = 'geodetic_crs' AND "
+ "type = " GEOG_3D_SINGLE_QUOTED ")");
+ break;
+ case ObjectType::PROJECTED_CRS:
+ addToListString(tableNameList, "'projected_crs'");
+ break;
+ case ObjectType::VERTICAL_CRS:
+ addToListString(tableNameList, "'vertical_crs'");
+ break;
+ case ObjectType::COMPOUND_CRS:
+ addToListString(tableNameList, "'compound_crs'");
+ break;
+ case ObjectType::COORDINATE_OPERATION:
+ addToListString(
+ tableNameList,
+ "'conversion','helmert_transformation',"
+ "'grid_transformation','other_transformation',"
+ "'concatenated_operation'");
+ break;
+ case ObjectType::CONVERSION:
+ addToListString(tableNameList, "'conversion'");
+ break;
+ case ObjectType::TRANSFORMATION:
+ addToListString(
+ tableNameList,
+ "'helmert_transformation',"
+ "'grid_transformation','other_transformation'");
+ break;
+ case ObjectType::CONCATENATED_OPERATION:
+ addToListString(tableNameList, "'concatenated_operation'");
+ break;
+ }
}
- }
- if (!tableNameList.empty()) {
- sql += "((table_name IN (";
- sql += tableNameList;
- sql += "))";
- if (!otherConditions.empty()) {
- sql += " OR ";
- sql += otherConditions;
+ std::string l_sql;
+ if (!tableNameList.empty()) {
+ l_sql = "((" + colName + " IN (";
+ l_sql += tableNameList;
+ l_sql += "))";
+ if (!otherConditions.empty()) {
+ l_sql += " OR ";
+ l_sql += otherConditions;
+ }
+ l_sql += ')';
+ } else if (!otherConditions.empty()) {
+ l_sql = "(";
+ l_sql += otherConditions;
+ l_sql += ')';
}
- sql += ')';
- } else if (!otherConditions.empty()) {
- sql += "(";
- sql += otherConditions;
- sql += ')';
+ return l_sql;
}
+ };
+
+ sql += getTableNameConstraint("table_name");
+
+ sql += " UNION SELECT ov.table_name AS table_name, "
+ "ov.auth_name AS auth_name, "
+ "ov.code AS code, a.alt_name AS name, "
+ "ov.deprecated AS deprecated FROM object_view ov "
+ "JOIN alias_name a ON ov.table_name = a.table_name AND "
+ "ov.auth_name = a.auth_name AND ov.code = a.code WHERE ";
+ if (deprecated) {
+ sql += "ov.deprecated = 1 AND ";
+ }
+ if (!approximateMatch) {
+ sql += "a.alt_name LIKE ? AND ";
+ params.push_back(searchedNameWithoutDeprecated);
+ }
+ if (d->hasAuthorityRestriction()) {
+ sql += "ov.auth_name = ? AND ";
+ params.emplace_back(d->authority());
}
- sql += " ORDER BY deprecated, length(name), name";
+ sql += getTableNameConstraint("ov.table_name");
+
+ sql += ") ORDER BY deprecated, length(name), name";
if (limitResultCount > 0 &&
limitResultCount <
static_cast<size_t>(std::numeric_limits<int>::max()) &&
@@ -5417,6 +5450,7 @@ AuthorityFactory::createObjectsFromName(
}
std::list<common::IdentifiedObjectNNPtr> res;
+ std::set<std::pair<std::string, std::string>> setIdentified;
// Querying geodetic datum is a super hot path when importing from WKT1
// so cache results.
@@ -5444,6 +5478,12 @@ AuthorityFactory::createObjectsFromName(
for (const auto &row : listOfRow) {
const auto &auth_name = row[1];
const auto &code = row[2];
+ const auto key =
+ std::pair<std::string, std::string>(auth_name, code);
+ if (setIdentified.find(key) != setIdentified.end()) {
+ continue;
+ }
+ setIdentified.insert(key);
auto factory = d->createFactory(auth_name);
res.emplace_back(factory->createGeodeticDatum(code));
if (limitResultCount > 0 && res.size() == limitResultCount) {
@@ -5469,6 +5509,12 @@ AuthorityFactory::createObjectsFromName(
const auto &auth_name = row[1];
const auto &code = row[2];
+ const auto key =
+ std::pair<std::string, std::string>(auth_name, code);
+ if (setIdentified.find(key) != setIdentified.end()) {
+ continue;
+ }
+ setIdentified.insert(key);
auto factory = d->createFactory(auth_name);
res.emplace_back(factory->createGeodeticDatum(code));
if (limitResultCount > 0 &&
@@ -5504,6 +5550,12 @@ AuthorityFactory::createObjectsFromName(
const auto &table_name = row[0];
const auto &auth_name = row[1];
const auto &code = row[2];
+ const auto key =
+ std::pair<std::string, std::string>(auth_name, code);
+ if (setIdentified.find(key) != setIdentified.end()) {
+ continue;
+ }
+ setIdentified.insert(key);
const auto &deprecatedStr = row[4];
if (isFirst) {
firstIsDeprecated = deprecatedStr == "1";