Skip to content

Commit

Permalink
Merge pull request #1827 from rouault/improve_createObjectsFromName
Browse files Browse the repository at this point in the history
Improvements regarding name aliases (refs #1823)
  • Loading branch information
kbevers authored Jan 8, 2020
2 parents 6cd3a80 + 6426bcb commit 2d76bcf
Show file tree
Hide file tree
Showing 13 changed files with 7,155 additions and 139 deletions.
6,808 changes: 6,808 additions & 0 deletions data/sql/alias_name.sql

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions data/sql/customizations.sql
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,16 @@ INSERT INTO "geoid_model" SELECT 'GEOID12A', auth_name, code FROM grid_transform
INSERT INTO "geoid_model" SELECT 'GEOID12B', auth_name, code FROM grid_transformation WHERE auth_name = 'EPSG' AND grid_name LIKE 'g2012b%' AND deprecated = 0;

INSERT INTO "geoid_model" SELECT 'GEOID18', auth_name, code FROM grid_transformation WHERE auth_name = 'EPSG' AND grid_name LIKE 'g2018%' AND deprecated = 0;

---- PROJ historic +datum aliases -----

INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6326','WGS84','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6121','GGRS87','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6269','NAD83','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6267','NAD27','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6314','potsdam','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6223','carthage','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6312','hermannskogel','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6299','ire65','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6272','nzgd49','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6277','OSGB36','PROJ');
4 changes: 2 additions & 2 deletions docs/source/apps/projinfo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Synopsis
********

| **projinfo**
| [-o formats] [-k crs|operation|ellipsoid] [--summary] [-q]
| [-o formats] [-k crs|operation|datum|ellipsoid] [--summary] [-q]
| [[--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]]
| [--spatial-test contains|intersects]
| [--crs-extent-use none|both|intersection|smallest]
Expand Down Expand Up @@ -80,7 +80,7 @@ The following control parameters can appear in any order:
.. note:: Before PROJ 6.3.0, WKT1:GDAL was implicitly calling --boundcrs-to-wgs84.
This is no longer the case.

.. option:: -k crs|operation|ellipsoid
.. option:: -k crs|operation|datum|ellipsoid

When used to query a single object with a AUTHORITY:CODE, determines the (k)ind of the object
in case there are CRS, coordinate operations or ellipsoids with the same CODE.
Expand Down
27 changes: 27 additions & 0 deletions scripts/build_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,33 @@ def fill_alias(proj_db_cursor):
else:
print('Cannot find datum %s in geodetic_datum or vertical_datum' % (code))

proj_db_cursor.execute("SELECT object_code, alias FROM epsg.epsg_alias WHERE object_table_name = 'epsg_coordinatereferencesystem'")
for row in proj_db_cursor.fetchall():
code, alt_name = row
if int(code) > 60000000:
continue
proj_db_cursor.execute('SELECT 1 FROM geodetic_crs WHERE code = ?', (code,))
if proj_db_cursor.fetchone() is not None:
proj_db_cursor.execute("INSERT INTO alias_name VALUES ('geodetic_crs','EPSG',?,?,'EPSG')", (code, alt_name))
continue

proj_db_cursor.execute('SELECT 1 FROM projected_crs WHERE code = ?', (code,))
if proj_db_cursor.fetchone() is not None:
proj_db_cursor.execute("INSERT INTO alias_name VALUES ('projected_crs','EPSG',?,?,'EPSG')", (code, alt_name))
continue

proj_db_cursor.execute('SELECT 1 FROM vertical_crs WHERE code = ?', (code,))
if proj_db_cursor.fetchone() is not None:
proj_db_cursor.execute("INSERT INTO alias_name VALUES ('vertical_crs','EPSG',?,?,'EPSG')", (code, alt_name))
continue

proj_db_cursor.execute('SELECT 1 FROM compound_crs WHERE code = ?', (code,))
if proj_db_cursor.fetchone() is not None:
proj_db_cursor.execute("INSERT INTO alias_name VALUES ('compound_crs','EPSG',?,?,'EPSG')", (code, alt_name))
continue

print('Cannot find CRS %s in geodetic_crs, projected_crs, vertical_crs or compound_crs' % (code))


def find_table(proj_db_cursor, code):
for table_name in ('helmert_transformation', 'grid_transformation', 'concatenated_operation', 'geodetic_crs', 'projected_crs', 'vertical_crs', 'compound_crs'):
Expand Down
60 changes: 59 additions & 1 deletion src/apps/projinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ struct OutputOptions {

static void usage() {
std::cerr
<< "usage: projinfo [-o formats] [-k crs|operation|ellipsoid] "
<< "usage: projinfo [-o formats] [-k crs|operation|datum|ellipsoid] "
"[--summary] [-q]"
<< std::endl
<< " ([--area name_or_code] | "
Expand Down Expand Up @@ -184,6 +184,9 @@ static BaseObjectNNPtr buildObject(
} else if (kind == "ellipsoid" && tokens.size() == 2) {
auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + tokens[1];
obj = createFromUserInput(urn, dbContext).as_nullable();
} else if (kind == "datum" && tokens.size() == 2) {
auto urn = "urn:ogc:def:datum:" + tokens[0] + "::" + tokens[1];
obj = createFromUserInput(urn, dbContext).as_nullable();
} else {
// Convenience to be able to use C escaped strings...
if (l_user_string.size() > 2 && l_user_string[0] == '"' &&
Expand All @@ -205,6 +208,59 @@ static BaseObjectNNPtr buildObject(
}
}
}
} else if (dbContext && !kind.empty() && kind != "crs" &&
l_user_string.find(':') == std::string::npos) {
std::vector<AuthorityFactory::ObjectType> allowedTypes;
if (kind == "operation")
allowedTypes.push_back(
AuthorityFactory::ObjectType::COORDINATE_OPERATION);
else if (kind == "ellipsoid")
allowedTypes.push_back(
AuthorityFactory::ObjectType::ELLIPSOID);
else if (kind == "datum")
allowedTypes.push_back(AuthorityFactory::ObjectType::DATUM);
constexpr size_t limitResultCount = 10;
auto factory = AuthorityFactory::create(NN_NO_CHECK(dbContext),
std::string());
for (int pass = 0; pass <= 1; ++pass) {
const bool approximateMatch = (pass == 1);
auto res = factory->createObjectsFromName(
l_user_string, allowedTypes, approximateMatch,
limitResultCount);
if (res.size() == 1) {
obj = res.front().as_nullable();
} else {
for (const auto &l_obj : res) {
if (Identifier::isEquivalentName(
l_obj->nameStr().c_str(),
l_user_string.c_str())) {
obj = l_obj.as_nullable();
break;
}
}
if (obj) {
break;
}
}
if (res.size() > 1) {
std::string msg("several objects matching this name: ");
bool first = true;
for (const auto &l_obj : res) {
if (msg.size() > 200) {
msg += ", ...";
break;
}
if (!first) {
msg += ", ";
}
first = false;
msg += l_obj->nameStr();
}
std::cerr << context << ": " << msg << std::endl;
std::exit(1);
}
}

} else {
obj =
createFromUserInput(l_user_string, dbContext).as_nullable();
Expand Down Expand Up @@ -861,6 +917,8 @@ int main(int argc, char **argv) {
objectKind = "operation";
} else if (ci_equal(kind, "ellipsoid")) {
objectKind = "ellipsoid";
} else if (ci_equal(kind, "datum")) {
objectKind = "datum";
} else {
std::cerr << "Unrecognized value for option -k: " << kind
<< std::endl;
Expand Down
23 changes: 13 additions & 10 deletions src/iso19111/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2760,16 +2760,19 @@ static GeodeticReferenceFrameNNPtr createGeodeticReferenceFrame(
if (metadata::Identifier::isEquivalentName(
datumName.c_str(), refDatum->nameStr().c_str())) {
datumName = refDatum->nameStr();
}
} else {
std::string outTableName;
std::string authNameFromAlias;
std::string codeFromAlias;
auto officialName = authFactory->getOfficialNameFromAlias(
datumName, "geodetic_datum", std::string(), true,
outTableName, authNameFromAlias, codeFromAlias);
if (!officialName.empty()) {
datumName = officialName;
} else if (refDatum->identifiers().size() == 1) {
const auto &id = refDatum->identifiers()[0];
const auto aliases =
authFactory->databaseContext()->getAliases(
*id->codeSpace(), id->code(), refDatum->nameStr(),
"geodetic_datum", std::string());
for (const auto &alias : aliases) {
if (metadata::Identifier::isEquivalentName(
datumName.c_str(), alias.c_str())) {
datumName = refDatum->nameStr();
break;
}
}
}
}
}
Expand Down
Loading

0 comments on commit 2d76bcf

Please sign in to comment.