aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/common.cpp2
-rw-r--r--src/iso19111/coordinateoperation.cpp88
-rw-r--r--src/iso19111/crs.cpp17
-rw-r--r--src/iso19111/io.cpp40
4 files changed, 123 insertions, 24 deletions
diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp
index 4b947dc9..d46da0da 100644
--- a/src/iso19111/common.cpp
+++ b/src/iso19111/common.cpp
@@ -1073,7 +1073,7 @@ void ObjectUsage::setProperties(
void ObjectUsage::baseExportToWKT(WKTFormatter *formatter) const {
const bool isWKT2 = formatter->version() == WKTFormatter::Version::WKT2;
- if (isWKT2 && formatter->outputId()) {
+ if (isWKT2 && formatter->outputUsage()) {
auto l_domains = domains();
if (!l_domains.empty()) {
if (formatter->use2018Keywords()) {
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 80c1a572..d7f138a4 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -7639,6 +7639,53 @@ void Transformation::_exportToWKT(io::WKTFormatter *formatter) const {
// ---------------------------------------------------------------------------
+static void exportSourceCRSAndTargetCRSToWKT(const CoordinateOperation *co,
+ io::WKTFormatter *formatter) {
+ auto l_sourceCRS = co->sourceCRS();
+ assert(l_sourceCRS);
+ auto l_targetCRS = co->targetCRS();
+ assert(l_targetCRS);
+ const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
+ const bool canExportCRSId =
+ (isWKT2 && formatter->use2018Keywords() &&
+ !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId()));
+
+ const bool hasDomains = !co->domains().empty();
+ if (hasDomains) {
+ formatter->pushDisableUsage();
+ }
+
+ formatter->startNode(io::WKTConstants::SOURCECRS, false);
+ if (canExportCRSId && !l_sourceCRS->identifiers().empty()) {
+ // fake that top node has no id, so that the sourceCRS id is
+ // considered
+ formatter->pushHasId(false);
+ l_sourceCRS->_exportToWKT(formatter);
+ formatter->popHasId();
+ } else {
+ l_sourceCRS->_exportToWKT(formatter);
+ }
+ formatter->endNode();
+
+ formatter->startNode(io::WKTConstants::TARGETCRS, false);
+ if (canExportCRSId && !l_targetCRS->identifiers().empty()) {
+ // fake that top node has no id, so that the targetCRS id is
+ // considered
+ formatter->pushHasId(false);
+ l_targetCRS->_exportToWKT(formatter);
+ formatter->popHasId();
+ } else {
+ l_targetCRS->_exportToWKT(formatter);
+ }
+ formatter->endNode();
+
+ if (hasDomains) {
+ formatter->popDisableUsage();
+ }
+}
+
+// ---------------------------------------------------------------------------
+
void SingleOperation::exportTransformationToWKT(
io::WKTFormatter *formatter) const {
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
@@ -7647,11 +7694,6 @@ void SingleOperation::exportTransformationToWKT(
"Transformation can only be exported to WKT2");
}
- auto l_sourceCRS = sourceCRS();
- assert(l_sourceCRS);
- auto l_targetCRS = targetCRS();
- assert(l_targetCRS);
-
if (formatter->abridgedTransformation()) {
formatter->startNode(io::WKTConstants::ABRIDGEDTRANSFORMATION,
!identifiers().empty());
@@ -7672,13 +7714,7 @@ void SingleOperation::exportTransformationToWKT(
}
if (!formatter->abridgedTransformation()) {
- formatter->startNode(io::WKTConstants::SOURCECRS, false);
- l_sourceCRS->_exportToWKT(formatter);
- formatter->endNode();
-
- formatter->startNode(io::WKTConstants::TARGETCRS, false);
- l_targetCRS->_exportToWKT(formatter);
- formatter->endNode();
+ exportSourceCRSAndTargetCRSToWKT(this, formatter);
}
method()->_exportToWKT(formatter);
@@ -9337,20 +9373,34 @@ void ConcatenatedOperation::_exportToWKT(io::WKTFormatter *formatter) const {
}
}
- formatter->startNode(io::WKTConstants::SOURCECRS, false);
- sourceCRS()->_exportToWKT(formatter);
- formatter->endNode();
+ exportSourceCRSAndTargetCRSToWKT(this, formatter);
- formatter->startNode(io::WKTConstants::TARGETCRS, false);
- targetCRS()->_exportToWKT(formatter);
- formatter->endNode();
+ const bool canExportOperationId =
+ !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId());
+
+ const bool hasDomains = !domains().empty();
+ if (hasDomains) {
+ formatter->pushDisableUsage();
+ }
for (const auto &operation : operations()) {
formatter->startNode(io::WKTConstants::STEP, false);
- operation->_exportToWKT(formatter);
+ if (canExportOperationId && !operation->identifiers().empty()) {
+ // fake that top node has no id, so that the operation id is
+ // considered
+ formatter->pushHasId(false);
+ operation->_exportToWKT(formatter);
+ formatter->popHasId();
+ } else {
+ operation->_exportToWKT(formatter);
+ }
formatter->endNode();
}
+ if (hasDomains) {
+ formatter->popDisableUsage();
+ }
+
ObjectUsage::baseExportToWKT(formatter);
formatter->endNode();
}
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 9688883d..2dc6b3bf 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -2421,16 +2421,21 @@ void DerivedCRS::setDerivingConversionCRS() {
// ---------------------------------------------------------------------------
-void DerivedCRS::baseExportToWKT(io::WKTFormatter *&formatter,
+void DerivedCRS::baseExportToWKT(io::WKTFormatter *formatter,
const std::string &keyword,
const std::string &baseKeyword) const {
formatter->startNode(keyword, !identifiers().empty());
formatter->addQuotedString(nameStr());
const auto &l_baseCRS = d->baseCRS_;
- formatter->startNode(baseKeyword, !l_baseCRS->identifiers().empty());
+ formatter->startNode(baseKeyword, formatter->use2018Keywords() &&
+ !l_baseCRS->identifiers().empty());
formatter->addQuotedString(l_baseCRS->nameStr());
l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter);
+ if (formatter->use2018Keywords() &&
+ !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) {
+ l_baseCRS->formatID(formatter);
+ }
formatter->endNode();
formatter->setUseDerivingConversion(true);
@@ -2658,7 +2663,7 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
dynamic_cast<const GeographicCRS *>(l_baseCRS.get()))
? io::WKTConstants::BASEGEOGCRS
: io::WKTConstants::BASEGEODCRS,
- !l_baseCRS->identifiers().empty());
+ formatter->use2018Keywords() && !l_baseCRS->identifiers().empty());
formatter->addQuotedString(l_baseCRS->nameStr());
l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter);
// insert ellipsoidal cs unit when the units of the map
@@ -2669,6 +2674,10 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
geodeticCRSAxisList[0]->unit()._exportToWKT(formatter);
}
l_baseCRS->primeMeridian()->_exportToWKT(formatter);
+ if (formatter->use2018Keywords() &&
+ !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) {
+ l_baseCRS->formatID(formatter);
+ }
formatter->endNode();
} else {
const auto oldAxisOutputRule = formatter->outputAxis();
@@ -4848,7 +4857,7 @@ DerivedCRSTemplate<DerivedCRSTraits>::create(
// ---------------------------------------------------------------------------
-static void DerivedCRSTemplateCheckExportToWKT(io::WKTFormatter *&formatter,
+static void DerivedCRSTemplateCheckExportToWKT(io::WKTFormatter *formatter,
const std::string &crsName,
bool wkt2_2018_only) {
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 220ee967..578234b4 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -141,6 +141,7 @@ struct WKTFormatter::Private {
std::vector<bool> stackHasChild_{};
std::vector<bool> stackHasId_{false};
std::vector<bool> stackEmptyKeyword_{};
+ std::vector<bool> stackDisableUsage_{};
std::vector<bool> outputUnitStack_{true};
std::vector<bool> outputIdStack_{true};
std::vector<UnitOfMeasureNNPtr> axisLinearUnitStack_{
@@ -272,6 +273,11 @@ const std::string &WKTFormatter::toString() const {
if (d->outputUnitStack_.size() != 1)
throw FormattingException(
"Unbalanced pushOutputUnit() / popOutputUnit()");
+ if (d->stackHasId_.size() != 1)
+ throw FormattingException("Unbalanced pushHasId() / popHasId()");
+ if (!d->stackDisableUsage_.empty())
+ throw FormattingException(
+ "Unbalanced pushDisableUsage() / popDisableUsage()");
return d->result_;
}
@@ -556,6 +562,28 @@ bool WKTFormatter::outputId() const {
// ---------------------------------------------------------------------------
+void WKTFormatter::pushHasId(bool hasId) { d->stackHasId_.push_back(hasId); }
+
+// ---------------------------------------------------------------------------
+
+void WKTFormatter::popHasId() { d->stackHasId_.pop_back(); }
+
+// ---------------------------------------------------------------------------
+
+void WKTFormatter::pushDisableUsage() { d->stackDisableUsage_.push_back(true); }
+
+// ---------------------------------------------------------------------------
+
+void WKTFormatter::popDisableUsage() { d->stackDisableUsage_.pop_back(); }
+
+// ---------------------------------------------------------------------------
+
+bool WKTFormatter::outputUsage() const {
+ return outputId() && d->stackDisableUsage_.empty();
+}
+
+// ---------------------------------------------------------------------------
+
void WKTFormatter::pushAxisLinearUnit(const UnitOfMeasureNNPtr &unit) {
d->axisLinearUnitStack_.push_back(unit);
}
@@ -634,6 +662,18 @@ bool WKTFormatter::primeMeridianInDegree() const {
// ---------------------------------------------------------------------------
+bool WKTFormatter::idOnTopLevelOnly() const {
+ return d->params_.idOnTopLevelOnly_;
+}
+
+// ---------------------------------------------------------------------------
+
+bool WKTFormatter::topLevelHasId() const {
+ return d->stackHasId_.size() >= 2 && d->stackHasId_[1];
+}
+
+// ---------------------------------------------------------------------------
+
WKTFormatter::Version WKTFormatter::version() const {
return d->params_.version_;
}