aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/datum.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-08-20 13:22:01 +0200
committerGitHub <noreply@github.com>2019-08-20 13:22:01 +0200
commit2c9c015a6529548f5a5d448c78bc9b565d751590 (patch)
tree2597c59e8270f1480785c97f7441ee0b295c29b3 /src/iso19111/datum.cpp
parente52fc2aa58504e6f0658da821bdd543d7a39df34 (diff)
parentcad1c5cf61fc00759bf4ad17b0b34f57f4945de6 (diff)
downloadPROJ-2c9c015a6529548f5a5d448c78bc9b565d751590.tar.gz
PROJ-2c9c015a6529548f5a5d448c78bc9b565d751590.zip
Merge pull request #1547 from rouault/json_export
Add CRS JSON export (refs #1545)
Diffstat (limited to 'src/iso19111/datum.cpp')
-rw-r--r--src/iso19111/datum.cpp317
1 files changed, 313 insertions, 4 deletions
diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp
index bf3092c1..65905ca9 100644
--- a/src/iso19111/datum.cpp
+++ b/src/iso19111/datum.cpp
@@ -93,6 +93,9 @@ struct Datum::Private {
// cppcheck-suppress functionStatic
void exportAnchorDefinition(io::WKTFormatter *formatter) const;
+
+ // cppcheck-suppress functionStatic
+ void exportAnchorDefinition(io::JSONFormatter *formatter) const;
};
// ---------------------------------------------------------------------------
@@ -105,6 +108,17 @@ void Datum::Private::exportAnchorDefinition(io::WKTFormatter *formatter) const {
}
}
+// ---------------------------------------------------------------------------
+
+void Datum::Private::exportAnchorDefinition(
+ io::JSONFormatter *formatter) const {
+ if (anchorDefinition) {
+ auto &writer = formatter->writer();
+ writer.AddObjKey("anchor");
+ writer.Add(*anchorDefinition);
+ }
+}
+
//! @endcond
// ---------------------------------------------------------------------------
@@ -348,6 +362,40 @@ void PrimeMeridian::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void PrimeMeridian::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto &writer = formatter->writer();
+ auto objectContext(
+ formatter->MakeObjectContext("PrimeMeridian", !identifiers().empty()));
+
+ 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");
+ const auto &unit = l_long.unit();
+ if (unit == common::UnitOfMeasure::DEGREE) {
+ writer.Add(l_long.value(), 15);
+ } else {
+ auto longitudeContext(formatter->MakeObjectContext(nullptr, false));
+ writer.AddObjKey("value");
+ writer.Add(l_long.value(), 15);
+ 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();
@@ -768,6 +816,66 @@ void Ellipsoid::_exportToWKT(
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+void Ellipsoid::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto &writer = formatter->writer();
+ auto objectContext(
+ formatter->MakeObjectContext("Ellipsoid", !identifiers().empty()));
+
+ writer.AddObjKey("name");
+ auto l_name = nameStr();
+ if (l_name.empty()) {
+ writer.Add("unnamed");
+ } else {
+ writer.Add(l_name);
+ }
+
+ const auto &semiMajor = semiMajorAxis();
+ const auto &semiMajorUnit = semiMajor.unit();
+ writer.AddObjKey(isSphere() ? "radius" : "semi_major_axis");
+ if (semiMajorUnit == common::UnitOfMeasure::METRE) {
+ writer.Add(semiMajor.value(), 15);
+ } else {
+ auto objContext(formatter->MakeObjectContext(nullptr, false));
+ writer.AddObjKey("value");
+ writer.Add(semiMajor.value(), 15);
+
+ writer.AddObjKey("unit");
+ semiMajorUnit._exportToJSON(formatter);
+ }
+
+ if (!isSphere()) {
+ const auto &l_inverseFlattening = inverseFlattening();
+ if (l_inverseFlattening.has_value()) {
+ writer.AddObjKey("inverse_flattening");
+ writer.Add(l_inverseFlattening->getSIValue(), 15);
+ } else {
+ writer.AddObjKey("semi_minor_axis");
+ const auto &l_semiMinorAxis(semiMinorAxis());
+ const auto &semiMinorAxisUnit(l_semiMinorAxis->unit());
+ if (semiMinorAxisUnit == common::UnitOfMeasure::METRE) {
+ writer.Add(l_semiMinorAxis->value(), 15);
+ } else {
+ auto objContext(formatter->MakeObjectContext(nullptr, false));
+ writer.AddObjKey("value");
+ writer.Add(l_semiMinorAxis->value(), 15);
+
+ writer.AddObjKey("unit");
+ semiMinorAxisUnit._exportToJSON(formatter);
+ }
+ }
+ }
+
+ if (formatter->outputId()) {
+ formatID(formatter);
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
bool Ellipsoid::lookForProjWellKnownEllps(std::string &projEllpsName,
std::string &ellpsName) const {
const double a = semiMajorAxis().getSIValue();
@@ -1153,6 +1261,55 @@ void GeodeticReferenceFrame::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void GeodeticReferenceFrame::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto dynamicGRF = dynamic_cast<const DynamicGeodeticReferenceFrame *>(this);
+
+ auto objectContext(formatter->MakeObjectContext(
+ dynamicGRF ? "DynamicGeodeticReferenceFrame" : "GeodeticReferenceFrame",
+ !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ auto l_name = nameStr();
+ if (l_name.empty()) {
+ writer.Add("unnamed");
+ } else {
+ writer.Add(l_name);
+ }
+
+ Datum::getPrivate()->exportAnchorDefinition(formatter);
+
+ if (dynamicGRF) {
+ writer.AddObjKey("frame_reference_epoch");
+ writer.Add(dynamicGRF->frameReferenceEpoch().value());
+
+ const auto &deformationModel = dynamicGRF->deformationModelName();
+ if (deformationModel.has_value()) {
+ writer.AddObjKey("deformation_model");
+ writer.Add(*deformationModel);
+ }
+ }
+
+ writer.AddObjKey("ellipsoid");
+ formatter->setOmitTypeInImmediateChild();
+ ellipsoid()->_exportToJSON(formatter);
+
+ const auto &l_primeMeridian(primeMeridian());
+ if (l_primeMeridian->nameStr() != "Greenwich") {
+ writer.AddObjKey("prime_meridian");
+ formatter->setOmitTypeInImmediateChild();
+ primeMeridian()->_exportToJSON(formatter);
+ }
+
+ ObjectUsage::baseExportToJSON(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
bool GeodeticReferenceFrame::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {
@@ -1279,7 +1436,7 @@ void DynamicGeodeticReferenceFrame::_exportToWKT(
// ---------------------------------------------------------------------------
-/** \brief Instantiate a DyanmicGeodeticReferenceFrame
+/** \brief Instantiate a DynamicGeodeticReferenceFrame
*
* @param properties See \ref general_properties.
* At minimum the name should be defined.
@@ -1288,7 +1445,7 @@ void DynamicGeodeticReferenceFrame::_exportToWKT(
* @param primeMeridian the PrimeMeridian.
* @param frameReferenceEpochIn the frame reference epoch.
* @param deformationModelNameIn deformation model name, or empty
- * @return new DyanmicGeodeticReferenceFrame.
+ * @return new DynamicGeodeticReferenceFrame.
*/
DynamicGeodeticReferenceFrameNNPtr DynamicGeodeticReferenceFrame::create(
const util::PropertyMap &properties, const EllipsoidNNPtr &ellipsoid,
@@ -1419,6 +1576,56 @@ void DatumEnsemble::_exportToWKT(
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+void DatumEnsemble::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto objectContext(
+ formatter->MakeObjectContext("DatumEnsemble", !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ auto l_name = nameStr();
+ if (l_name.empty()) {
+ writer.Add("unnamed");
+ } else {
+ writer.Add(l_name);
+ }
+
+ auto l_datums = datums();
+ writer.AddObjKey("members");
+ {
+ auto membersContext(writer.MakeArrayContext(false));
+ for (const auto &datum : l_datums) {
+ auto memberContext(writer.MakeObjectContext());
+ writer.AddObjKey("name");
+ const auto &l_datum_name = datum->nameStr();
+ if (!l_datum_name.empty()) {
+ writer.Add(l_datum_name);
+ } else {
+ writer.Add("unnamed");
+ }
+ datum->formatID(formatter);
+ }
+ }
+
+ auto grfFirst = std::dynamic_pointer_cast<GeodeticReferenceFrame>(
+ l_datums[0].as_nullable());
+ if (grfFirst) {
+ writer.AddObjKey("ellipsoid");
+ formatter->setOmitTypeInImmediateChild();
+ grfFirst->ellipsoid()->_exportToJSON(formatter);
+ }
+
+ writer.AddObjKey("accuracy");
+ writer.Add(positionalAccuracy()->value());
+
+ formatID(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Instantiate a DatumEnsemble.
*
* @param properties See \ref general_properties.
@@ -1583,6 +1790,44 @@ void VerticalReferenceFrame::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void VerticalReferenceFrame::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto dynamicGRF = dynamic_cast<const DynamicVerticalReferenceFrame *>(this);
+
+ auto objectContext(formatter->MakeObjectContext(
+ dynamicGRF ? "DynamicVerticalReferenceFrame" : "VerticalReferenceFrame",
+ !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ auto l_name = nameStr();
+ if (l_name.empty()) {
+ writer.Add("unnamed");
+ } else {
+ writer.Add(l_name);
+ }
+
+ Datum::getPrivate()->exportAnchorDefinition(formatter);
+
+ if (dynamicGRF) {
+ writer.AddObjKey("frame_reference_epoch");
+ writer.Add(dynamicGRF->frameReferenceEpoch().value());
+
+ const auto &deformationModel = dynamicGRF->deformationModelName();
+ if (deformationModel.has_value()) {
+ writer.AddObjKey("deformation_model");
+ writer.Add(*deformationModel);
+ }
+ }
+
+ ObjectUsage::baseExportToJSON(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
bool VerticalReferenceFrame::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {
@@ -1715,7 +1960,7 @@ void DynamicVerticalReferenceFrame::_exportToWKT(
// ---------------------------------------------------------------------------
-/** \brief Instantiate a DyanmicVerticalReferenceFrame
+/** \brief Instantiate a DynamicVerticalReferenceFrame
*
* @param properties See \ref general_properties.
* At minimum the name should be defined.
@@ -1723,7 +1968,7 @@ void DynamicVerticalReferenceFrame::_exportToWKT(
* @param realizationMethodIn the realization method, or empty.
* @param frameReferenceEpochIn the frame reference epoch.
* @param deformationModelNameIn deformation model name, or empty
- * @return new DyanmicVerticalReferenceFrame.
+ * @return new DynamicVerticalReferenceFrame.
*/
DynamicVerticalReferenceFrameNNPtr DynamicVerticalReferenceFrame::create(
const util::PropertyMap &properties,
@@ -1846,6 +2091,32 @@ void TemporalDatum::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void TemporalDatum::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto objectContext(
+ formatter->MakeObjectContext("TemporalDatum", !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ writer.Add(nameStr());
+
+ writer.AddObjKey("calendar");
+ writer.Add(calendar());
+
+ const auto &timeOriginStr = temporalOrigin().toString();
+ if (!timeOriginStr.empty()) {
+ writer.AddObjKey("time_origin");
+ writer.Add(timeOriginStr);
+ }
+
+ ObjectUsage::baseExportToJSON(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
bool TemporalDatum::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {
@@ -1919,6 +2190,25 @@ void EngineeringDatum::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void EngineeringDatum::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto objectContext(formatter->MakeObjectContext("EngineeringDatum",
+ !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ writer.Add(nameStr());
+
+ Datum::getPrivate()->exportAnchorDefinition(formatter);
+
+ ObjectUsage::baseExportToJSON(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
bool EngineeringDatum::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {
@@ -1985,6 +2275,25 @@ void ParametricDatum::_exportToWKT(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+void ParametricDatum::_exportToJSON(
+ io::JSONFormatter *formatter) const // throw(FormattingException)
+{
+ auto objectContext(formatter->MakeObjectContext("ParametricDatum",
+ !identifiers().empty()));
+ auto &writer = formatter->writer();
+
+ writer.AddObjKey("name");
+ writer.Add(nameStr());
+
+ Datum::getPrivate()->exportAnchorDefinition(formatter);
+
+ ObjectUsage::baseExportToJSON(formatter);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
bool ParametricDatum::_isEquivalentTo(
const util::IComparable *other,
util::IComparable::Criterion criterion) const {