Skip to content

Commit

Permalink
Merge pull request #3562 from rouault/coordinateMetadata
Browse files Browse the repository at this point in the history
Initial support for ISO19111 CoordinateMetadata class
  • Loading branch information
rouault authored Jan 18, 2023
2 parents fea8a4d + 33f1914 commit 2ffc593
Show file tree
Hide file tree
Showing 32 changed files with 1,417 additions and 60 deletions.
15 changes: 14 additions & 1 deletion data/projjson.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{ "$ref": "#/definitions/ellipsoid" },
{ "$ref": "#/definitions/prime_meridian" },
{ "$ref": "#/definitions/single_operation" },
{ "$ref": "#/definitions/concatenated_operation" }
{ "$ref": "#/definitions/concatenated_operation" },
{ "$ref": "#/definitions/coordinate_metadata" }
],

"definitions": {
Expand Down Expand Up @@ -208,6 +209,18 @@
"additionalProperties": false
},

"coordinate_metadata": {
"type": "object",
"properties": {
"$schema" : { "type": "string" },
"type": { "type": "string", "enum": ["CoordinateMetadata"] },
"crs": { "$ref": "#/definitions/crs" },
"coordinateEpoch": { "type": "number" }
},
"required" : [ "crs" ],
"additionalProperties": false
},

"coordinate_system": {
"type": "object",
"properties": {
Expand Down
1 change: 1 addition & 0 deletions docs/source/apps/cs2cs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Synopsis
"urn:ogc:def:coordinateOperation:EPSG::1671"),
- an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as
uniqueness is not guaranteed, heuristics are applied to determine the appropriate best match.
- a CRS name and a coordinate epoch, separated with '@'. For example "ITRF2014@2025.0". (*added in 9.2*)
- a OGC URN combining references for compound coordinate reference systems
(e.g "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" or custom abbreviated
syntax "EPSG:2393+5717"),
Expand Down
1 change: 1 addition & 0 deletions docs/source/apps/projinfo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Synopsis
"urn:ogc:def:coordinateOperation:EPSG::1671"),
- an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as
uniqueness is not guaranteed, heuristics are applied to determine the appropriate best match.
- a CRS name and a coordinate epoch, separated with '@'. For example "ITRF2014@2025.0". (*added in 9.2*)
- a OGC URN combining references for compound coordinate reference systems
(e.g "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" or custom abbreviated
syntax "EPSG:2393+5717"),
Expand Down
10 changes: 8 additions & 2 deletions docs/source/development/reference/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ paragraph for more details.
- more generally any string accepted by :c:func:`proj_create` representing
a CRS
Starting with PROJ 9.2, source_crs or target_crs can be a CoordinateMetadata
with an associated coordinate epoch (but only one of them, not both).
An "area of use" can be specified in area. When it is supplied, the more
accurate transformation between two given systems can be chosen.
Expand All @@ -164,9 +167,9 @@ paragraph for more details.
:param ctx: Threading context.
:type ctx: :c:type:`PJ_CONTEXT` *
:param `source_crs`: Source CRS.
:param `source_crs`: Source CRS or CoordinateMetadata.
:type `source_crs`: `const char*`
:param `target_crs`: Destination SRS.
:param `target_crs`: Destination SRS or CoordinateMetadata
:type `target_crs`: `const char*`
:param `area`: Descriptor of the desired area for the transformation.
:type `area`: :c:type:`PJ_AREA` *
Expand All @@ -182,6 +185,9 @@ paragraph for more details.
This is the same as :c:func:`proj_create_crs_to_crs` except that the source and
target CRS are passed as PJ* objects which must be of the CRS variety.
Starting with PROJ 9.2, source_crs or target_crs can be a CoordinateMetadata
with an associated coordinate epoch (but only one of them, not both).
:param `options`: a list of NUL terminated options, or NULL.
The list of supported options is:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/specifications/projjson.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ in the WKT2:2019 specification also apply, as supplement to the JSON schema cons
History of the schema
---------------------

