diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-08-20 13:22:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-20 13:22:01 +0200 |
| commit | 2c9c015a6529548f5a5d448c78bc9b565d751590 (patch) | |
| tree | 2597c59e8270f1480785c97f7441ee0b295c29b3 /src/iso19111/datum.cpp | |
| parent | e52fc2aa58504e6f0658da821bdd543d7a39df34 (diff) | |
| parent | cad1c5cf61fc00759bf4ad17b0b34f57f4945de6 (diff) | |
| download | PROJ-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.cpp | 317 |
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 { |
