aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNyall Dawson <nyall.dawson@gmail.com>2019-12-14 10:15:05 +1000
committerEven Rouault <even.rouault@spatialys.com>2019-12-14 01:15:05 +0100
commitccaebae3cb9424a9b21d0c58237d7e95c9e16b1b (patch)
treedec6e14e4a310c47ed987b7ef67d3e67f14f0fe3
parentc9d6d364a86054f1dddbeb772660375be47aa23b (diff)
downloadPROJ-ccaebae3cb9424a9b21d0c58237d7e95c9e16b1b.tar.gz
PROJ-ccaebae3cb9424a9b21d0c58237d7e95c9e16b1b.zip
Add proj_coordoperation_create_inverse to C API (#1795)
-rw-r--r--scripts/reference_exported_symbols.txt1
-rw-r--r--src/iso19111/c_api.cpp28
-rw-r--r--src/proj.h3
-rw-r--r--test/unit/test_c_api.cpp30
4 files changed, 62 insertions, 0 deletions
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt
index e20f29b3..3f4cd51b 100644
--- a/scripts/reference_exported_symbols.txt
+++ b/scripts/reference_exported_symbols.txt
@@ -801,6 +801,7 @@ proj_context_use_proj4_init_rules
proj_convert_conversion_to_other_method
proj_coord
proj_coord_error()
+proj_coordoperation_create_inverse
proj_coordoperation_get_accuracy
proj_coordoperation_get_grid_used
proj_coordoperation_get_grid_used_count
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index 9db9e5b3..5e2ac522 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -7769,6 +7769,34 @@ PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) {
// ---------------------------------------------------------------------------
+/** \brief Returns a PJ* coordinate operation object which represents the
+ * inverse operation of the specified coordinate operation.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type CoordinateOperation (must not be NULL)
+ * @return a new PJ* object to free with proj_destroy() in case of success, or
+ * nullptr in case of error
+ * @since 6.3
+ */
+PJ *proj_coordoperation_create_inverse(PJ_CONTEXT *ctx, const PJ *obj) {
+
+ SANITIZE_CTX(ctx);
+ auto co = dynamic_cast<const CoordinateOperation *>(obj->iso_obj.get());
+ if (!co) {
+ proj_log_error(ctx, __FUNCTION__,
+ "Object is not a CoordinateOperation");
+ return nullptr;
+ }
+ try {
+ return pj_obj_create(ctx, co->inverse());
+ } catch (const std::exception &e) {
+ proj_log_debug(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Returns the number of steps of a concatenated operation.
*
* The input object must be a concatenated operation.
diff --git a/src/proj.h b/src/proj.h
index fc309542..b8b90277 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -1091,6 +1091,9 @@ int PROJ_DLL proj_coordoperation_get_towgs84_values(PJ_CONTEXT *ctx,
int value_count,
int emit_error_if_incompatible);
+PJ PROJ_DLL *proj_coordoperation_create_inverse(PJ_CONTEXT *ctx, const PJ *obj);
+
+
int PROJ_DLL proj_concatoperation_get_step_count(PJ_CONTEXT *ctx,
const PJ *concatoperation);
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index f87f6589..22e2ac11 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -3486,6 +3486,36 @@ TEST_F(CApi, proj_normalize_for_visualization_on_crs) {
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_coordoperation_create_inverse) {
+
+ auto P = proj_create(
+ m_ctxt, "+proj=pipeline +step +proj=axisswap +order=2,1 +step "
+ "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push "
+ "+v_3 +step +proj=cart +ellps=evrst30 +step +proj=helmert "
+ "+x=293 +y=836 +z=318 +rx=0.5 +ry=1.6 +rz=-2.8 +s=2.1 "
+ "+convention=position_vector +step +inv +proj=cart "
+ "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert "
+ "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1");
+ ObjectKeeper keeper_P(P);
+ ASSERT_NE(P, nullptr);
+ auto Pinversed = proj_coordoperation_create_inverse(m_ctxt, P);
+ ObjectKeeper keeper_Pinversed(Pinversed);
+ ASSERT_NE(Pinversed, nullptr);
+
+ auto projstr = proj_as_proj_string(m_ctxt, Pinversed, PJ_PROJ_5, nullptr);
+ ASSERT_NE(projstr, nullptr);
+ EXPECT_EQ(std::string(projstr),
+ "+proj=pipeline +step +proj=axisswap +order=2,1 +step "
+ "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 "
+ "+step +proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=293 "
+ "+y=836 +z=318 +rx=0.5 +ry=1.6 +rz=-2.8 +s=2.1 "
+ "+convention=position_vector +step +inv +proj=cart "
+ "+ellps=evrst30 +step +proj=pop +v_3 +step +proj=unitconvert "
+ "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1");
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_get_remarks) {
auto co = proj_create_from_database(m_ctxt, "EPSG", "8048",
PJ_CATEGORY_COORDINATE_OPERATION, false,