From 17f0b0b3bc65ffba39bf6f22a12b2cc7fcb9bafd Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 6 Jul 2019 02:03:50 +0200 Subject: Proof-of-concept of JSON export limited to PrimeMeridian (refs #1545) --- src/iso19111/datum.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src/iso19111/datum.cpp') 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 @@ -347,6 +347,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) { -- cgit v1.2.3 From ece151aed1b4bf2634de5759f37fd7bc005e8313 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 6 Jul 2019 17:06:23 +0200 Subject: CRS JSON: export GeographicCRS and Projected CRS --- src/iso19111/datum.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 101 insertions(+), 5 deletions(-) (limited to 'src/iso19111/datum.cpp') diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 6ba219d4..89ecc755 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 // --------------------------------------------------------------------------- @@ -352,10 +366,8 @@ void PrimeMeridian::_exportToJSON( io::JSONFormatter *formatter) const // throw(FormattingException) { auto &writer = formatter->writer(); - PROJ::CPLJSonStreamingWriter::ObjectContext objectContext(writer); - - writer.AddObjKey("type"); - writer.Add("PrimeMeridian"); + auto objectContext( + formatter->MakeObjectContext("PrimeMeridian", !identifiers().empty())); writer.AddObjKey("name"); std::string l_name = @@ -365,7 +377,7 @@ void PrimeMeridian::_exportToJSON( const auto &l_long = longitude(); writer.AddObjKey("longitude"); { - PROJ::CPLJSonStreamingWriter::ObjectContext longitudeContext(writer); + auto longitudeContext(formatter->MakeObjectContext(nullptr, false)); writer.AddObjKey("value"); writer.Add(l_long.value(), 15); @@ -803,6 +815,60 @@ 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"); + { + 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"); + { + auto objContext(formatter->MakeObjectContext(nullptr, false)); + writer.AddObjKey("value"); + writer.Add(semiMinorAxis()->value(), 15); + + writer.AddObjKey("unit"); + semiMinorAxis()->unit()._exportToJSON(formatter); + } + } + } + + if (formatter->outputId()) { + formatID(formatter); + } +} +//! @endcond + +// --------------------------------------------------------------------------- + bool Ellipsoid::lookForProjWellKnownEllps(std::string &projEllpsName, std::string &ellpsName) const { const double a = semiMajorAxis().getSIValue(); @@ -1187,6 +1253,36 @@ void GeodeticReferenceFrame::_exportToWKT( // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +void GeodeticReferenceFrame::_exportToJSON( + io::JSONFormatter *formatter) const // throw(FormattingException) +{ + auto objectContext(formatter->MakeObjectContext("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); + + writer.AddObjKey("ellipsoid"); + ellipsoid()->_exportToJSON(formatter); + + writer.AddObjKey("prime_meridian"); + primeMeridian()->_exportToJSON(formatter); + + ObjectUsage::baseExportToJSON(formatter); +} +//! @endcond + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress bool GeodeticReferenceFrame::_isEquivalentTo( const util::IComparable *other, -- cgit v1.2.3 From 89f2cc7ec4178a369e73e9cd115a2552a55d870a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 8 Aug 2019 20:04:20 +0200 Subject: PROJJSON export: use more compact form --- src/iso19111/datum.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src/iso19111/datum.cpp') diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 89ecc755..2944da1e 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -376,12 +376,13 @@ void PrimeMeridian::_exportToJSON( 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); - - const auto &unit = l_long.unit(); writer.AddObjKey("unit"); unit._exportToJSON(formatter); } @@ -834,7 +835,9 @@ void Ellipsoid::_exportToJSON( 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); @@ -850,13 +853,17 @@ void Ellipsoid::_exportToJSON( 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(semiMinorAxis()->value(), 15); + writer.Add(l_semiMinorAxis->value(), 15); writer.AddObjKey("unit"); - semiMinorAxis()->unit()._exportToJSON(formatter); + semiMinorAxisUnit._exportToJSON(formatter); } } } @@ -1272,10 +1279,15 @@ void GeodeticReferenceFrame::_exportToJSON( Datum::getPrivate()->exportAnchorDefinition(formatter); writer.AddObjKey("ellipsoid"); + formatter->setOmitTypeInImmediateChild(); ellipsoid()->_exportToJSON(formatter); - writer.AddObjKey("prime_meridian"); - primeMeridian()->_exportToJSON(formatter); + const auto &l_primeMeridian(primeMeridian()); + if (l_primeMeridian->nameStr() != "Greenwich") { + writer.AddObjKey("prime_meridian"); + formatter->setOmitTypeInImmediateChild(); + primeMeridian()->_exportToJSON(formatter); + } ObjectUsage::baseExportToJSON(formatter); } -- cgit v1.2.3 From f0d766e45640800412c08a7cb9ab4f8823d88d05 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 9 Aug 2019 17:10:20 +0200 Subject: PROJSJON: add import/export of VerticalCRS, CompoundCRS, BoundCRS, Transformation and ConcatenatedOperation --- src/iso19111/datum.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 'src/iso19111/datum.cpp') diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 2944da1e..d6e6bc21 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1725,6 +1725,30 @@ void VerticalReferenceFrame::_exportToWKT( // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +void VerticalReferenceFrame::_exportToJSON( + io::JSONFormatter *formatter) const // throw(FormattingException) +{ + auto objectContext(formatter->MakeObjectContext("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); + + ObjectUsage::baseExportToJSON(formatter); +} +//! @endcond + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress bool VerticalReferenceFrame::_isEquivalentTo( const util::IComparable *other, @@ -1988,6 +2012,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, @@ -2061,6 +2111,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, @@ -2127,6 +2196,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, -- cgit v1.2.3 From 63981af418d84749cd4d70752f83fd551100389f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 10 Aug 2019 15:15:44 +0200 Subject: PROJJSON: add support for DatumEnsemble and Dynamic[Geodetic|Vertical]ReferenceFrame --- src/iso19111/datum.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 8 deletions(-) (limited to 'src/iso19111/datum.cpp') diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index d6e6bc21..65905ca9 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1264,8 +1264,11 @@ void GeodeticReferenceFrame::_exportToWKT( void GeodeticReferenceFrame::_exportToJSON( io::JSONFormatter *formatter) const // throw(FormattingException) { - auto objectContext(formatter->MakeObjectContext("GeodeticReferenceFrame", - !identifiers().empty())); + auto dynamicGRF = dynamic_cast(this); + + auto objectContext(formatter->MakeObjectContext( + dynamicGRF ? "DynamicGeodeticReferenceFrame" : "GeodeticReferenceFrame", + !identifiers().empty())); auto &writer = formatter->writer(); writer.AddObjKey("name"); @@ -1278,6 +1281,17 @@ void GeodeticReferenceFrame::_exportToJSON( 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); @@ -1422,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. @@ -1431,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, @@ -1562,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( + 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. @@ -1729,8 +1793,11 @@ void VerticalReferenceFrame::_exportToWKT( void VerticalReferenceFrame::_exportToJSON( io::JSONFormatter *formatter) const // throw(FormattingException) { - auto objectContext(formatter->MakeObjectContext("VerticalReferenceFrame", - !identifiers().empty())); + auto dynamicGRF = dynamic_cast(this); + + auto objectContext(formatter->MakeObjectContext( + dynamicGRF ? "DynamicVerticalReferenceFrame" : "VerticalReferenceFrame", + !identifiers().empty())); auto &writer = formatter->writer(); writer.AddObjKey("name"); @@ -1743,6 +1810,17 @@ void VerticalReferenceFrame::_exportToJSON( 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 @@ -1882,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. @@ -1890,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, -- cgit v1.2.3