* v0.6: additional optional "source_crs" property in "abridged_transformation". Implemented in PROJ 9.2
* v0.6: additional optional "source_crs" property in "abridged_transformation". Added CoordinateMeta. Implemented in PROJ 9.2
* v0.5:
- Implemented in PROJ 9.1:
+ add "meridian" member in Axis object type.
Expand Down
2 changes: 1 addition & 1 deletion include/proj/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
install(
FILES util.hpp metadata.hpp common.hpp crs.hpp datum.hpp
FILES util.hpp metadata.hpp common.hpp coordinates.hpp crs.hpp datum.hpp
coordinatesystem.hpp coordinateoperation.hpp io.hpp nn.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/proj
)
37 changes: 37 additions & 0 deletions include/proj/coordinateoperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ class DerivedCRS;
class ProjectedCRS;
} // namespace crs

namespace coordinates {
class CoordinateMetadata;
using CoordinateMetadataPtr = std::shared_ptr<CoordinateMetadata>;
using CoordinateMetadataNNPtr = util::nn<CoordinateMetadataPtr>;
} // namespace coordinates

/** osgeo.proj.operation namespace
\brief Coordinate operations (relationship between any two coordinate
Expand Down Expand Up @@ -193,6 +199,11 @@ class PROJ_GCC_DLL CoordinateOperation : public common::ObjectUsage,
const std::vector<metadata::PositionalAccuracyNNPtr> &accuracies);
PROJ_INTERNAL void setHasBallparkTransformation(bool b);

PROJ_INTERNAL void
setSourceCoordinateEpoch(const util::optional<common::DataEpoch> &epoch);
PROJ_INTERNAL void
setTargetCoordinateEpoch(const util::optional<common::DataEpoch> &epoch);

PROJ_INTERNAL void
setProperties(const util::PropertyMap
&properties); // throw(InvalidValueTypeException)
Expand Down Expand Up @@ -1904,12 +1915,28 @@ class PROJ_GCC_DLL CoordinateOperationContext {
PROJ_DLL const std::vector<std::pair<std::string, std::string>> &
getIntermediateCRS() const;

PROJ_DLL void
setSourceCoordinateEpoch(const util::optional<common::DataEpoch> &epoch);

PROJ_DLL const util::optional<common::DataEpoch> &
getSourceCoordinateEpoch() const;

PROJ_DLL void
setTargetCoordinateEpoch(const util::optional<common::DataEpoch> &epoch);

PROJ_DLL const util::optional<common::DataEpoch> &
getTargetCoordinateEpoch() const;

PROJ_DLL static CoordinateOperationContextNNPtr
create(const io::AuthorityFactoryPtr &authorityFactory,
const metadata::ExtentPtr &extent, double accuracy);

PROJ_DLL CoordinateOperationContextNNPtr clone() const;

protected:
PROJ_INTERNAL CoordinateOperationContext();
PROJ_INTERNAL
CoordinateOperationContext(const CoordinateOperationContext &);
INLINED_MAKE_UNIQUE

private:
Expand Down Expand Up @@ -1947,6 +1974,16 @@ class PROJ_GCC_DLL CoordinateOperationFactory {
const crs::CRSNNPtr &targetCRS,
const CoordinateOperationContextNNPtr &context) const;

PROJ_DLL std::vector<CoordinateOperationNNPtr> createOperations(
const coordinates::CoordinateMetadataNNPtr &sourceCoordinateMetadata,
const crs::CRSNNPtr &targetCRS,
const CoordinateOperationContextNNPtr &context) const;

PROJ_DLL std::vector<CoordinateOperationNNPtr> createOperations(
const crs::CRSNNPtr &sourceCRS,
const coordinates::CoordinateMetadataNNPtr &targetCoordinateMetadata,
const CoordinateOperationContextNNPtr &context) const;

PROJ_DLL static CoordinateOperationFactoryNNPtr create();

protected:
Expand Down
108 changes: 108 additions & 0 deletions include/proj/coordinates.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/******************************************************************************
*
* Project: PROJ
* Purpose: ISO19111:2019 implementation
* Author: Even Rouault <even dot rouault at spatialys dot com>
*
******************************************************************************
* Copyright (c) 2023, Even Rouault <even dot rouault at spatialys dot com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/

#ifndef COORDINATES_HH_INCLUDED
#define COORDINATES_HH_INCLUDED

#include <memory>

#include "common.hpp"
#include "crs.hpp"
#include "io.hpp"
#include "util.hpp"

NS_PROJ_START

/** osgeo.proj.coordinates namespace
\brief Coordinates package
*/
namespace coordinates {

class CoordinateMetadata;
/** Shared pointer of CoordinateMetadata */
using CoordinateMetadataPtr = std::shared_ptr<CoordinateMetadata>;
/** Non-null shared pointer of CoordinateMetadata */
using CoordinateMetadataNNPtr = util::nn<CoordinateMetadataPtr>;

// ---------------------------------------------------------------------------

/** \brief Associates a CRS with a coordinate epoch.
*
* \remark Implements CoordinateMetadata from \ref ISO_19111_2019
* \since 9.2
*/

class PROJ_GCC_DLL CoordinateMetadata : public util::BaseObject,
public io::IWKTExportable,
public io::IJSONExportable {
public:
//! @cond Doxygen_Suppress
PROJ_DLL ~CoordinateMetadata() override;
//! @endcond

PROJ_DLL const crs::CRSNNPtr &crs() PROJ_PURE_DECL;
PROJ_DLL const util::optional<common::DataEpoch> &
coordinateEpoch() PROJ_PURE_DECL;
PROJ_DLL double coordinateEpochAsDecimalYear() PROJ_PURE_DECL;

PROJ_DLL static CoordinateMetadataNNPtr create(const crs::CRSNNPtr &crsIn);
PROJ_DLL static CoordinateMetadataNNPtr
create(const crs::CRSNNPtr &crsIn, double coordinateEpochAsDecimalYear);

PROJ_PRIVATE :
//! @cond Doxygen_Suppress

PROJ_INTERNAL void
_exportToWKT(io::WKTFormatter *formatter)
const override; // throw(io::FormattingException)

PROJ_INTERNAL void _exportToJSON(io::JSONFormatter *formatter)
const override; // throw(FormattingException)

//! @endcond

protected:
PROJ_INTERNAL explicit CoordinateMetadata(const crs::CRSNNPtr &crsIn);
PROJ_INTERNAL CoordinateMetadata(const crs::CRSNNPtr &crsIn,
double coordinateEpochAsDecimalYear);

INLINED_MAKE_SHARED

private:
PROJ_OPAQUE_PRIVATE_DATA
CoordinateMetadata &operator=(const CoordinateMetadata &other) = delete;
};

// ---------------------------------------------------------------------------

} // namespace coordinates

