aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/factory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/factory.cpp')
-rw-r--r--src/iso19111/factory.cpp442
1 files changed, 262 insertions, 180 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index a011f397..f98e5cc8 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -1064,6 +1064,28 @@ std::string DatabaseContext::getOldProjGridName(const std::string &gridName) {
// ---------------------------------------------------------------------------
+// FIXME: as we don't support datum ensemble yet, remove it from name
+static std::string addEnsembleSuffix(const std::string &name) {
+ if (name == "World Geodetic System 1984") {
+ return "World Geodetic System 1984 ensemble";
+ } else if (name == "European Terrestrial Reference System 1989") {
+ return "European Terrestrial Reference System 1989 ensemble";
+ }
+ return name;
+}
+
+// FIXME: as we don't support datum ensemble yet, add it from name
+static std::string removeEnsembleSuffix(const std::string &name) {
+ if (name == "World Geodetic System 1984 ensemble") {
+ return "World Geodetic System 1984";
+ } else if (name == "European Terrestrial Reference System 1989 ensemble") {
+ return "European Terrestrial Reference System 1989";
+ }
+ return name;
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Gets the alias name from an official name.
*
* @param officialName Official name. Mandatory
@@ -1082,7 +1104,7 @@ DatabaseContext::getAliasFromOfficialName(const std::string &officialName,
if (tableName == "geodetic_crs") {
sql += " AND type = " GEOG_2D_SINGLE_QUOTED;
}
- auto res = d->run(sql, {officialName});
+ auto res = d->run(sql, {addEnsembleSuffix(officialName)});
if (res.empty()) {
return std::string();
}
@@ -1129,7 +1151,7 @@ std::list<std::string> DatabaseContext::getAliases(
if (tableName == "geodetic_crs") {
sql += " AND type = " GEOG_2D_SINGLE_QUOTED;
}
- auto resSql = d->run(sql, {officialName});
+ auto resSql = d->run(sql, {addEnsembleSuffix(officialName)});
if (resSql.empty()) {
d->cacheAliasNames_.insert(key, res);
return res;
@@ -1312,21 +1334,19 @@ struct AuthorityFactory::Private {
UnitOfMeasure createUnitOfMeasure(const std::string &auth_name,
const std::string &code);
- util::PropertyMap createProperties(const std::string &code,
- const std::string &name, bool deprecated,
- const metadata::ExtentPtr &extent);
+ util::PropertyMap
+ createProperties(const std::string &code, const std::string &name,
+ bool deprecated,
+ const std::vector<ObjectDomainNNPtr> &usages);
- util::PropertyMap createProperties(const std::string &code,
- const std::string &name, bool deprecated,
- const std::string &area_of_use_auth_name,
- const std::string &area_of_use_code);
+ util::PropertyMap
+ createPropertiesSearchUsages(const std::string &table_name,
+ const std::string &code,
+ const std::string &name, bool deprecated);
- util::PropertyMap createProperties(const std::string &code,
- const std::string &name, bool deprecated,
- const std::string &remarks,
- const std::string &scope,
- const std::string &area_of_use_auth_name,
- const std::string &area_of_use_code);
+ util::PropertyMap createPropertiesSearchUsages(
+ const std::string &table_name, const std::string &code,
+ const std::string &name, bool deprecated, const std::string &remarks);
SQLResultSet run(const std::string &sql,
const ListOfParams &parameters = ListOfParams());
@@ -1385,7 +1405,7 @@ AuthorityFactory::Private::createUnitOfMeasure(const std::string &auth_name,
util::PropertyMap AuthorityFactory::Private::createProperties(
const std::string &code, const std::string &name, bool deprecated,
- const metadata::ExtentPtr &extent) {
+ const std::vector<ObjectDomainNNPtr> &usages) {
auto props = util::PropertyMap()
.set(metadata::Identifier::CODESPACE_KEY, authority())
.set(metadata::Identifier::CODE_KEY, code)
@@ -1393,45 +1413,93 @@ util::PropertyMap AuthorityFactory::Private::createProperties(
if (deprecated) {
props.set(common::IdentifiedObject::DEPRECATED_KEY, true);
}
- if (extent) {
- props.set(
- common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
- NN_NO_CHECK(std::static_pointer_cast<util::BaseObject>(extent)));
+ if (!usages.empty()) {
+
+ auto array(util::ArrayOfBaseObject::create());
+ for (const auto &usage : usages) {
+ array->add(usage);
+ }
+ props.set(common::ObjectUsage::OBJECT_DOMAIN_KEY,
+ util::nn_static_pointer_cast<util::BaseObject>(array));
}
return props;
}
// ---------------------------------------------------------------------------
-util::PropertyMap AuthorityFactory::Private::createProperties(
- const std::string &code, const std::string &name, bool deprecated,
- const std::string &area_of_use_auth_name,
- const std::string &area_of_use_code) {
- return createProperties(code, name, deprecated,
- area_of_use_auth_name.empty()
- ? nullptr
- : createFactory(area_of_use_auth_name)
- ->createExtent(area_of_use_code)
- .as_nullable());
+util::PropertyMap AuthorityFactory::Private::createPropertiesSearchUsages(
+ const std::string &table_name, const std::string &code,
+ const std::string &name, bool deprecated) {
+
+ const std::string sql(
+ "SELECT extent.name, extent.description, extent.south_lat, "
+ "extent.north_lat, extent.west_lon, extent.east_lon, "
+ "scope.scope, "
+ "(CASE WHEN scope.scope LIKE '%large scale%' THEN 0 ELSE 1 END) "
+ "AS score "
+ "FROM usage "
+ "JOIN extent ON usage.extent_auth_name = extent.auth_name AND "
+ "usage.extent_code = extent.code "
+ "JOIN scope ON usage.scope_auth_name = scope.auth_name AND "
+ "usage.scope_code = scope.code "
+ "WHERE object_table_name = ? AND object_auth_name = ? AND "
+ "object_code = ? "
+ "ORDER BY score, usage.auth_name, usage.code");
+ auto res = run(sql, {table_name, authority(), code});
+ std::vector<ObjectDomainNNPtr> usages;
+ for (const auto &row : res) {
+ try {
+ size_t idx = 0;
+ const auto &extent_name = row[idx++];
+ idx++; /*const auto &extent_description = row[idx++];*/
+ const auto &south_lat_str = row[idx++];
+ const auto &north_lat_str = row[idx++];
+ const auto &west_lon_str = row[idx++];
+ const auto &east_lon_str = row[idx++];
+ const auto &scope = row[idx];
+
+ util::optional<std::string> scopeOpt;
+ if (!scope.empty()) {
+ scopeOpt = scope;
+ }
+
+ metadata::ExtentPtr extent;
+ if (south_lat_str.empty()) {
+ extent =
+ metadata::Extent::create(
+ util::optional<std::string>(extent_name), {}, {}, {})
+ .as_nullable();
+ } else {
+ double south_lat = c_locale_stod(south_lat_str);
+ double north_lat = c_locale_stod(north_lat_str);
+ double west_lon = c_locale_stod(west_lon_str);
+ double east_lon = c_locale_stod(east_lon_str);
+ auto bbox = metadata::GeographicBoundingBox::create(
+ west_lon, south_lat, east_lon, north_lat);
+ extent = metadata::Extent::create(
+ util::optional<std::string>(extent_name),
+ std::vector<metadata::GeographicExtentNNPtr>{bbox},
+ std::vector<metadata::VerticalExtentNNPtr>(),
+ std::vector<metadata::TemporalExtentNNPtr>())
+ .as_nullable();
+ }
+
+ usages.emplace_back(ObjectDomain::create(scopeOpt, extent));
+ } catch (const std::exception &) {
+ }
+ }
+ return createProperties(code, name, deprecated, std::move(usages));
}
// ---------------------------------------------------------------------------
-util::PropertyMap AuthorityFactory::Private::createProperties(
- const std::string &code, const std::string &name, bool deprecated,
- const std::string &remarks, const std::string &scope,
- const std::string &area_of_use_auth_name,
- const std::string &area_of_use_code) {
- auto props = createProperties(code, name, deprecated,
- area_of_use_auth_name.empty()
- ? nullptr
- : createFactory(area_of_use_auth_name)
- ->createExtent(area_of_use_code)
- .as_nullable());
+util::PropertyMap AuthorityFactory::Private::createPropertiesSearchUsages(
+ const std::string &table_name, const std::string &code,
+ const std::string &name, bool deprecated, const std::string &remarks) {
+ auto props =
+ createPropertiesSearchUsages(table_name, code, name, deprecated);
if (!remarks.empty())
props.set(common::IdentifiedObject::REMARKS_KEY, remarks);
- if (!scope.empty())
- props.set(common::ObjectUsage::SCOPE_KEY, scope);
return props;
}
@@ -1554,7 +1622,7 @@ AuthorityFactory::createObject(const std::string &code) const {
throw FactoryException(msg);
}
const auto &table_name = res.front()[0];
- if (table_name == "area") {
+ if (table_name == "extent") {
return util::nn_static_pointer_cast<util::BaseObject>(
createExtent(code));
}
@@ -1639,10 +1707,10 @@ AuthorityFactory::createExtent(const std::string &code) const {
}
}
auto sql = "SELECT name, south_lat, north_lat, west_lon, east_lon, "
- "deprecated FROM area WHERE auth_name = ? AND code = ?";
+ "deprecated FROM extent WHERE auth_name = ? AND code = ?";
auto res = d->runWithCodeParam(sql, code);
if (res.empty()) {
- throw NoSuchAuthorityCodeException("area not found", d->authority(),
+ throw NoSuchAuthorityCodeException("extent not found", d->authority(),
code);
}
try {
@@ -1670,7 +1738,7 @@ AuthorityFactory::createExtent(const std::string &code) const {
return extent;
} catch (const std::exception &ex) {
- throw buildFactoryException("area", code, ex);
+ throw buildFactoryException("extent", code, ex);
}
}
@@ -1816,7 +1884,7 @@ AuthorityFactory::createPrimeMeridian(const std::string &code) const {
normalizeMeasure(uom_code, longitude, normalized_uom_code);
auto uom = d->createUnitOfMeasure(uom_auth_name, normalized_uom_code);
- auto props = d->createProperties(code, name, deprecated, nullptr);
+ auto props = d->createProperties(code, name, deprecated, {});
auto pm = datum::PrimeMeridian::create(
props, common::Angle(normalized_value, uom));
d->context()->d->cache(cacheKey, pm);
@@ -1897,7 +1965,7 @@ AuthorityFactory::createEllipsoid(const std::string &code) const {
const auto &body = row[6];
const bool deprecated = row[7] == "1";
auto uom = d->createUnitOfMeasure(uom_auth_name, uom_code);
- auto props = d->createProperties(code, name, deprecated, nullptr);
+ auto props = d->createProperties(code, name, deprecated, {});
if (!inv_flattening_str.empty()) {
auto ellps = datum::Ellipsoid::createFlattenedSphere(
props, common::Length(semi_major_axis, uom),
@@ -1940,13 +2008,13 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const {
return NN_NO_CHECK(datum);
}
}
- auto res = d->runWithCodeParam(
- "SELECT name, ellipsoid_auth_name, ellipsoid_code, "
- "prime_meridian_auth_name, prime_meridian_code, area_of_use_auth_name, "
- "area_of_use_code, publication_date, deprecated FROM geodetic_datum "
- "WHERE "
- "auth_name = ? AND code = ?",
- code);
+ auto res =
+ d->runWithCodeParam("SELECT name, ellipsoid_auth_name, ellipsoid_code, "
+ "prime_meridian_auth_name, prime_meridian_code, "
+ "publication_date, deprecated FROM geodetic_datum "
+ "WHERE "
+ "auth_name = ? AND code = ?",
+ code);
if (res.empty()) {
throw NoSuchAuthorityCodeException("geodetic datum not found",
d->authority(), code);
@@ -1958,16 +2026,14 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const {
const auto &ellipsoid_code = row[2];
const auto &prime_meridian_auth_name = row[3];
const auto &prime_meridian_code = row[4];
- const auto &area_of_use_auth_name = row[5];
- const auto &area_of_use_code = row[6];
- const auto &publication_date = row[7];
- const bool deprecated = row[8] == "1";
+ const auto &publication_date = row[5];
+ const bool deprecated = row[6] == "1";
auto ellipsoid = d->createFactory(ellipsoid_auth_name)
->createEllipsoid(ellipsoid_code);
auto pm = d->createFactory(prime_meridian_auth_name)
->createPrimeMeridian(prime_meridian_code);
- auto props = d->createProperties(
- code, name, deprecated, area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages(
+ "geodetic_datum", code, removeEnsembleSuffix(name), deprecated);
auto anchor = util::optional<std::string>();
if (!publication_date.empty()) {
props.set("PUBLICATION_DATE", publication_date);
@@ -1993,10 +2059,10 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const {
datum::VerticalReferenceFrameNNPtr
AuthorityFactory::createVerticalDatum(const std::string &code) const {
- auto res = d->runWithCodeParam(
- "SELECT name, area_of_use_auth_name, area_of_use_code, deprecated FROM "
- "vertical_datum WHERE auth_name = ? AND code = ?",
- code);
+ auto res =
+ d->runWithCodeParam("SELECT name, deprecated FROM "
+ "vertical_datum WHERE auth_name = ? AND code = ?",
+ code);
if (res.empty()) {
throw NoSuchAuthorityCodeException("vertical datum not found",
d->authority(), code);
@@ -2004,11 +2070,9 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const {
try {
const auto &row = res.front();
const auto &name = row[0];
- const auto &area_of_use_auth_name = row[1];
- const auto &area_of_use_code = row[2];
- const bool deprecated = row[3] == "1";
- auto props = d->createProperties(
- code, name, deprecated, area_of_use_auth_name, area_of_use_code);
+ const bool deprecated = row[1] == "1";
+ auto props = d->createPropertiesSearchUsages("vertical_datum", code,
+ name, deprecated);
auto anchor = util::optional<std::string>();
return datum::VerticalReferenceFrame::create(props, anchor);
} catch (const std::exception &ex) {
@@ -2105,7 +2169,13 @@ AuthorityFactory::createCoordinateSystem(const std::string &code) const {
const auto &orientation = row[2];
const auto &uom_auth_name = row[3];
const auto &uom_code = row[4];
- auto uom = d->createUnitOfMeasure(uom_auth_name, uom_code);
+ if (uom_auth_name.empty() && csType != "ordinal") {
+ throw FactoryException("no unit of measure for an axis is only "
+ "supported for ordinatal CS");
+ }
+ auto uom = uom_auth_name.empty()
+ ? common::UnitOfMeasure::NONE
+ : d->createUnitOfMeasure(uom_auth_name, uom_code);
auto props =
util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, name);
const cs::AxisDirection *direction =
@@ -2176,6 +2246,9 @@ AuthorityFactory::createCoordinateSystem(const std::string &code) const {
}
throw FactoryException("invalid number of axis for VerticalCS");
}
+ if (csType == "ordinal") {
+ return cacheAndRet(cs::OrdinalCS::create(props, axisList));
+ }
throw FactoryException("unhandled coordinate system type: " + csType);
}
@@ -2250,7 +2323,7 @@ AuthorityFactory::createGeodeticCRS(const std::string &code,
}
std::string sql("SELECT name, type, coordinate_system_auth_name, "
"coordinate_system_code, datum_auth_name, datum_code, "
- "area_of_use_auth_name, area_of_use_code, text_definition, "
+ "text_definition, "
"deprecated FROM "
"geodetic_crs WHERE auth_name = ? AND code = ?");
if (geographicOnly) {
@@ -2270,13 +2343,11 @@ AuthorityFactory::createGeodeticCRS(const std::string &code,
const auto &cs_code = row[3];
const auto &datum_auth_name = row[4];
const auto &datum_code = row[5];
- const auto &area_of_use_auth_name = row[6];
- const auto &area_of_use_code = row[7];
- const auto &text_definition = row[8];
- const bool deprecated = row[9] == "1";
+ const auto &text_definition = row[6];
+ const bool deprecated = row[7] == "1";
- auto props = d->createProperties(
- code, name, deprecated, area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages("geodetic_crs", code, name,
+ deprecated);
if (!text_definition.empty()) {
DatabaseContext::Private::RecursionDetector detector(d->context());
@@ -2359,7 +2430,7 @@ AuthorityFactory::createVerticalCRS(const std::string &code) const {
auto res = d->runWithCodeParam(
"SELECT name, coordinate_system_auth_name, "
"coordinate_system_code, datum_auth_name, datum_code, "
- "area_of_use_auth_name, area_of_use_code, deprecated FROM "
+ "deprecated FROM "
"vertical_crs WHERE auth_name = ? AND code = ?",
code);
if (res.empty()) {
@@ -2373,16 +2444,14 @@ AuthorityFactory::createVerticalCRS(const std::string &code) const {
const auto &cs_code = row[2];
const auto &datum_auth_name = row[3];
const auto &datum_code = row[4];
- const auto &area_of_use_auth_name = row[5];
- const auto &area_of_use_code = row[6];
- const bool deprecated = row[7] == "1";
+ const bool deprecated = row[5] == "1";
auto cs =
d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code);
auto datum =
d->createFactory(datum_auth_name)->createVerticalDatum(datum_code);
- auto props = d->createProperties(
- code, name, deprecated, area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages("vertical_crs", code, name,
+ deprecated);
auto verticalCS = util::nn_dynamic_pointer_cast<cs::VerticalCS>(cs);
if (verticalCS) {
@@ -2412,8 +2481,7 @@ operation::ConversionNNPtr
AuthorityFactory::createConversion(const std::string &code) const {
static const char *sql =
- "SELECT name, description, scope, "
- "area_of_use_auth_name, area_of_use_code, "
+ "SELECT name, description, "
"method_auth_name, method_code, method_name, "
"param1_auth_name, param1_code, param1_name, param1_value, "
@@ -2463,9 +2531,6 @@ AuthorityFactory::createConversion(const std::string &code) const {
size_t idx = 0;
const auto &name = row[idx++];
const auto &description = row[idx++];
- const auto &scope = row[idx++];
- const auto &area_of_use_auth_name = row[idx++];
- const auto &area_of_use_code = row[idx++];
const auto &method_auth_name = row[idx++];
const auto &method_code = row[idx++];
const auto &method_name = row[idx++];
@@ -2498,9 +2563,11 @@ AuthorityFactory::createConversion(const std::string &code) const {
}
const bool deprecated = row[base_param_idx + N_MAX_PARAMS * 6] == "1";
- auto propConversion =
- d->createProperties(code, name, deprecated, description, scope,
- area_of_use_auth_name, area_of_use_code);
+ auto propConversion = d->createPropertiesSearchUsages(
+ "conversion", code, name, deprecated);
+ if (!description.empty())
+ propConversion.set(common::IdentifiedObject::REMARKS_KEY,
+ description);
auto propMethod = util::PropertyMap().set(
common::IdentifiedObject::NAME_KEY, method_name);
@@ -2556,7 +2623,7 @@ AuthorityFactory::Private::createProjectedCRSBegin(const std::string &code) {
"SELECT name, coordinate_system_auth_name, "
"coordinate_system_code, geodetic_crs_auth_name, geodetic_crs_code, "
"conversion_auth_name, conversion_code, "
- "area_of_use_auth_name, area_of_use_code, text_definition, "
+ "text_definition, "
"deprecated FROM projected_crs WHERE auth_name = ? AND code = ?",
code);
}
@@ -2581,13 +2648,11 @@ AuthorityFactory::Private::createProjectedCRSEnd(const std::string &code,
const auto &geodetic_crs_code = row[4];
const auto &conversion_auth_name = row[5];
const auto &conversion_code = row[6];
- const auto &area_of_use_auth_name = row[7];
- const auto &area_of_use_code = row[8];
- const auto &text_definition = row[9];
- const bool deprecated = row[10] == "1";
+ const auto &text_definition = row[7];
+ const bool deprecated = row[8] == "1";
- auto props = createProperties(code, name, deprecated,
- area_of_use_auth_name, area_of_use_code);
+ auto props = createPropertiesSearchUsages("projected_crs", code, name,
+ deprecated);
if (!text_definition.empty()) {
DatabaseContext::Private::RecursionDetector detector(context());
@@ -2670,12 +2735,12 @@ AuthorityFactory::Private::createProjectedCRSEnd(const std::string &code,
crs::CompoundCRSNNPtr
AuthorityFactory::createCompoundCRS(const std::string &code) const {
- auto res = d->runWithCodeParam(
- "SELECT name, horiz_crs_auth_name, horiz_crs_code, "
- "vertical_crs_auth_name, vertical_crs_code, "
- "area_of_use_auth_name, area_of_use_code, deprecated FROM "
- "compound_crs WHERE auth_name = ? AND code = ?",
- code);
+ auto res =
+ d->runWithCodeParam("SELECT name, horiz_crs_auth_name, horiz_crs_code, "
+ "vertical_crs_auth_name, vertical_crs_code, "
+ "deprecated FROM "
+ "compound_crs WHERE auth_name = ? AND code = ?",
+ code);
if (res.empty()) {
throw NoSuchAuthorityCodeException("compoundCRS not found",
d->authority(), code);
@@ -2687,9 +2752,7 @@ AuthorityFactory::createCompoundCRS(const std::string &code) const {
const auto &horiz_crs_code = row[2];
const auto &vertical_crs_auth_name = row[3];
const auto &vertical_crs_code = row[4];
- const auto &area_of_use_auth_name = row[5];
- const auto &area_of_use_code = row[6];
- const bool deprecated = row[7] == "1";
+ const bool deprecated = row[5] == "1";
auto horizCRS =
d->createFactory(horiz_crs_auth_name)
@@ -2697,8 +2760,8 @@ AuthorityFactory::createCompoundCRS(const std::string &code) const {
auto vertCRS = d->createFactory(vertical_crs_auth_name)
->createVerticalCRS(vertical_crs_code);
- auto props = d->createProperties(
- code, name, deprecated, area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages("compound_crs", code, name,
+ deprecated);
return crs::CompoundCRS::create(
props, std::vector<crs::CRSNNPtr>{horizCRS, vertCRS});
} catch (const std::exception &ex) {
@@ -2831,10 +2894,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
if (type == "helmert_transformation") {
auto res = d->runWithCodeParam(
- "SELECT name, description, scope, "
+ "SELECT name, description, "
"method_auth_name, method_code, method_name, "
"source_crs_auth_name, source_crs_code, target_crs_auth_name, "
- "target_crs_code, area_of_use_auth_name, area_of_use_code, "
+ "target_crs_code, "
"accuracy, tx, ty, tz, translation_uom_auth_name, "
"translation_uom_code, rx, ry, rz, rotation_uom_auth_name, "
"rotation_uom_code, scale_difference, "
@@ -2858,7 +2921,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
size_t idx = 0;
const auto &name = row[idx++];
const auto &description = row[idx++];
- const auto &scope = row[idx++];
const auto &method_auth_name = row[idx++];
const auto &method_code = row[idx++];
const auto &method_name = row[idx++];
@@ -2866,8 +2928,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
const auto &source_crs_code = row[idx++];
const auto &target_crs_auth_name = row[idx++];
const auto &target_crs_code = row[idx++];
- const auto &area_of_use_auth_name = row[idx++];
- const auto &area_of_use_code = row[idx++];
const auto &accuracy = row[idx++];
const auto &tx = row[idx++];
@@ -3046,9 +3106,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
values.emplace_back(createLength(pz, uom_pivot));
}
- auto props =
- d->createProperties(code, name, deprecated, description, scope,
- area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages(
+ type, code, name, deprecated, description);
if (!operation_version.empty()) {
props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY,
operation_version);
@@ -3076,10 +3135,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
if (type == "grid_transformation") {
auto res = d->runWithCodeParam(
- "SELECT name, description, scope, "
+ "SELECT name, description, "
"method_auth_name, method_code, method_name, "
"source_crs_auth_name, source_crs_code, target_crs_auth_name, "
- "target_crs_code, area_of_use_auth_name, area_of_use_code, "
+ "target_crs_code, "
"accuracy, grid_param_auth_name, grid_param_code, grid_param_name, "
"grid_name, "
"grid2_param_auth_name, grid2_param_code, grid2_param_name, "
@@ -3098,7 +3157,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
size_t idx = 0;
const auto &name = row[idx++];
const auto &description = row[idx++];
- const auto &scope = row[idx++];
const auto &method_auth_name = row[idx++];
const auto &method_code = row[idx++];
const auto &method_name = row[idx++];
@@ -3106,8 +3164,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
const auto &source_crs_code = row[idx++];
const auto &target_crs_auth_name = row[idx++];
const auto &target_crs_code = row[idx++];
- const auto &area_of_use_auth_name = row[idx++];
- const auto &area_of_use_code = row[idx++];
const auto &accuracy = row[idx++];
const auto &grid_param_auth_name = row[idx++];
const auto &grid_param_code = row[idx++];
@@ -3162,9 +3218,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
operation::ParameterValue::createFilename(grid2_name));
}
- auto props =
- d->createProperties(code, name, deprecated, description, scope,
- area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages(
+ type, code, name, deprecated, description);
if (!operation_version.empty()) {
props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY,
operation_version);
@@ -3197,10 +3252,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
std::ostringstream buffer;
buffer.imbue(std::locale::classic());
buffer
- << "SELECT name, description, scope, "
+ << "SELECT name, description, "
"method_auth_name, method_code, method_name, "
"source_crs_auth_name, source_crs_code, target_crs_auth_name, "
- "target_crs_code, area_of_use_auth_name, area_of_use_code, "
+ "target_crs_code, "
"accuracy";
constexpr int N_MAX_PARAMS = 7;
for (int i = 1; i <= N_MAX_PARAMS; ++i) {
@@ -3225,7 +3280,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
size_t idx = 0;
const auto &name = row[idx++];
const auto &description = row[idx++];
- const auto &scope = row[idx++];
const auto &method_auth_name = row[idx++];
const auto &method_code = row[idx++];
const auto &method_name = row[idx++];
@@ -3233,8 +3287,6 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
const auto &source_crs_code = row[idx++];
const auto &target_crs_auth_name = row[idx++];
const auto &target_crs_code = row[idx++];
- const auto &area_of_use_auth_name = row[idx++];
- const auto &area_of_use_code = row[idx++];
const auto &accuracy = row[idx++];
const size_t base_param_idx = idx;
@@ -3279,9 +3331,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
d->createFactory(target_crs_auth_name)
->createCoordinateReferenceSystem(target_crs_code);
- auto props =
- d->createProperties(code, name, deprecated, description, scope,
- area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages(
+ type, code, name, deprecated, description);
if (!operation_version.empty()) {
props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY,
operation_version);
@@ -3338,10 +3389,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
if (allowConcatenated && type == "concatenated_operation") {
auto res = d->runWithCodeParam(
- "SELECT name, description, scope, "
+ "SELECT name, description, "
"source_crs_auth_name, source_crs_code, "
"target_crs_auth_name, target_crs_code, "
- "area_of_use_auth_name, area_of_use_code, accuracy, "
+ "accuracy, "
"operation_version, deprecated FROM "
"concatenated_operation WHERE auth_name = ? AND code = ?",
code);
@@ -3362,13 +3413,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
size_t idx = 0;
const auto &name = row[idx++];
const auto &description = row[idx++];
- const auto &scope = row[idx++];
const auto &source_crs_auth_name = row[idx++];
const auto &source_crs_code = row[idx++];
const auto &target_crs_auth_name = row[idx++];
const auto &target_crs_code = row[idx++];
- const auto &area_of_use_auth_name = row[idx++];
- const auto &area_of_use_code = row[idx++];
const auto &accuracy = row[idx++];
const auto &operation_version = row[idx++];
const auto &deprecated_str = row[idx++];
@@ -3392,9 +3440,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
->createCoordinateReferenceSystem(target_crs_code),
operations);
- auto props =
- d->createProperties(code, name, deprecated, description, scope,
- area_of_use_auth_name, area_of_use_code);
+ auto props = d->createPropertiesSearchUsages(
+ type, code, name, deprecated, description);
if (!operation_version.empty()) {
props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY,
operation_version);
@@ -3602,11 +3649,17 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
sql = "SELECT source_crs_auth_name, source_crs_code, "
"target_crs_auth_name, target_crs_code, "
"cov.auth_name, cov.code, cov.table_name, "
- "area.south_lat, area.west_lon, area.north_lat, area.east_lon, "
+ "extent.south_lat, extent.west_lon, extent.north_lat, "
+ "extent.east_lon, "
"ss.replacement_auth_name, ss.replacement_code FROM "
- "coordinate_operation_view cov JOIN area "
- "ON cov.area_of_use_auth_name = area.auth_name AND "
- "cov.area_of_use_code = area.code "
+ "coordinate_operation_view cov "
+ "JOIN usage ON "
+ "usage.object_table_name = cov.table_name AND "
+ "usage.object_auth_name = cov.auth_name AND "
+ "usage.object_code = cov.code "
+ "JOIN extent "
+ "ON extent.auth_name = usage.extent_auth_name AND "
+ "extent.code = usage.extent_code "
"LEFT JOIN supersession ss ON "
"ss.superseded_table_name = cov.table_name AND "
"ss.superseded_auth_name = cov.auth_name AND "
@@ -3618,11 +3671,17 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
sql = "SELECT source_crs_auth_name, source_crs_code, "
"target_crs_auth_name, target_crs_code, "
"cov.auth_name, cov.code, cov.table_name, "
- "area.south_lat, area.west_lon, area.north_lat, area.east_lon "
+ "extent.south_lat, extent.west_lon, extent.north_lat, "
+ "extent.east_lon "
"FROM "
- "coordinate_operation_view cov JOIN area "
- "ON cov.area_of_use_auth_name = area.auth_name AND "
- "cov.area_of_use_code = area.code "
+ "coordinate_operation_view cov "
+ "JOIN usage ON "
+ "usage.object_table_name = cov.table_name AND "
+ "usage.object_auth_name = cov.auth_name AND "
+ "usage.object_code = cov.code "
+ "JOIN extent "
+ "ON extent.auth_name = usage.extent_auth_name AND "
+ "extent.code = usage.extent_code "
"WHERE ";
}
ListOfParams params;
@@ -3955,10 +4014,20 @@ AuthorityFactory::createFromCRSCodesWithIntermediates(
"ss2.same_source_target_crs = 1 ");
const std::string joinArea(
(discardSuperseded ? joinSupersession : std::string()) +
- "JOIN area a1 ON v1.area_of_use_auth_name = a1.auth_name "
- "AND v1.area_of_use_code = a1.code "
- "JOIN area a2 ON v2.area_of_use_auth_name = a2.auth_name "
- "AND v2.area_of_use_code = a2.code ");
+ "JOIN usage u1 ON "
+ "u1.object_table_name = v1.table_name AND "
+ "u1.object_auth_name = v1.auth_name AND "
+ "u1.object_code = v1.code "
+ "JOIN extent a1 "
+ "ON a1.auth_name = u1.extent_auth_name AND "
+ "a1.code = u1.extent_code "
+ "JOIN usage u2 ON "
+ "u2.object_table_name = v2.table_name AND "
+ "u2.object_auth_name = v2.auth_name AND "
+ "u2.object_code = v2.code "
+ "JOIN extent a2 "
+ "ON a2.auth_name = u2.extent_auth_name AND "
+ "a2.code = u2.extent_code ");
const std::string orderBy(
"ORDER BY (CASE WHEN accuracy1 is NULL THEN 1 ELSE 0 END) + "
"(CASE WHEN accuracy2 is NULL THEN 1 ELSE 0 END), "
@@ -4399,11 +4468,20 @@ AuthorityFactory::createBetweenGeodeticCRSWithDatumBasedIntermediates(
"AND g_v2s.code = v2.source_crs_code "
"AND g_v2t.auth_name = v2.target_crs_auth_name "
"AND g_v2t.code = v2.target_crs_code ");
- const std::string joinArea(
- "JOIN area a1 ON v1.area_of_use_auth_name = a1.auth_name "
- "AND v1.area_of_use_code = a1.code "
- "JOIN area a2 ON v2.area_of_use_auth_name = a2.auth_name "
- "AND v2.area_of_use_code = a2.code ");
+ const std::string joinArea("JOIN usage u1 ON "
+ "u1.object_table_name = v1.table_name AND "
+ "u1.object_auth_name = v1.auth_name AND "
+ "u1.object_code = v1.code "
+ "JOIN extent a1 "
+ "ON a1.auth_name = u1.extent_auth_name AND "
+ "a1.code = u1.extent_code "
+ "JOIN usage u2 ON "
+ "u2.object_table_name = v2.table_name AND "
+ "u2.object_auth_name = v2.auth_name AND "
+ "u2.object_code = v2.code "
+ "JOIN extent a2 "
+ "ON a2.auth_name = u2.extent_auth_name AND "
+ "a2.code = u2.extent_code ");
auto params = ListOfParams{sourceCRSAuthName, sourceCRSCode,
targetCRSAuthName, targetCRSCode};
@@ -5206,13 +5284,23 @@ AuthorityFactory::getDescriptionText(const std::string &code) const {
* @throw FactoryException
*/
std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
+
+ const auto getSqlArea = [](const std::string &table_name) {
+ return "JOIN usage u ON "
+ "u.object_table_name = '" +
+ table_name + "' AND "
+ "u.object_auth_name = c.auth_name AND "
+ "u.object_code = c.code "
+ "JOIN extent a "
+ "ON a.auth_name = u.extent_auth_name AND "
+ "a.code = u.extent_code ";
+ };
+
std::string sql = "SELECT c.auth_name, c.code, c.name, c.type, "
"c.deprecated, "
"a.west_lon, a.south_lat, a.east_lon, a.north_lat, "
- "a.name, NULL FROM geodetic_crs c "
- "JOIN area a ON "
- "c.area_of_use_auth_name = a.auth_name AND "
- "c.area_of_use_code = a.code";
+ "a.name, NULL FROM geodetic_crs c " +
+ getSqlArea("geodetic_crs");
ListOfParams params;
if (d->hasAuthorityRestriction()) {
sql += " WHERE c.auth_name = ?";
@@ -5222,10 +5310,8 @@ std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
sql += "SELECT c.auth_name, c.code, c.name, 'projected', "
"c.deprecated, "
"a.west_lon, a.south_lat, a.east_lon, a.north_lat, "
- "a.name, cm.name AS conversion_method_name FROM projected_crs c "
- "JOIN area a ON "
- "c.area_of_use_auth_name = a.auth_name AND "
- "c.area_of_use_code = a.code "
+ "a.name, cm.name AS conversion_method_name FROM projected_crs c " +
+ getSqlArea("projected_crs") +
"LEFT JOIN conversion_table conv ON "
"c.conversion_auth_name = conv.auth_name AND "
"c.conversion_code = conv.code "
@@ -5240,10 +5326,8 @@ std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
sql += "SELECT c.auth_name, c.code, c.name, 'vertical', "
"c.deprecated, "
"a.west_lon, a.south_lat, a.east_lon, a.north_lat, "
- "a.name, NULL FROM vertical_crs c "
- "JOIN area a ON "
- "c.area_of_use_auth_name = a.auth_name AND "
- "c.area_of_use_code = a.code";
+ "a.name, NULL FROM vertical_crs c " +
+ getSqlArea("vertical_crs");
if (d->hasAuthorityRestriction()) {
sql += " WHERE c.auth_name = ?";
params.emplace_back(d->authority());
@@ -5252,10 +5336,8 @@ std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
sql += "SELECT c.auth_name, c.code, c.name, 'compound', "
"c.deprecated, "
"a.west_lon, a.south_lat, a.east_lon, a.north_lat, "
- "a.name, NULL FROM compound_crs c "
- "JOIN area a ON "
- "c.area_of_use_auth_name = a.auth_name AND "
- "c.area_of_use_code = a.code";
+ "a.name, NULL FROM compound_crs c " +
+ getSqlArea("compound_crs");
if (d->hasAuthorityRestriction()) {
sql += " WHERE c.auth_name = ?";
params.emplace_back(d->authority());
@@ -5416,7 +5498,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias(
if (res.empty()) { // shouldn't happen normally
return std::string();
}
- return res.front()[0];
+ return removeEnsembleSuffix(res.front()[0]);
}
}
return std::string();
@@ -5466,7 +5548,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias(
outTableName = row[1];
outAuthName = row[2];
outCode = row[3];
- return row[0];
+ return removeEnsembleSuffix(row[0]);
}
}
@@ -5521,7 +5603,7 @@ AuthorityFactory::createObjectsFromNameEx(
const std::string &searchedName,
const std::vector<ObjectType> &allowedObjectTypes, bool approximateMatch,
size_t limitResultCount) const {
- std::string searchedNameWithoutDeprecated(searchedName);
+ std::string searchedNameWithoutDeprecated(addEnsembleSuffix(searchedName));
bool deprecated = false;
if (ends_with(searchedNameWithoutDeprecated, " (deprecated)")) {
deprecated = true;
@@ -5925,7 +6007,7 @@ std::list<std::pair<std::string, std::string>>
AuthorityFactory::listAreaOfUseFromName(const std::string &name,
bool approximateMatch) const {
std::string sql(
- "SELECT auth_name, code FROM area WHERE deprecated = 0 AND ");
+ "SELECT auth_name, code FROM extent WHERE deprecated = 0 AND ");
ListOfParams params;
if (d->hasAuthorityRestriction()) {
sql += " auth_name = ? AND ";