diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-11-01 18:50:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-01 18:50:58 +0100 |
| commit | 3b7c3a6ad42e3b4fc20884a71b9b9a9c6aad3dc5 (patch) | |
| tree | cbbcf9745d41f2f0d2a10ccfe29b1aab7580f6f9 /src | |
| parent | cccd65e50d1143a1119afedae97cec5a6b9397e9 (diff) | |
| parent | 119888b041258267768d632b89395e7074323326 (diff) | |
| download | PROJ-3b7c3a6ad42e3b4fc20884a71b9b9a9c6aad3dc5.tar.gz PROJ-3b7c3a6ad42e3b4fc20884a71b9b9a9c6aad3dc5.zip | |
Merge pull request #2371 from rouault/epsg10_part2
EPSG v10 update part 2: ingest DatumEnsemble from the database
Diffstat (limited to 'src')
| -rw-r--r-- | src/apps/projinfo.cpp | 18 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 5 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 8 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 295 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 9 | ||||
| -rw-r--r-- | src/proj.h | 3 |
6 files changed, 263 insertions, 75 deletions
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 37b76346..6ee5925a 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -79,7 +79,8 @@ struct OutputOptions { static void usage() { std::cerr - << "usage: projinfo [-o formats] [-k crs|operation|datum|ellipsoid] " + << "usage: projinfo [-o formats] " + "[-k crs|operation|datum|ensemble|ellipsoid] " "[--summary] [-q]" << std::endl << " ([--area name_or_code] | " @@ -184,11 +185,11 @@ static BaseObjectNNPtr buildObject( auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); - } 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]; + } else if ((kind == "ellipsoid" || kind == "datum" || + kind == "ensemble") && + tokens.size() == 2) { + auto urn = + "urn:ogc:def:" + kind + ":" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); } else { // Convenience to be able to use C escaped strings... @@ -222,6 +223,9 @@ static BaseObjectNNPtr buildObject( AuthorityFactory::ObjectType::ELLIPSOID); else if (kind == "datum") allowedTypes.push_back(AuthorityFactory::ObjectType::DATUM); + else if (kind == "ensemble") + allowedTypes.push_back( + AuthorityFactory::ObjectType::DATUM_ENSEMBLE); constexpr size_t limitResultCount = 10; auto factory = AuthorityFactory::create(NN_NO_CHECK(dbContext), std::string()); @@ -929,6 +933,8 @@ int main(int argc, char **argv) { objectKind = "ellipsoid"; } else if (ci_equal(kind, "datum")) { objectKind = "datum"; + } else if (ci_equal(kind, "ensemble")) { + objectKind = "ensemble"; } else { std::cerr << "Unrecognized value for option -k: " << kind << std::endl; diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 90a414c6..cbbdcaa8 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -675,6 +675,9 @@ PJ *proj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name, codeStr, usePROJAlternativeGridNames != 0) .as_nullable(); break; + case PJ_CATEGORY_DATUM_ENSEMBLE: + obj = factory->createDatumEnsemble(codeStr).as_nullable(); + break; } return pj_obj_create(ctx, NN_NO_CHECK(obj)); } catch (const std::exception &e) { @@ -916,7 +919,7 @@ convertPJObjectTypeToObjectType(PJ_TYPE type, bool &valid) { break; case PJ_TYPE_DATUM_ENSEMBLE: - cppType = AuthorityFactory::ObjectType::DATUM; + cppType = AuthorityFactory::ObjectType::DATUM_ENSEMBLE; break; case PJ_TYPE_TEMPORAL_DATUM: diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 5bc8074c..e29f6319 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1731,6 +1731,14 @@ void DatumEnsemble::_exportToWKT( formatter->startNode(io::WKTConstants::ENSEMBLEACCURACY, false); formatter->add(positionalAccuracy()->value()); formatter->endNode(); + + // In theory, we should do the following, but currently the WKT grammar + // doesn't allow this + // ObjectUsage::baseExportToWKT(formatter); + if (formatter->outputId()) { + formatID(formatter); + } + formatter->endNode(); } //! @endcond diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 5d02aeea..0ccfefc1 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -192,6 +192,13 @@ struct DatabaseContext::Private { void cache(const std::string &code, const datum::GeodeticReferenceFrameNNPtr &datum); + datum::DatumEnsemblePtr + // cppcheck-suppress functionStatic + getDatumEnsembleFromCache(const std::string &code); + // cppcheck-suppress functionStatic + void cache(const std::string &code, + const datum::DatumEnsembleNNPtr &datumEnsemble); + datum::EllipsoidPtr // cppcheck-suppress functionStatic getEllipsoidFromCache(const std::string &code); @@ -258,6 +265,7 @@ struct DatabaseContext::Private { LRUCacheOfObjects cacheCRS_{CACHE_SIZE}; LRUCacheOfObjects cacheEllipsoid_{CACHE_SIZE}; LRUCacheOfObjects cacheGeodeticDatum_{CACHE_SIZE}; + LRUCacheOfObjects cacheDatumEnsemble_{CACHE_SIZE}; LRUCacheOfObjects cachePrimeMeridian_{CACHE_SIZE}; LRUCacheOfObjects cacheCS_{CACHE_SIZE}; LRUCacheOfObjects cacheExtent_{CACHE_SIZE}; @@ -417,6 +425,22 @@ void DatabaseContext::Private::cache( // --------------------------------------------------------------------------- +datum::DatumEnsemblePtr +DatabaseContext::Private::getDatumEnsembleFromCache(const std::string &code) { + util::BaseObjectPtr obj; + getFromCache(cacheDatumEnsemble_, code, obj); + return std::static_pointer_cast<datum::DatumEnsemble>(obj); +} + +// --------------------------------------------------------------------------- + +void DatabaseContext::Private::cache( + const std::string &code, const datum::DatumEnsembleNNPtr &datumEnsemble) { + insertIntoCache(cacheDatumEnsemble_, code, datumEnsemble.as_nullable()); +} + +// --------------------------------------------------------------------------- + datum::EllipsoidPtr DatabaseContext::Private::getEllipsoidFromCache(const std::string &code) { util::BaseObjectPtr obj; @@ -1064,18 +1088,6 @@ std::string DatabaseContext::getOldProjGridName(const std::string &gridName) { // --------------------------------------------------------------------------- -// 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 @@ -2012,18 +2024,38 @@ AuthorityFactory::createEllipsoid(const std::string &code) const { datum::GeodeticReferenceFrameNNPtr AuthorityFactory::createGeodeticDatum(const std::string &code) const { + + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = true; + createGeodeticDatumOrEnsemble(code, datum, datumEnsemble, + turnEnsembleAsDatum); + return NN_NO_CHECK(datum); +} + +// --------------------------------------------------------------------------- + +void AuthorityFactory::createGeodeticDatumOrEnsemble( + const std::string &code, datum::GeodeticReferenceFramePtr &outDatum, + datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const { const auto cacheKey(d->authority() + code); { - auto datum = d->context()->d->getGeodeticDatumFromCache(cacheKey); - if (datum) { - return NN_NO_CHECK(datum); + outDatumEnsemble = d->context()->d->getDatumEnsembleFromCache(cacheKey); + if (outDatumEnsemble) { + if (!turnEnsembleAsDatum) + return; + outDatumEnsemble = nullptr; + } + outDatum = d->context()->d->getGeodeticDatumFromCache(cacheKey); + if (outDatum) { + return; } } auto res = d->runWithCodeParam("SELECT name, ellipsoid_auth_name, ellipsoid_code, " "prime_meridian_auth_name, prime_meridian_code, " "publication_date, frame_reference_epoch, " - "deprecated FROM geodetic_datum " + "ensemble_accuracy, deprecated FROM geodetic_datum " "WHERE " "auth_name = ? AND code = ?", code); @@ -2040,29 +2072,63 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const { const auto &prime_meridian_code = row[4]; const auto &publication_date = row[5]; const auto &frame_reference_epoch = row[6]; - const bool deprecated = row[7] == "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->createPropertiesSearchUsages( - "geodetic_datum", code, removeEnsembleSuffix(name), deprecated); - auto anchor = util::optional<std::string>(); - if (!publication_date.empty()) { - props.set("PUBLICATION_DATE", publication_date); - } - auto datum = - frame_reference_epoch.empty() - ? datum::GeodeticReferenceFrame::create(props, ellipsoid, - anchor, pm) - : util::nn_static_pointer_cast<datum::GeodeticReferenceFrame>( - datum::DynamicGeodeticReferenceFrame::create( - props, ellipsoid, anchor, pm, - common::Measure(c_locale_stod(frame_reference_epoch), - common::UnitOfMeasure::YEAR), - util::optional<std::string>())); - d->context()->d->cache(cacheKey, datum); - return datum; + const auto &ensemble_accuracy = row[7]; + const bool deprecated = row[8] == "1"; + + std::string massagedName = name; + if (turnEnsembleAsDatum) { + if (name == "World Geodetic System 1984 ensemble") { + massagedName = "World Geodetic System 1984"; + } else if (name == + "European Terrestrial Reference System 1989 ensemble") { + massagedName = "European Terrestrial Reference System 1989"; + } + } + auto props = d->createPropertiesSearchUsages("geodetic_datum", code, + massagedName, deprecated); + + if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) { + auto resMembers = + d->run("SELECT member_auth_name, member_code FROM " + "geodetic_datum_ensemble_member WHERE " + "ensemble_auth_name = ? AND ensemble_code = ? " + "ORDER BY sequence", + {d->authority(), code}); + + std::vector<datum::DatumNNPtr> members; + for (const auto &memberRow : resMembers) { + members.push_back( + d->createFactory(memberRow[0])->createDatum(memberRow[1])); + } + auto datumEnsemble = datum::DatumEnsemble::create( + props, std::move(members), + metadata::PositionalAccuracy::create(ensemble_accuracy)); + d->context()->d->cache(cacheKey, datumEnsemble); + outDatumEnsemble = datumEnsemble.as_nullable(); + } else { + auto ellipsoid = d->createFactory(ellipsoid_auth_name) + ->createEllipsoid(ellipsoid_code); + auto pm = d->createFactory(prime_meridian_auth_name) + ->createPrimeMeridian(prime_meridian_code); + + auto anchor = util::optional<std::string>(); + if (!publication_date.empty()) { + props.set("PUBLICATION_DATE", publication_date); + } + auto datum = frame_reference_epoch.empty() + ? datum::GeodeticReferenceFrame::create( + props, ellipsoid, anchor, pm) + : util::nn_static_pointer_cast< + datum::GeodeticReferenceFrame>( + datum::DynamicGeodeticReferenceFrame::create( + props, ellipsoid, anchor, pm, + common::Measure( + c_locale_stod(frame_reference_epoch), + common::UnitOfMeasure::YEAR), + util::optional<std::string>())); + d->context()->d->cache(cacheKey, datum); + outDatum = datum.as_nullable(); + } } catch (const std::exception &ex) { throw buildFactoryException("geodetic reference frame", code, ex); } @@ -2080,9 +2146,23 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const { datum::VerticalReferenceFrameNNPtr AuthorityFactory::createVerticalDatum(const std::string &code) const { + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = true; + createVerticalDatumOrEnsemble(code, datum, datumEnsemble, + turnEnsembleAsDatum); + return NN_NO_CHECK(datum); +} + +// --------------------------------------------------------------------------- + +void AuthorityFactory::createVerticalDatumOrEnsemble( + const std::string &code, datum::VerticalReferenceFramePtr &outDatum, + datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const { auto res = d->runWithCodeParam("SELECT name, publication_date, " - "frame_reference_epoch, deprecated FROM " + "frame_reference_epoch, ensemble_accuracy, " + "deprecated FROM " "vertical_datum WHERE auth_name = ? AND code = ?", code); if (res.empty()) { @@ -2094,24 +2174,49 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const { const auto &name = row[0]; const auto &publication_date = row[1]; const auto &frame_reference_epoch = row[2]; - const bool deprecated = row[3] == "1"; + const auto &ensemble_accuracy = row[3]; + const bool deprecated = row[4] == "1"; auto props = d->createPropertiesSearchUsages("vertical_datum", code, name, deprecated); - if (!publication_date.empty()) { - props.set("PUBLICATION_DATE", publication_date); - } - if (d->authority() == "ESRI" && starts_with(code, "from_geogdatum_")) { - props.set("VERT_DATUM_TYPE", "2002"); - } - auto anchor = util::optional<std::string>(); - if (frame_reference_epoch.empty()) { - return datum::VerticalReferenceFrame::create(props, anchor); + if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) { + auto resMembers = + d->run("SELECT member_auth_name, member_code FROM " + "vertical_datum_ensemble_member WHERE " + "ensemble_auth_name = ? AND ensemble_code = ? " + "ORDER BY sequence", + {d->authority(), code}); + + std::vector<datum::DatumNNPtr> members; + for (const auto &memberRow : resMembers) { + members.push_back( + d->createFactory(memberRow[0])->createDatum(memberRow[1])); + } + auto datumEnsemble = datum::DatumEnsemble::create( + props, std::move(members), + metadata::PositionalAccuracy::create(ensemble_accuracy)); + outDatumEnsemble = datumEnsemble.as_nullable(); } else { - return datum::DynamicVerticalReferenceFrame::create( - props, anchor, util::optional<datum::RealizationMethod>(), - common::Measure(c_locale_stod(frame_reference_epoch), - common::UnitOfMeasure::YEAR), - util::optional<std::string>()); + if (!publication_date.empty()) { + props.set("PUBLICATION_DATE", publication_date); + } + if (d->authority() == "ESRI" && + starts_with(code, "from_geogdatum_")) { + props.set("VERT_DATUM_TYPE", "2002"); + } + auto anchor = util::optional<std::string>(); + if (frame_reference_epoch.empty()) { + outDatum = datum::VerticalReferenceFrame::create(props, anchor) + .as_nullable(); + } else { + outDatum = + datum::DynamicVerticalReferenceFrame::create( + props, anchor, + util::optional<datum::RealizationMethod>(), + common::Measure(c_locale_stod(frame_reference_epoch), + common::UnitOfMeasure::YEAR), + util::optional<std::string>()) + .as_nullable(); + } } } catch (const std::exception &ex) { throw buildFactoryException("vertical reference frame", code, ex); @@ -2472,20 +2577,24 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, auto cs = d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code); - auto datum = - d->createFactory(datum_auth_name)->createGeodeticDatum(datum_code); + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + d->createFactory(datum_auth_name) + ->createGeodeticDatumOrEnsemble(datum_code, datum, datumEnsemble, + turnEnsembleAsDatum); auto ellipsoidalCS = util::nn_dynamic_pointer_cast<cs::EllipsoidalCS>(cs); if ((type == GEOG_2D || type == GEOG_3D) && ellipsoidalCS) { auto crsRet = crs::GeographicCRS::create( - props, datum, NN_NO_CHECK(ellipsoidalCS)); + props, datum, datumEnsemble, NN_NO_CHECK(ellipsoidalCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; } auto geocentricCS = util::nn_dynamic_pointer_cast<cs::CartesianCS>(cs); if (type == GEOCENTRIC && geocentricCS) { - auto crsRet = crs::GeodeticCRS::create(props, datum, + auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble, NN_NO_CHECK(geocentricCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; @@ -2539,16 +2648,19 @@ AuthorityFactory::createVerticalCRS(const std::string &code) const { 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); - + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + d->createFactory(datum_auth_name) + ->createVerticalDatumOrEnsemble(datum_code, datum, datumEnsemble, + turnEnsembleAsDatum); auto props = d->createPropertiesSearchUsages("vertical_crs", code, name, deprecated); auto verticalCS = util::nn_dynamic_pointer_cast<cs::VerticalCS>(cs); if (verticalCS) { - auto crsRet = - crs::VerticalCRS::create(props, datum, NN_NO_CHECK(verticalCS)); + auto crsRet = crs::VerticalCRS::create(props, datum, datumEnsemble, + NN_NO_CHECK(verticalCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; } @@ -5340,6 +5452,11 @@ AuthorityFactory::getAuthorityCodes(const ObjectType &type, case ObjectType::CONCATENATED_OPERATION: sql = "SELECT code FROM concatenated_operation WHERE "; break; + case ObjectType::DATUM_ENSEMBLE: + sql = "SELECT code FROM object_view WHERE table_name IN " + "('geodetic_datum', 'vertical_datum') AND " + "type = 'ensemble' AND "; + break; } sql += "auth_name = ?"; @@ -5617,7 +5734,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias( if (res.empty()) { // shouldn't happen normally return std::string(); } - return removeEnsembleSuffix(res.front()[0]); + return res.front()[0]; } } return std::string(); @@ -5667,7 +5784,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias( outTableName = row[1]; outAuthName = row[2]; outCode = row[3]; - return removeEnsembleSuffix(row[0]); + return row[0]; } } @@ -5849,12 +5966,28 @@ AuthorityFactory::createObjectsFromNameEx( res.emplace_back( TableType("concatenated_operation", std::string())); break; + case ObjectType::DATUM_ENSEMBLE: + res.emplace_back(TableType("geodetic_datum", "ensemble")); + res.emplace_back(TableType("vertical_datum", "ensemble")); + break; } } } return res; }; + bool datumEnsembleAllowed = false; + if (allowedObjectTypes.empty()) { + datumEnsembleAllowed = true; + } else { + for (const auto type : allowedObjectTypes) { + if (type == ObjectType::DATUM_ENSEMBLE) { + datumEnsembleAllowed = true; + break; + } + } + } + const auto listTableNameType = getTableAndTypeConstraints(); bool first = true; ListOfParams params; @@ -5872,6 +6005,8 @@ AuthorityFactory::createObjectsFromNameEx( if (!tableNameTypePair.second.empty()) { if (tableNameTypePair.second == "frame_reference_epoch") { sql += "AND frame_reference_epoch IS NOT NULL "; + } else if (tableNameTypePair.second == "ensemble") { + sql += "AND ensemble_accuracy IS NOT NULL "; } else { sql += "AND type = '"; sql += tableNameTypePair.second; @@ -5906,6 +6041,8 @@ AuthorityFactory::createObjectsFromNameEx( if (!tableNameTypePair.second.empty()) { if (tableNameTypePair.second == "frame_reference_epoch") { sql += "AND ov.frame_reference_epoch IS NOT NULL "; + } else if (tableNameTypePair.second == "ensemble") { + sql += "AND ov.ensemble_accuracy IS NOT NULL "; } else { sql += "AND ov.type = '"; sql += tableNameTypePair.second; @@ -6053,7 +6190,7 @@ AuthorityFactory::createObjectsFromNameEx( break; } auto factory = d->createFactory(auth_name); - auto getObject = [&factory]( + auto getObject = [&factory, datumEnsembleAllowed]( const std::string &l_table_name, const std::string &l_code) -> common::IdentifiedObjectNNPtr { if (l_table_name == "prime_meridian") { @@ -6061,8 +6198,32 @@ AuthorityFactory::createObjectsFromNameEx( } else if (l_table_name == "ellipsoid") { return factory->createEllipsoid(l_code); } else if (l_table_name == "geodetic_datum") { + if (datumEnsembleAllowed) { + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + factory->createGeodeticDatumOrEnsemble( + l_code, datum, datumEnsemble, turnEnsembleAsDatum); + if (datum) { + return NN_NO_CHECK(datum); + } + assert(datumEnsemble); + return NN_NO_CHECK(datumEnsemble); + } return factory->createGeodeticDatum(l_code); } else if (l_table_name == "vertical_datum") { + if (datumEnsembleAllowed) { + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + factory->createVerticalDatumOrEnsemble( + l_code, datum, datumEnsemble, turnEnsembleAsDatum); + if (datum) { + return NN_NO_CHECK(datum); + } + assert(datumEnsemble); + return NN_NO_CHECK(datumEnsemble); + } return factory->createVerticalDatum(l_code); } else if (l_table_name == "geodetic_crs") { return factory->createGeodeticCRS(l_code); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index f4ec7740..b2e5822b 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2110,6 +2110,10 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame( name = "World Geodetic System 1984"; authNameFromAlias = Identifier::EPSG; codeFromAlias = "6326"; + } else if (name == "D_ETRS_1989") { + name = "European Terrestrial Reference System 1989"; + authNameFromAlias = Identifier::EPSG; + codeFromAlias = "6258"; } else { tableNameForAlias = "geodetic_datum"; } @@ -6263,6 +6267,9 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, if (type == "datum") { return factory->createDatum(code); } + if (type == "ensemble") { + return factory->createDatumEnsemble(code); + } if (type == "ellipsoid") { return factory->createEllipsoid(code); } @@ -6381,6 +6388,8 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, AuthorityFactory::ObjectType:: DATUM, AuthorityFactory::ObjectType:: + DATUM_ENSEMBLE, + AuthorityFactory::ObjectType:: COORDINATE_OPERATION}, goOn); } catch (const std::exception &) { @@ -694,7 +694,8 @@ typedef enum PJ_CATEGORY_PRIME_MERIDIAN, PJ_CATEGORY_DATUM, PJ_CATEGORY_CRS, - PJ_CATEGORY_COORDINATE_OPERATION + PJ_CATEGORY_COORDINATE_OPERATION, + PJ_CATEGORY_DATUM_ENSEMBLE } PJ_CATEGORY; /** \brief Object type. */ |
