aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-10-10 15:38:54 +0200
committerGitHub <noreply@github.com>2020-10-10 15:38:54 +0200
commit9751f31ca9aa42d075421b038f93fe1b1640ffd3 (patch)
treef99750451df364d1410c6e17073d8b513cb6b82e /src/iso19111
parenta5dd7bbb8512a10280001491bd3fecc599fd4eca (diff)
parent5163741254088b7f3fbb651349463cd2942df4f6 (diff)
downloadPROJ-9751f31ca9aa42d075421b038f93fe1b1640ffd3.tar.gz
PROJ-9751f31ca9aa42d075421b038f93fe1b1640ffd3.zip
Merge pull request #2372 from rouault/datum_with_pm
WKT2:2019 import/export: handle DATUM (at top level object) with PRIMEM
Diffstat (limited to 'src/iso19111')
-rw-r--r--src/iso19111/datum.cpp7
-rw-r--r--src/iso19111/io.cpp46
2 files changed, 44 insertions, 9 deletions
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index 83f615e9..fbd4fd2d 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -1300,6 +1300,13 @@ void GeodeticReferenceFrame::_exportToWKT(
}
// the PRIMEM is exported as a child of the CRS
formatter->endNode();
+
+ if (formatter->isAtTopLevel()) {
+ const auto &l_primeMeridian(primeMeridian());
+ if (l_primeMeridian->nameStr() != "Greenwich") {
+ l_primeMeridian->_exportToWKT(formatter);
+ }
+ }
}
//! @endcond
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 16ab22f7..c464b724 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -388,6 +388,12 @@ void WKTFormatter::leave() {
// ---------------------------------------------------------------------------
+bool WKTFormatter::isAtTopLevel() const {
+ return d->level_ == 0 && d->indentLevel_ == 0;
+}
+
+// ---------------------------------------------------------------------------
+
void WKTFormatter::startNode(const std::string &keyword, bool hasId) {
if (!d->stackHasChild_.empty()) {
d->startNewChild();
@@ -4733,13 +4739,7 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) {
return util::nn_static_pointer_cast<BaseObject>(NN_NO_CHECK(crs));
}
- if (ci_equal(name, WKTConstants::DATUM) ||
- ci_equal(name, WKTConstants::GEODETICDATUM) ||
- ci_equal(name, WKTConstants::TRF)) {
- return util::nn_static_pointer_cast<BaseObject>(
- buildGeodeticReferenceFrame(node, PrimeMeridian::GREENWICH,
- null_node));
- }
+ // Datum handled by caller code WKTParser::createFromWKT()
if (ci_equal(name, WKTConstants::ENSEMBLE)) {
return util::nn_static_pointer_cast<BaseObject>(buildDatumEnsemble(
@@ -6441,8 +6441,36 @@ BaseObjectNNPtr createFromUserInput(const std::string &text, PJ_CONTEXT *ctx) {
* @throw ParsingException
*/
BaseObjectNNPtr WKTParser::createFromWKT(const std::string &wkt) {
- WKTNodeNNPtr root = WKTNode::createFrom(wkt);
- auto obj = d->build(root);
+ const auto build = [this, &wkt]() -> BaseObjectNNPtr {
+ size_t indexEnd;
+ WKTNodeNNPtr root = WKTNode::createFrom(wkt, 0, 0, indexEnd);
+ const std::string &name(root->GP()->value());
+ if (ci_equal(name, WKTConstants::DATUM) ||
+ ci_equal(name, WKTConstants::GEODETICDATUM) ||
+ ci_equal(name, WKTConstants::TRF)) {
+
+ auto primeMeridian = PrimeMeridian::GREENWICH;
+ if (indexEnd < wkt.size()) {
+ indexEnd = skipSpace(wkt, indexEnd);
+ if (indexEnd < wkt.size() && wkt[indexEnd] == ',') {
+ ++indexEnd;
+ indexEnd = skipSpace(wkt, indexEnd);
+ if (indexEnd < wkt.size() &&
+ ci_starts_with(wkt.c_str() + indexEnd,
+ WKTConstants::PRIMEM.c_str())) {
+ primeMeridian = d->buildPrimeMeridian(
+ WKTNode::createFrom(wkt, indexEnd + 1, 0, indexEnd),
+ UnitOfMeasure::DEGREE);
+ }
+ }
+ }
+ return d->buildGeodeticReferenceFrame(root, primeMeridian,
+ null_node);
+ }
+ return d->build(root);
+ };
+
+ auto obj = build();
const auto dialect = guessDialect(wkt);
if (dialect == WKTGuessedDialect::WKT1_GDAL ||