aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-01-16 17:17:54 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-01-16 17:18:30 +0100
commit6d2af0904652baba69ec81261c914e9b68221dac (patch)
tree289e2af7e0cb472d633e2357804e696714d1557b
parent15bbaa50ae6e5779462bb921a5f50126a2f2f252 (diff)
downloadPROJ-6d2af0904652baba69ec81261c914e9b68221dac.tar.gz
PROJ-6d2af0904652baba69ec81261c914e9b68221dac.zip
PROJBasedOperation: write it as a conformant CONVERSION WKT, and make it parsed appropriately on the reading side
-rw-r--r--include/proj/internal/coordinateoperation_internal.hpp4
-rw-r--r--src/iso19111/coordinateoperation.cpp50
-rw-r--r--src/iso19111/io.cpp16
-rw-r--r--test/unit/test_io.cpp14
-rw-r--r--test/unit/test_operation.cpp6
5 files changed, 47 insertions, 43 deletions
diff --git a/include/proj/internal/coordinateoperation_internal.hpp b/include/proj/internal/coordinateoperation_internal.hpp
index d8c091d0..8428b8bf 100644
--- a/include/proj/internal/coordinateoperation_internal.hpp
+++ b/include/proj/internal/coordinateoperation_internal.hpp
@@ -252,8 +252,7 @@ class PROJBasedOperation : public SingleOperation {
gridsNeeded(const io::DatabaseContextPtr &databaseContext) const override;
protected:
- PROJBasedOperation(const OperationMethodNNPtr &methodIn,
- const std::vector<GeneralParameterValueNNPtr> &values);
+ PROJBasedOperation(const OperationMethodNNPtr &methodIn);
void _exportToPROJString(io::PROJStringFormatter *formatter)
const override; // throw(FormattingException)
@@ -261,6 +260,7 @@ class PROJBasedOperation : public SingleOperation {
INLINED_MAKE_SHARED
private:
+ std::string projString_{};
io::IPROJStringExportablePtr projStringExportable_{};
bool inverse_ = false;
};
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 47f10392..cc212314 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -11788,33 +11788,22 @@ PROJBasedOperation::~PROJBasedOperation() = default;
// ---------------------------------------------------------------------------
-PROJBasedOperation::PROJBasedOperation(
- const OperationMethodNNPtr &methodIn,
- const std::vector<GeneralParameterValueNNPtr> &values)
- : SingleOperation(methodIn) {
- setParameterValues(values);
-}
+PROJBasedOperation::PROJBasedOperation(const OperationMethodNNPtr &methodIn)
+ : SingleOperation(methodIn) {}
// ---------------------------------------------------------------------------
-static const std::string PROJSTRING_PARAMETER_NAME("PROJ string");
-
PROJBasedOperationNNPtr PROJBasedOperation::create(
const util::PropertyMap &properties, const std::string &PROJString,
const crs::CRSPtr &sourceCRS, const crs::CRSPtr &targetCRS,
const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies) {
- auto parameter = OperationParameter::create(util::PropertyMap().set(
- common::IdentifiedObject::NAME_KEY, PROJSTRING_PARAMETER_NAME));
auto method = OperationMethod::create(
util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
- "PROJ-based operation method"),
- std::vector<OperationParameterNNPtr>{parameter});
- std::vector<GeneralParameterValueNNPtr> values;
- values.push_back(OperationParameterValue::create(
- parameter, ParameterValue::create(PROJString)));
- auto op =
- PROJBasedOperation::nn_make_shared<PROJBasedOperation>(method, values);
+ "PROJ-based operation method: " + PROJString),
+ std::vector<GeneralOperationParameterNNPtr>{});
+ auto op = PROJBasedOperation::nn_make_shared<PROJBasedOperation>(method);
op->assignSelf(op);
+ op->projString_ = PROJString;
if (sourceCRS && targetCRS) {
op->setCRSs(NN_NO_CHECK(sourceCRS), NN_NO_CHECK(targetCRS), nullptr);
}
@@ -11826,21 +11815,11 @@ PROJBasedOperationNNPtr PROJBasedOperation::create(
// ---------------------------------------------------------------------------
-static const std::string
- APPROX_PROJSTRING_PARAMETER_NAME("(Approximte) PROJ string");
-
PROJBasedOperationNNPtr PROJBasedOperation::create(
const util::PropertyMap &properties,
const io::IPROJStringExportableNNPtr &projExportable, bool inverse,
const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies) {
- auto parameter = OperationParameter::create(util::PropertyMap().set(
- common::IdentifiedObject::NAME_KEY, APPROX_PROJSTRING_PARAMETER_NAME));
- auto method = OperationMethod::create(
- util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
- "PROJ-based operation method"),
- std::vector<OperationParameterNNPtr>{parameter});
- std::vector<GeneralParameterValueNNPtr> values;
auto formatter = io::PROJStringFormatter::create();
if (inverse) {
@@ -11852,11 +11831,14 @@ PROJBasedOperationNNPtr PROJBasedOperation::create(
}
auto projString = formatter->toString();
- values.push_back(OperationParameterValue::create(
- parameter, ParameterValue::create(projString)));
- auto op =
- PROJBasedOperation::nn_make_shared<PROJBasedOperation>(method, values);
+ auto method = OperationMethod::create(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY,
+ "PROJ-based operation method (approximate) : " +
+ projString),
+ std::vector<GeneralOperationParameterNNPtr>{});
+ auto op = PROJBasedOperation::nn_make_shared<PROJBasedOperation>(method);
op->assignSelf(op);
+ op->projString_ = projString;
op->setCRSs(sourceCRS, targetCRS, nullptr);
op->setProperties(
addDefaultNameIfNeeded(properties, "PROJ-based coordinate operation"));
@@ -11882,8 +11864,7 @@ CoordinateOperationNNPtr PROJBasedOperation::inverse() const {
auto formatter = io::PROJStringFormatter::create();
formatter->startInversion();
try {
- formatter->ingestPROJString(
- parameterValue(PROJSTRING_PARAMETER_NAME)->stringValue());
+ formatter->ingestPROJString(projString_);
} catch (const io::ParsingException &e) {
throw util::UnsupportedOperationException(
std::string("PROJBasedOperation::inverse() failed: ") + e.what());
@@ -11938,8 +11919,7 @@ void PROJBasedOperation::_exportToPROJString(
}
try {
- formatter->ingestPROJString(
- parameterValue(PROJSTRING_PARAMETER_NAME)->stringValue());
+ formatter->ingestPROJString(projString_);
} catch (const io::ParsingException &e) {
throw io::FormattingException(
std::string("PROJBasedOperation::exportToPROJString() failed: ") +
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 13a8f236..5be02ffe 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4252,8 +4252,20 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) {
}
if (ci_equal(name, WKTConstants::CONVERSION)) {
- return util::nn_static_pointer_cast<BaseObject>(
- buildConversion(node, UnitOfMeasure::METRE, UnitOfMeasure::DEGREE));
+ auto conv =
+ buildConversion(node, UnitOfMeasure::METRE, UnitOfMeasure::DEGREE);
+
+ if (conv->nameStr() == "PROJ-based coordinate operation" &&
+ starts_with(conv->method()->nameStr(),
+ "PROJ-based operation method: ")) {
+ auto projString = conv->method()->nameStr().substr(
+ strlen("PROJ-based operation method: "));
+ return util::nn_static_pointer_cast<BaseObject>(
+ PROJBasedOperation::create(PropertyMap(), projString, nullptr,
+ nullptr, {}));
+ }
+
+ return util::nn_static_pointer_cast<BaseObject>(conv);
}
if (ci_equal(name, WKTConstants::CONCATENATEDOPERATION)) {
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 2b5eeffc..43b74fd8 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -2280,6 +2280,20 @@ TEST(wkt_parse, COORDINATEOPERATION) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, conversion_proj_based) {
+
+ auto wkt = "CONVERSION[\"PROJ-based coordinate operation\",\n"
+ " METHOD[\"PROJ-based operation method: +proj=merc\"]]";
+
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto transf = nn_dynamic_pointer_cast<SingleOperation>(obj);
+ ASSERT_TRUE(transf != nullptr);
+ EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=merc");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, CONCATENATEDOPERATION) {
auto transf_1 = Transformation::create(
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index d3f05548..bdadd830 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -4099,8 +4099,7 @@ TEST(operation, PROJ_based) {
EXPECT_EQ(conv->exportToWKT(WKTFormatter::create().get()),
"CONVERSION[\"PROJ-based coordinate operation\",\n"
- " METHOD[\"PROJ-based operation method\"],\n"
- " PARAMETER[\"PROJ string\",\"+proj=merc\"]]");
+ " METHOD[\"PROJ-based operation method: +proj=merc\"]]");
EXPECT_EQ(conv->inverse()->exportToPROJString(
PROJStringFormatter::create().get()),
@@ -4135,8 +4134,7 @@ TEST(operation, PROJ_based_empty) {
EXPECT_EQ(conv->exportToWKT(WKTFormatter::create().get()),
"CONVERSION[\"PROJ-based coordinate operation\",\n"
- " METHOD[\"PROJ-based operation method\"],\n"
- " PARAMETER[\"PROJ string\",\"\"]]");
+ " METHOD[\"PROJ-based operation method: \"]]");
EXPECT_THROW(
conv->exportToWKT(