aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-07-06 02:03:50 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-07-06 02:27:46 +0200
commit17f0b0b3bc65ffba39bf6f22a12b2cc7fcb9bafd (patch)
tree5993d701145e2117fb8598faa186312b98d54f00 /src/iso19111
parent1da55c8be619a21153845607a553c9d1206bc792 (diff)
downloadPROJ-17f0b0b3bc65ffba39bf6f22a12b2cc7fcb9bafd.tar.gz
PROJ-17f0b0b3bc65ffba39bf6f22a12b2cc7fcb9bafd.zip
Proof-of-concept of JSON export limited to PrimeMeridian (refs #1545)
Diffstat (limited to 'src/iso19111')
-rw-r--r--src/iso19111/common.cpp65
-rw-r--r--src/iso19111/datum.cpp35
-rw-r--r--src/iso19111/io.cpp87
-rw-r--r--src/iso19111/metadata.cpp20
4 files changed, 207 insertions, 0 deletions
diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp
index d46da0da..f2a51032 100644
--- a/src/iso19111/common.cpp
+++ b/src/iso19111/common.cpp
@@ -236,6 +236,54 @@ void UnitOfMeasure::_exportToWKT(
}
formatter->endNode();
}
+
+// ---------------------------------------------------------------------------
+
+void UnitOfMeasure::_exportToJSON(
+ JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto &writer = formatter->writer();
+ PROJ::CPLJSonStreamingWriter::ObjectContext objContext(writer);
+ writer.AddObjKey("type");
+ const auto l_type = type();
+ if (l_type == Type::LINEAR) {
+ writer.Add("LinearUnit");
+ } else if (l_type == Type::ANGULAR) {
+ writer.Add("AngularUnit");
+ } else if (l_type == Type::SCALE) {
+ writer.Add("ScaleUnit");
+ } else if (l_type == Type::TIME) {
+ writer.Add("TimeUnit");
+ } else if (l_type == Type::PARAMETRIC) {
+ writer.Add("ParametericUnit");
+ } else {
+ writer.Add("Unit");
+ }
+
+ writer.AddObjKey("name");
+ const auto &l_name = name();
+ writer.Add(l_name);
+
+ const auto &factor = conversionToSI();
+ writer.AddObjKey("conversion_factor");
+ writer.Add(factor, 15);
+
+ const auto &l_codeSpace = codeSpace();
+ if (!l_codeSpace.empty() && formatter->outputId()) {
+ writer.AddObjKey("id");
+ PROJ::CPLJSonStreamingWriter::ObjectContext idContext(writer);
+ writer.AddObjKey("authority");
+ writer.Add(l_codeSpace);
+ writer.AddObjKey("code");
+ const auto &l_code = code();
+ try {
+ writer.Add(std::stoi(l_code));
+ } catch (const std::exception &) {
+ writer.Add(l_code);
+ }
+ }
+}
+
//! @endcond
// ---------------------------------------------------------------------------
@@ -815,6 +863,23 @@ void IdentifiedObject::formatRemarks(WKTFormatter *formatter) const {
// ---------------------------------------------------------------------------
+void IdentifiedObject::formatID(JSONFormatter *formatter) const {
+ const auto &ids(identifiers());
+ auto &writer = formatter->writer();
+ if (ids.size() == 1) {
+ writer.AddObjKey("id");
+ ids.front()->_exportToJSON(formatter);
+ } else if (!ids.empty()) {
+ writer.AddObjKey("ids");
+ PROJ::CPLJSonStreamingWriter::ArrayContext arrayContext(writer);
+ for (const auto &id : ids) {
+ id->_exportToJSON(formatter);
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
bool IdentifiedObject::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index bf3092c1..6ba219d4 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -348,6 +348,41 @@ void PrimeMeridian::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void PrimeMeridian::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto &writer = formatter->writer();
+ PROJ::CPLJSonStreamingWriter::ObjectContext objectContext(writer);
+
+ writer.AddObjKey("type");
+ writer.Add("PrimeMeridian");
+
+ writer.AddObjKey("name");
+ std::string l_name =
+ name()->description().has_value() ? nameStr() : "Greenwich";
+ writer.Add(l_name);
+
+ const auto &l_long = longitude();
+ writer.AddObjKey("longitude");
+ {
+ PROJ::CPLJSonStreamingWriter::ObjectContext longitudeContext(writer);
+ writer.AddObjKey("value");
+ writer.Add(l_long.value(), 15);
+
+ const auto &unit = l_long.unit();
+ writer.AddObjKey("unit");
+ unit._exportToJSON(formatter);
+ }
+
+ if (formatter->outputId()) {
+ formatID(formatter);
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
std::string
PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) {
const double valRad = angle.getSIValue();
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index 0db97d0b..0c9f8a0c 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -60,6 +60,7 @@
#include "proj_constants.h"
+#include "proj_json_streaming_writer.hpp"
#include "wkt1_parser.h"
#include "wkt2_parser.h"
@@ -8016,5 +8017,91 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
nullptr, nullptr, {});
}
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+struct JSONFormatter::Private {
+ PROJ::CPLJSonStreamingWriter writer_{nullptr, nullptr};
+ DatabaseContextPtr dbContext_{};
+ std::string result_{};
+};
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+/** \brief Constructs a new formatter.
+ *
+ * A formatter can be used only once (its internal state is mutated)
+ *
+ * @return new formatter.
+ */
+JSONFormatterNNPtr JSONFormatter::create( // cppcheck-suppress passedByValue
+ DatabaseContextPtr dbContext) {
+ auto ret = NN_NO_CHECK(JSONFormatter::make_unique<JSONFormatter>());
+ ret->d->dbContext_ = dbContext;
+ return ret;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Whether to use multi line output or not. */
+JSONFormatter &JSONFormatter::setMultiLine(bool multiLine) noexcept {
+ d->writer_.SetPrettyFormatting(multiLine);
+ return *this;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Set number of spaces for each indentation level (defaults to 4).
+ */
+JSONFormatter &JSONFormatter::setIndentationWidth(int width) noexcept {
+ d->writer_.SetIndentationSize(width);
+ return *this;
+}
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+
+JSONFormatter::JSONFormatter() : d(internal::make_unique<Private>()) {}
+
+// ---------------------------------------------------------------------------
+
+JSONFormatter::~JSONFormatter() = default;
+
+// ---------------------------------------------------------------------------
+
+PROJ::CPLJSonStreamingWriter &JSONFormatter::writer() const {
+ return d->writer_;
+}
+
+// ---------------------------------------------------------------------------
+
+bool JSONFormatter::outputId() const { return true; }
+
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return the serialized JSON.
+ */
+const std::string &JSONFormatter::toString() const {
+ return d->writer_.GetString();
+}
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+IJSONExportable::~IJSONExportable() = default;
+
+// ---------------------------------------------------------------------------
+
+std::string IJSONExportable::exportToJSON(JSONFormatter *formatter) const {
+ _exportToJSON(formatter);
+ return formatter->toString();
+}
+
+//! @endcond
+
} // namespace io
NS_PROJ_END
diff --git a/src/iso19111/metadata.cpp b/src/iso19111/metadata.cpp
index 3725b072..761b909b 100644
--- a/src/iso19111/metadata.cpp
+++ b/src/iso19111/metadata.cpp
@@ -1088,6 +1088,26 @@ void Identifier::_exportToWKT(WKTFormatter *formatter) const {
}
}
}
+
+// ---------------------------------------------------------------------------
+
+void Identifier::_exportToJSON(JSONFormatter *formatter) const {
+ const std::string &l_code = code();
+ const std::string &l_codeSpace = *codeSpace();
+ if (!l_codeSpace.empty() && !l_code.empty()) {
+ auto &writer = formatter->writer();
+ PROJ::CPLJSonStreamingWriter::ObjectContext objContext(writer);
+ writer.AddObjKey("authority");
+ writer.Add(l_codeSpace);
+ writer.AddObjKey("code");
+ try {
+ writer.Add(std::stoi(l_code));
+ } catch (const std::exception &) {
+ writer.Add(l_code);
+ }
+ }
+}
+
//! @endcond
// ---------------------------------------------------------------------------