NS_PROJ_END

#endif // COORDINATES_HH_INCLUDED
1 change: 1 addition & 0 deletions include/proj/crs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class PROJ_GCC_DLL CRS : public common::ObjectUsage,

// Non-standard

PROJ_DLL bool isDynamic(bool considerWGS84AsDynamic = false) const;
PROJ_DLL GeodeticCRSPtr extractGeodeticCRS() const;
PROJ_DLL GeographicCRSPtr extractGeographicCRS() const;
PROJ_DLL VerticalCRSPtr extractVerticalCRS() const;
Expand Down
4 changes: 3 additions & 1 deletion include/proj/internal/io_internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ class WKTConstants {
static const std::string BASEPARAMCRS;
static const std::string BASETIMECRS;
static const std::string VERSION;
static const std::string GEOIDMODEL; // WKT2-2019
static const std::string GEOIDMODEL; // WKT2-2019
static const std::string COORDINATEMETADATA; // WKT2-2019
static const std::string EPOCH; // WKT2-2019

// WKT2 alternate (longer or shorter)
static const std::string GEODETICCRS;
Expand Down
15 changes: 14 additions & 1 deletion schemas/v0.6/projjson.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
{ "$ref": "#/definitions/ellipsoid" },
{ "$ref": "#/definitions/prime_meridian" },
{ "$ref": "#/definitions/single_operation" },
{ "$ref": "#/definitions/concatenated_operation" }
{ "$ref": "#/definitions/concatenated_operation" },
{ "$ref": "#/definitions/coordinate_metadata" }
],

