aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@mines-paris.org>2019-02-21 17:42:41 +0100
committerGitHub <noreply@github.com>2019-02-21 17:42:41 +0100
commitbbf31d0e1052a40269547d0dec5d63a7e0534ccc (patch)
treeb48ac00785b9107072de08b2d591e62c3143fe32 /src
parentf5a78058c9d8e633e34e6b0979c79cb7d17b1a93 (diff)
parent287230f86d89a26574c777bb5e5b498084a84897 (diff)
downloadPROJ-bbf31d0e1052a40269547d0dec5d63a7e0534ccc.tar.gz
PROJ-bbf31d0e1052a40269547d0dec5d63a7e0534ccc.zip
Merge pull request #1280 from rouault/SWEN17_RH2000_gtx
proj.db: add missing custom entries for vertical transform and fix a few wrong ones
Diffstat (limited to 'src')
-rw-r--r--src/apps/projinfo.cpp49
-rw-r--r--src/iso19111/coordinateoperation.cpp103
2 files changed, 124 insertions, 28 deletions
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp
index 094587e2..7e401887 100644
--- a/src/apps/projinfo.cpp
+++ b/src/apps/projinfo.cpp
@@ -464,11 +464,42 @@ static void outputObject(
}
}
}
+
+ auto op = dynamic_cast<CoordinateOperation *>(obj.get());
+ if (op && dbContext && getenv("PROJINFO_NO_GRID_CHECK") == nullptr) {
+ try {
+ auto setGrids = op->gridsNeeded(dbContext);
+ bool firstWarning = true;
+ for (const auto &grid : setGrids) {
+ if (!grid.available) {
+ if (firstWarning) {
+ std::cout << std::endl;
+ firstWarning = false;
+ }
+ std::cout << "Grid " << grid.shortName
+ << " needed but not found on the system.";
+ if (!grid.packageName.empty()) {
+ std::cout << " Can be obtained from the "
+ << grid.packageName << " package";
+ if (!grid.url.empty()) {
+ std::cout << " at " << grid.url;
+ }
+ } else if (!grid.url.empty()) {
+ std::cout << " Can be obtained at " << grid.url;
+ }
+ std::cout << std::endl;
+ }
+ }
+ } catch (const std::exception &e) {
+ std::cerr << "Error in gridsNeeded(): " << e.what() << std::endl;
+ }
+ }
}
// ---------------------------------------------------------------------------
-static void outputOperationSummary(const CoordinateOperationNNPtr &op) {
+static void outputOperationSummary(const CoordinateOperationNNPtr &op,
+ const DatabaseContextPtr &dbContext) {
auto ids = op->identifiers();
if (!ids.empty()) {
std::cout << *(ids[0]->codeSpace()) << ":" << ids[0]->code();
@@ -512,6 +543,18 @@ static void outputOperationSummary(const CoordinateOperationNNPtr &op) {
std::cout << ", has ballpark transformation";
}
+ if (dbContext && getenv("PROJINFO_NO_GRID_CHECK") == nullptr) {
+ try {
+ auto setGrids = op->gridsNeeded(dbContext);
+ for (const auto &grid : setGrids) {
+ if (!grid.available) {
+ std::cout << ", at least one grid missing";
+ break;
+ }
+ }
+ } catch (const std::exception &) {
+ }
+ }
std::cout << std::endl;
}
@@ -598,7 +641,7 @@ static void outputOperations(
}
if (summary) {
for (const auto &op : list) {
- outputOperationSummary(op);
+ outputOperationSummary(op, dbContext);
}
} else {
bool first = true;
@@ -613,7 +656,7 @@ static void outputOperations(
"\xC2\xB0"
<< (i + 1) << ":" << std::endl
<< std::endl;
- outputOperationSummary(op);
+ outputOperationSummary(op, dbContext);
std::cout << std::endl;
outputObject(dbContext, op, allowUseIntermediateCRS, outputOpt);
}
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 224b19ef..7b0adc6f 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -106,6 +106,7 @@ constexpr double UTM_SOUTH_FALSE_NORTHING = 10000000.0;
static const std::string INVERSE_OF = "Inverse of ";
static const char *BALLPARK_GEOCENTRIC_TRANSLATION =
"Ballpark geocentric translation";
+static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset";
static const char *BALLPARK_GEOGRAPHIC_OFFSET = "Ballpark geographic offset";
static const char *BALLPARK_VERTICAL_TRANSFORMATION_PREFIX =
" (ballpark vertical transformation";
@@ -7189,6 +7190,8 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom,
opType = BALLPARK_GEOCENTRIC_TRANSLATION;
} else if (starts_with(forwardName, BALLPARK_GEOGRAPHIC_OFFSET)) {
opType = BALLPARK_GEOGRAPHIC_OFFSET;
+ } else if (starts_with(forwardName, NULL_GEOGRAPHIC_OFFSET)) {
+ opType = NULL_GEOGRAPHIC_OFFSET;
} else if (dynamic_cast<const Transformation *>(op) ||
starts_with(forwardName, "Transformation from ")) {
opType = "Transformation";
@@ -10182,6 +10185,8 @@ struct FilterResults {
const bool isNullTransformation =
op->nameStr().find(BALLPARK_GEOGRAPHIC_OFFSET) !=
std::string::npos ||
+ op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) !=
+ std::string::npos ||
op->nameStr().find(BALLPARK_GEOCENTRIC_TRANSLATION) !=
std::string::npos;
map[op.get()] = PrecomputedOpCharacteristics(
@@ -10206,6 +10211,7 @@ struct FilterResults {
if (hasOpThatContainsAreaOfInterest && res.size() > 1) {
const std::string &name = res.back()->nameStr();
if (name.find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos ||
+ name.find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos ||
name.find(BALLPARK_GEOCENTRIC_TRANSLATION) !=
std::string::npos) {
std::vector<CoordinateOperationNNPtr> resTemp;
@@ -10622,7 +10628,18 @@ static std::vector<CoordinateOperationNNPtr> findsOpsInRegistryWithIntermediate(
static TransformationNNPtr
createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS,
const crs::CRSNNPtr &targetCRS) {
- std::string name(BALLPARK_GEOGRAPHIC_OFFSET);
+
+ const crs::GeographicCRS *geogSrc =
+ dynamic_cast<const crs::GeographicCRS *>(sourceCRS.get());
+ const crs::GeographicCRS *geogDst =
+ dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
+ const bool isSameDatum =
+ geogSrc && geogDst && geogSrc->datum() && geogDst->datum() &&
+ geogSrc->datum()->_isEquivalentTo(
+ geogDst->datum().get(), util::IComparable::Criterion::EQUIVALENT);
+
+ std::string name(isSameDatum ? NULL_GEOGRAPHIC_OFFSET
+ : BALLPARK_GEOGRAPHIC_OFFSET);
name += " from ";
name += sourceCRS->nameStr();
name += " to ";
@@ -10641,6 +10658,12 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS,
sameExtent ? NN_NO_CHECK(sourceCRSExtent)
: metadata::Extent::WORLD);
const common::Angle angle0(0);
+
+ std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
+ if (isSameDatum) {
+ accuracies.emplace_back(metadata::PositionalAccuracy::create("0"));
+ }
+
if (dynamic_cast<const crs::SingleCRS *>(sourceCRS.get())
->coordinateSystem()
->axisList()
@@ -10650,10 +10673,11 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS,
->axisList()
.size() == 3) {
return Transformation::createGeographic3DOffsets(
- map, sourceCRS, targetCRS, angle0, angle0, common::Length(0), {});
+ map, sourceCRS, targetCRS, angle0, angle0, common::Length(0),
+ accuracies);
} else {
return Transformation::createGeographic2DOffsets(
- map, sourceCRS, targetCRS, angle0, angle0, {});
+ map, sourceCRS, targetCRS, angle0, angle0, accuracies);
}
}
//! @endcond
@@ -10829,30 +10853,58 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased(
auto exportable = util::nn_make_shared<MyPROJStringExportableHorizVertical>(
horizTransform, verticalTransform, geogDst);
- bool dummy = false;
- auto ops = std::vector<CoordinateOperationNNPtr>{horizTransform,
- verticalTransform};
- auto extent = getExtent(ops, true, dummy);
- auto properties = util::PropertyMap();
- properties.set(common::IdentifiedObject::NAME_KEY,
- computeConcatenatedName(ops));
-
- if (extent) {
- properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
- NN_NO_CHECK(extent));
+ bool horizTransformIsNoOp = horizTransform->sourceCRS()->_isEquivalentTo(
+ horizTransform->targetCRS().get());
+ if (!horizTransformIsNoOp) {
+ const crs::GeographicCRS *geogSrc =
+ dynamic_cast<const crs::GeographicCRS *>(
+ horizTransform->sourceCRS().get());
+ if (geogSrc) {
+ horizTransformIsNoOp =
+ geogSrc->is2DPartOf3D(NN_NO_CHECK(geogDst.get()));
+ }
}
- std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
- const double accuracy = getAccuracy(ops);
- if (accuracy >= 0.0) {
- accuracies.emplace_back(
- metadata::PositionalAccuracy::create(toString(accuracy)));
- }
+ if (horizTransformIsNoOp) {
+ auto properties = util::PropertyMap();
+ properties.set(common::IdentifiedObject::NAME_KEY,
+ verticalTransform->nameStr());
+ bool dummy = false;
+ auto extent = getExtent(verticalTransform, true, dummy);
+ if (extent) {
+ properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ NN_NO_CHECK(extent));
+ }
+ return createPROJBased(
+ properties, exportable, sourceCRS, targetCRS,
+ verticalTransform->coordinateOperationAccuracies(),
+ verticalTransform->hasBallparkTransformation());
+ } else {
+ bool dummy = false;
+ auto ops = std::vector<CoordinateOperationNNPtr>{horizTransform,
+ verticalTransform};
+ auto extent = getExtent(ops, true, dummy);
+ auto properties = util::PropertyMap();
+ properties.set(common::IdentifiedObject::NAME_KEY,
+ computeConcatenatedName(ops));
- return createPROJBased(properties, exportable, sourceCRS, targetCRS,
- accuracies,
- horizTransform->hasBallparkTransformation() ||
- verticalTransform->hasBallparkTransformation());
+ if (extent) {
+ properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ NN_NO_CHECK(extent));
+ }
+
+ std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
+ const double accuracy = getAccuracy(ops);
+ if (accuracy >= 0.0) {
+ accuracies.emplace_back(
+ metadata::PositionalAccuracy::create(toString(accuracy)));
+ }
+
+ return createPROJBased(
+ properties, exportable, sourceCRS, targetCRS, accuracies,
+ horizTransform->hasBallparkTransformation() ||
+ verticalTransform->hasBallparkTransformation());
+ }
}
// ---------------------------------------------------------------------------
@@ -11147,7 +11199,8 @@ findCandidateGeodCRSForDatum(const io::AuthorityFactoryPtr &authFactory,
static bool isNullTransformation(const std::string &name) {
return starts_with(name, BALLPARK_GEOCENTRIC_TRANSLATION) ||
- starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET);
+ starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET) ||
+ starts_with(name, NULL_GEOGRAPHIC_OFFSET);
}
// ---------------------------------------------------------------------------