aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2019-05-01 18:42:13 +0200
committerGitHub <noreply@github.com>2019-05-01 18:42:13 +0200
commitfc48053092b4b6f496bb983765ebf619a356e257 (patch)
tree2c53161326b766dc41e4733ce6579503fc702384 /src/iso19111
parente168ad31badb6702240174250894a76385da323b (diff)
parenteeda5f7e5fd94a0cdcbf90df1f0b04a090f4c037 (diff)
downloadPROJ-fc48053092b4b6f496bb983765ebf619a356e257.tar.gz
PROJ-fc48053092b4b6f496bb983765ebf619a356e257.zip
Merge branch 'master' into check_exported_symbols
Diffstat (limited to 'src/iso19111')
-rw-r--r--src/iso19111/coordinateoperation.cpp40
-rw-r--r--src/iso19111/factory.cpp43
-rw-r--r--src/iso19111/io.cpp54
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: "));