"definitions": {
Expand Down Expand Up @@ -208,6 +209,18 @@
"additionalProperties": false
},

"coordinate_metadata": {
"type": "object",
"properties": {
"$schema" : { "type": "string" },
"type": { "type": "string", "enum": ["CoordinateMetadata"] },
"crs": { "$ref": "#/definitions/crs" },
"coordinateEpoch": { "type": "number" }
},
"required" : [ "crs" ],
"additionalProperties": false
},

"coordinate_system": {
"type": "object",
"properties": {
Expand Down
15 changes: 15 additions & 0 deletions scripts/reference_exported_symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ osgeo::proj::common::UnitOfMeasure::type() const
osgeo::proj::common::UnitOfMeasure::~UnitOfMeasure()
osgeo::proj::common::UnitOfMeasure::UnitOfMeasure(osgeo::proj::common::UnitOfMeasure const&)
osgeo::proj::common::UnitOfMeasure::UnitOfMeasure(std::string const&, double, osgeo::proj::common::UnitOfMeasure::Type, std::string const&, std::string const&)
osgeo::proj::coordinates::CoordinateMetadata::coordinateEpochAsDecimalYear() const
osgeo::proj::coordinates::CoordinateMetadata::coordinateEpoch() const
osgeo::proj::coordinates::CoordinateMetadata::~CoordinateMetadata()
osgeo::proj::coordinates::CoordinateMetadata::create(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&)
osgeo::proj::coordinates::CoordinateMetadata::create(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, double)
osgeo::proj::coordinates::CoordinateMetadata::crs() const
osgeo::proj::crs::BoundCRS::baseCRS() const
osgeo::proj::crs::BoundCRS::baseCRSWithCanonicalBoundCRS() const
osgeo::proj::crs::BoundCRS::~BoundCRS()
Expand All @@ -118,6 +124,7 @@ osgeo::proj::crs::CRS::extractGeographicCRS() const
osgeo::proj::crs::CRS::extractVerticalCRS() const
osgeo::proj::crs::CRS::getNonDeprecated(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::io::DatabaseContext> > const&) const
osgeo::proj::crs::CRS::identify(std::shared_ptr<osgeo::proj::io::AuthorityFactory> const&) const
osgeo::proj::crs::CRS::isDynamic(bool) const
osgeo::proj::crs::CRS::normalizeForVisualization() const
osgeo::proj::crs::CRS::promoteTo3D(std::string const&, std::shared_ptr<osgeo::proj::io::DatabaseContext> const&) const
osgeo::proj::crs::CRS::shallowClone() const
Expand Down Expand Up @@ -609,6 +616,7 @@ osgeo::proj::operation::Conversion::createWagnerV(osgeo::proj::util::PropertyMap
osgeo::proj::operation::Conversion::identify() const
osgeo::proj::operation::Conversion::inverse() const
osgeo::proj::operation::Conversion::isUTM(int&, bool&) const
osgeo::proj::operation::CoordinateOperationContext::clone() const
osgeo::proj::operation::CoordinateOperationContext::~CoordinateOperationContext()
osgeo::proj::operation::CoordinateOperationContext::create(std::shared_ptr<osgeo::proj::io::AuthorityFactory> const&, std::shared_ptr<osgeo::proj::metadata::Extent> const&, double)
osgeo::proj::operation::CoordinateOperationContext::getAllowBallparkTransformations() const
Expand All @@ -620,7 +628,9 @@ osgeo::proj::operation::CoordinateOperationContext::getDiscardSuperseded() const
osgeo::proj::operation::CoordinateOperationContext::getGridAvailabilityUse() const
osgeo::proj::operation::CoordinateOperationContext::getIntermediateCRS() const
osgeo::proj::operation::CoordinateOperationContext::getSourceAndTargetCRSExtentUse() const
osgeo::proj::operation::CoordinateOperationContext::getSourceCoordinateEpoch() const
osgeo::proj::operation::CoordinateOperationContext::getSpatialCriterion() const
osgeo::proj::operation::CoordinateOperationContext::getTargetCoordinateEpoch() const
osgeo::proj::operation::CoordinateOperationContext::getUsePROJAlternativeGridNames() const
osgeo::proj::operation::CoordinateOperationContext::setAllowBallparkTransformations(bool)
osgeo::proj::operation::CoordinateOperationContext::setAllowUseIntermediateCRS(osgeo::proj::operation::CoordinateOperationContext::IntermediateCRSUse)
Expand All @@ -630,13 +640,17 @@ osgeo::proj::operation::CoordinateOperationContext::setDiscardSuperseded(bool)
osgeo::proj::operation::CoordinateOperationContext::setGridAvailabilityUse(osgeo::proj::operation::CoordinateOperationContext::GridAvailabilityUse)
osgeo::proj::operation::CoordinateOperationContext::setIntermediateCRS(std::vector<std::pair<std::string, std::string>, std::allocator<std::pair<std::string, std::string> > > const&)
osgeo::proj::operation::CoordinateOperationContext::setSourceAndTargetCRSExtentUse(osgeo::proj::operation::CoordinateOperationContext::SourceTargetCRSExtentUse)
osgeo::proj::operation::CoordinateOperationContext::setSourceCoordinateEpoch(osgeo::proj::util::optional<osgeo::proj::common::DataEpoch> const&)
osgeo::proj::operation::CoordinateOperationContext::setSpatialCriterion(osgeo::proj::operation::CoordinateOperationContext::SpatialCriterion)
osgeo::proj::operation::CoordinateOperationContext::setTargetCoordinateEpoch(osgeo::proj::util::optional<osgeo::proj::common::DataEpoch> const&)
osgeo::proj::operation::CoordinateOperationContext::setUsePROJAlternativeGridNames(bool)
osgeo::proj::operation::CoordinateOperation::~CoordinateOperation()
osgeo::proj::operation::CoordinateOperation::coordinateOperationAccuracies() const
osgeo::proj::operation::CoordinateOperationFactory::~CoordinateOperationFactory()
osgeo::proj::operation::CoordinateOperationFactory::create()
osgeo::proj::operation::CoordinateOperationFactory::createOperation(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&) const
osgeo::proj::operation::CoordinateOperationFactory::createOperations(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::coordinates::CoordinateMetadata> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::unique_ptr<osgeo::proj::operation::CoordinateOperationContext, std::default_delete<osgeo::proj::operation::CoordinateOperationContext> > > const&) const
osgeo::proj::operation::CoordinateOperationFactory::createOperations(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::coordinates::CoordinateMetadata> > const&, dropbox::oxygen::nn<std::unique_ptr<osgeo::proj::operation::CoordinateOperationContext, std::default_delete<osgeo::proj::operation::CoordinateOperationContext> > > const&) const
osgeo::proj::operation::CoordinateOperationFactory::createOperations(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::unique_ptr<osgeo::proj::operation::CoordinateOperationContext, std::default_delete<osgeo::proj::operation::CoordinateOperationContext> > > const&) const
osgeo::proj::operation::CoordinateOperation::hasBallparkTransformation() const
osgeo::proj::operation::CoordinateOperation::interpolationCRS() const
Expand Down Expand Up @@ -838,6 +852,7 @@ proj_context_use_proj4_init_rules
proj_convert_conversion_to_other_method
proj_coord
proj_coord_error()
proj_coordinate_metadata_get_epoch
proj_coordoperation_create_inverse
proj_coordoperation_get_accuracy
proj_coordoperation_get_grid_used
Expand Down
Loading

0 comments on commit 2ffc593

Please sign in to comment.