diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2019-05-01 18:42:13 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-01 18:42:13 +0200 |
| commit | fc48053092b4b6f496bb983765ebf619a356e257 (patch) | |
| tree | 2c53161326b766dc41e4733ce6579503fc702384 /src/iso19111 | |
| parent | e168ad31badb6702240174250894a76385da323b (diff) | |
| parent | eeda5f7e5fd94a0cdcbf90df1f0b04a090f4c037 (diff) | |
| download | PROJ-fc48053092b4b6f496bb983765ebf619a356e257.tar.gz PROJ-fc48053092b4b6f496bb983765ebf619a356e257.zip | |
Merge branch 'master' into check_exported_symbols
Diffstat (limited to 'src/iso19111')
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 40 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 43 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 54 |
3 files changed, 97 insertions, 40 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 7eab849c..605004b6 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -5120,10 +5120,11 @@ static void getESRIMethodNameAndParams(const Conversion *conv, } } else if (esriMapping->epsg_code == EPSG_CODE_METHOD_TRANSVERSE_MERCATOR) { - if (l_targetCRS && - (ci_find(l_targetCRS->nameStr(), "Gauss") != - std::string::npos || - ci_find(l_targetCRS->nameStr(), "GK_") != std::string::npos)) { + if (ci_find(conv->nameStr(), "Gauss Kruger") != std::string::npos || + (l_targetCRS && (ci_find(l_targetCRS->nameStr(), "Gauss") != + std::string::npos || + ci_find(l_targetCRS->nameStr(), "GK_") != + std::string::npos))) { esriParams = paramsESRI_Gauss_Kruger; esriMethodName = "Gauss_Kruger"; } else { @@ -7484,6 +7485,8 @@ Transformation::Private::registerInv(util::BaseObjectNNPtr thisIn, TransformationNNPtr invTransform) { invTransform->d->forwardOperation_ = util::nn_dynamic_pointer_cast<Transformation>(thisIn); + invTransform->setHasBallparkTransformation( + invTransform->d->forwardOperation_->hasBallparkTransformation()); return invTransform; } //! @endcond @@ -9490,6 +9493,7 @@ CoordinateOperationNNPtr ConcatenatedOperation::inverse() const { auto op = create(properties, inversedOperations, coordinateOperationAccuracies()); op->d->computedName_ = d->computedName_; + op->setHasBallparkTransformation(hasBallparkTransformation()); return op; } @@ -12584,11 +12588,11 @@ getResolvedCRS(const crs::CRSNNPtr &crs, const auto tmpAuthFactory = io::AuthorityFactory::create( authFactory->databaseContext(), *ids.front()->codeSpace()); try { - crs::CRSNNPtr resolvedCrs( + auto resolvedCrs( tmpAuthFactory->createProjectedCRS(ids.front()->code())); - if (resolvedCrs->_isEquivalentTo( + if (resolvedCrs->isEquivalentTo( crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return resolvedCrs; + return util::nn_static_pointer_cast<crs::CRS>(resolvedCrs); } } catch (const std::exception &) { } @@ -12616,12 +12620,13 @@ getResolvedCRS(const crs::CRSNNPtr &crs, const auto tmpAuthFactory = io::AuthorityFactory::create( authFactory->databaseContext(), *ids.front()->codeSpace()); try { - crs::CRSNNPtr resolvedCrs( + auto resolvedCrs( tmpAuthFactory->createCompoundCRS(ids.front()->code())); - if (resolvedCrs->_isEquivalentTo( + if (resolvedCrs->isEquivalentTo( crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return resolvedCrs; + return util::nn_static_pointer_cast<crs::CRS>( + resolvedCrs); } } catch (const std::exception &) { } @@ -12665,6 +12670,17 @@ CoordinateOperationFactory::createOperations( auto l_resolvedTargetCRS = getResolvedCRS(l_targetCRS, context); Private::Context contextPrivate(l_resolvedSourceCRS, l_resolvedTargetCRS, context); + + if (context->getSourceAndTargetCRSExtentUse() == + CoordinateOperationContext::SourceTargetCRSExtentUse::INTERSECTION) { + auto sourceCRSExtent(getExtent(l_resolvedSourceCRS)); + auto targetCRSExtent(getExtent(l_resolvedTargetCRS)); + if (sourceCRSExtent && targetCRSExtent && + !sourceCRSExtent->intersects(NN_NO_CHECK(targetCRSExtent))) { + return std::vector<CoordinateOperationNNPtr>(); + } + } + return filterAndSort(Private::createOperations(l_resolvedSourceCRS, l_resolvedTargetCRS, contextPrivate), @@ -12703,6 +12719,8 @@ void InverseCoordinateOperation::setPropertiesFromForward() { if (forwardOperation_->sourceCRS() && forwardOperation_->targetCRS()) { setCRSs(forwardOperation_.get(), true); } + setHasBallparkTransformation( + forwardOperation_->hasBallparkTransformation()); } // --------------------------------------------------------------------------- @@ -12785,7 +12803,7 @@ PROJBasedOperationNNPtr PROJBasedOperation::create( auto method = OperationMethod::create( util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, - "PROJ-based operation method (approximate) : " + + "PROJ-based operation method (approximate): " + projString), std::vector<GeneralOperationParameterNNPtr>{}); auto op = PROJBasedOperation::nn_make_shared<PROJBasedOperation>(method); diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 9f7467a2..4515188a 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -614,11 +614,16 @@ void DatabaseContext::Private::setHandle(sqlite3 *sqlite_handle) { // --------------------------------------------------------------------------- std::vector<std::string> DatabaseContext::Private::getDatabaseStructure() { - auto sqlRes = run("SELECT sql FROM sqlite_master WHERE type " - "IN ('table', 'trigger', 'view') ORDER BY type"); + const char *sqls[] = { + "SELECT sql FROM sqlite_master WHERE type = 'table'", + "SELECT sql FROM sqlite_master WHERE type = 'view'", + "SELECT sql FROM sqlite_master WHERE type = 'trigger'"}; std::vector<std::string> res; - for (const auto &row : sqlRes) { - res.emplace_back(row[0]); + for (const auto &sql : sqls) { + auto sqlRes = run(sql); + for (const auto &row : sqlRes) { + res.emplace_back(row[0]); + } } return res; } @@ -2408,6 +2413,11 @@ AuthorityFactory::createProjectedCRS(const std::string &code) const { auto conv = d->createFactory(conversion_auth_name) ->createConversion(conversion_code); + if (conv->nameStr() == "unnamed") { + conv = conv->shallowClone(); + conv->setProperties(util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, name)); + } auto cartesianCS = util::nn_dynamic_pointer_cast<cs::CartesianCS>(cs); if (cartesianCS) { @@ -3934,13 +3944,16 @@ 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, conv.method_name FROM projected_crs c " + "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 " - "LEFT JOIN conversion conv ON " + "LEFT JOIN conversion_table conv ON " "c.conversion_auth_name = conv.auth_name AND " - "c.conversion_code = conv.code"; + "c.conversion_code = conv.code " + "LEFT JOIN conversion_method cm ON " + "conv.method_auth_name = cm.auth_name AND " + "conv.method_code = cm.code"; if (d->hasAuthorityRestriction()) { sql += " WHERE c.auth_name = ?"; params.emplace_back(d->authority()); @@ -4663,9 +4676,9 @@ AuthorityFactory::createProjectedCRSFromExisting( std::string sql( "SELECT projected_crs.auth_name, projected_crs.code FROM projected_crs " - "JOIN conversion ON " - "projected_crs.conversion_auth_name = conversion.auth_name AND " - "projected_crs.conversion_code = conversion.code WHERE " + "JOIN conversion_table conv ON " + "projected_crs.conversion_auth_name = conv.auth_name AND " + "projected_crs.conversion_code = conv.code WHERE " "projected_crs.deprecated = 0 AND "); ListOfParams params; if (!candidatesGeodCRS.empty()) { @@ -4673,8 +4686,8 @@ AuthorityFactory::createProjectedCRSFromExisting( "projected_crs.geodetic_crs_"); sql += " AND "; } - sql += "conversion.method_auth_name = 'EPSG' AND " - "conversion.method_code = ?"; + sql += "conv.method_auth_name = 'EPSG' AND " + "conv.method_code = ?"; params.emplace_back(toString(methodEPSGCode)); if (d->hasAuthorityRestriction()) { sql += " AND projected_crs.auth_name = ?"; @@ -4701,11 +4714,11 @@ AuthorityFactory::createProjectedCRSFromExisting( if (unit == common::UnitOfMeasure::DEGREE && geogCRS->coordinateSystem()->axisList()[0]->unit() == unit) { const auto iParamAsStr(toString(iParam)); - sql += " AND conversion.param"; + sql += " AND conv.param"; sql += iParamAsStr; - sql += "_code = ? AND conversion.param"; + sql += "_code = ? AND conv.param"; sql += iParamAsStr; - sql += "_auth_name = 'EPSG' AND conversion.param"; + sql += "_auth_name = 'EPSG' AND conv.param"; sql += iParamAsStr; sql += "_value BETWEEN ? AND ?"; // As angles might be expressed with the odd unit EPSG:9110 diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index d8282bb0..e072a66f 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -757,13 +757,22 @@ const std::string &WKTFormatter::getHDatumExtension() const { // --------------------------------------------------------------------------- std::string WKTFormatter::morphNameToESRI(const std::string &name) { + + for (const auto *suffix : {"(m)", "(ftUS)", "(E-N)", "(N-E)"}) { + if (ends_with(name, suffix)) { + return morphNameToESRI( + name.substr(0, name.size() - strlen(suffix))) + + suffix; + } + } + std::string ret; bool insertUnderscore = false; // Replace any special character by underscore, except at the beginning // and of the name where those characters are removed. for (char ch : name) { - if (ch == '+' || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z')) { + if (ch == '+' || ch == '-' || (ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { if (insertUnderscore && !ret.empty()) { ret += '_'; } @@ -1342,7 +1351,7 @@ struct WKTParser::Private { CRSPtr buildCRS(const WKTNodeNNPtr &node); - CoordinateOperationNNPtr buildCoordinateOperation(const WKTNodeNNPtr &node); + TransformationNNPtr buildCoordinateOperation(const WKTNodeNNPtr &node); ConcatenatedOperationNNPtr buildConcatenatedOperation(const WKTNodeNNPtr &node); @@ -2940,7 +2949,7 @@ WKTParser::Private::buildConversion(const WKTNodeNNPtr &node, // --------------------------------------------------------------------------- -CoordinateOperationNNPtr +TransformationNNPtr WKTParser::Private::buildCoordinateOperation(const WKTNodeNNPtr &node) { const auto *nodeP = node->GP(); auto &methodNode = nodeP->lookForChild(WKTConstants::METHOD); @@ -2991,11 +3000,10 @@ WKTParser::Private::buildCoordinateOperation(const WKTNodeNNPtr &node) { stripQuotes(accuracyNode->GP()->children()[0]))); } - return util::nn_static_pointer_cast<CoordinateOperation>( - Transformation::create(buildProperties(node), NN_NO_CHECK(sourceCRS), - NN_NO_CHECK(targetCRS), interpolationCRS, - buildProperties(methodNode), parameters, values, - accuracies)); + return Transformation::create(buildProperties(node), NN_NO_CHECK(sourceCRS), + NN_NO_CHECK(targetCRS), interpolationCRS, + buildProperties(methodNode), parameters, + values, accuracies); } // --------------------------------------------------------------------------- @@ -3257,7 +3265,10 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } return Conversion::create( - PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), + PropertyMap().set(IdentifiedObject::NAME_KEY, + esriProjectionName == "Gauss_Kruger" + ? "unnnamed (Gauss Kruger)" + : "unnamed"), propertiesMethod, parameters, values) ->identify(); } @@ -4307,16 +4318,31 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) { } if (ci_equal(name, WKTConstants::COORDINATEOPERATION)) { - return util::nn_static_pointer_cast<BaseObject>( - buildCoordinateOperation(node)); + auto transf = buildCoordinateOperation(node); + + const char *prefixes[] = { + "PROJ-based operation method: ", + "PROJ-based operation method (approximate): "}; + for (const char *prefix : prefixes) { + if (starts_with(transf->method()->nameStr(), prefix)) { + auto projString = + transf->method()->nameStr().substr(strlen(prefix)); + return util::nn_static_pointer_cast<BaseObject>( + PROJBasedOperation::create( + PropertyMap(), projString, transf->sourceCRS(), + transf->targetCRS(), + transf->coordinateOperationAccuracies())); + } + } + + return util::nn_static_pointer_cast<BaseObject>(transf); } if (ci_equal(name, WKTConstants::CONVERSION)) { auto conv = buildConversion(node, UnitOfMeasure::METRE, UnitOfMeasure::DEGREE); - if (conv->nameStr() == "PROJ-based coordinate operation" && - starts_with(conv->method()->nameStr(), + if (starts_with(conv->method()->nameStr(), "PROJ-based operation method: ")) { auto projString = conv->method()->nameStr().substr( strlen("PROJ-based operation method: ")); |
