aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/reference_exported_symbols.txt1
-rw-r--r--src/iso19111/c_api.cpp23
-rw-r--r--src/proj.h2
-rw-r--r--test/unit/test_c_api.cpp26
4 files changed, 52 insertions, 0 deletions
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt
index a5fd41ca..42c7e43e 100644
--- a/scripts/reference_exported_symbols.txt
+++ b/scripts/reference_exported_symbols.txt
@@ -928,6 +928,7 @@ proj_crs_get_geodetic_crs
proj_crs_get_horizontal_datum
proj_crs_get_sub_crs
proj_crs_info_list_destroy
+proj_crs_is_derived
proj_crs_promote_to_3D
proj_cs_get_axis_count
proj_cs_get_axis_info
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index cb0c113a..ae13b40d 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -1840,6 +1840,29 @@ PJ *proj_crs_get_geodetic_crs(PJ_CONTEXT *ctx, const PJ *crs) {
// ---------------------------------------------------------------------------
+/** \brief Returns whether a CRS is a derived CRS.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs Object of type CRS (must not be NULL)
+ * @return TRUE if the CRS is a derived CRS.
+ * @since 8.0
+ */
+int proj_crs_is_derived(PJ_CONTEXT *ctx, const PJ *crs) {
+ if (!crs) {
+ proj_context_errno_set(ctx, PROJ_ERR_OTHER_API_MISUSE);
+ proj_log_error(ctx, __FUNCTION__, "missing required input");
+ return false;
+ }
+ auto l_crs = dynamic_cast<const CRS *>(crs->iso_obj.get());
+ if (!l_crs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CRS");
+ return false;
+ }
+ return dynamic_cast<const DerivedCRS *>(l_crs) != nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Get a CRS component from a CompoundCRS
*
* The returned object must be unreferenced with proj_destroy() after
diff --git a/src/proj.h b/src/proj.h
index b16f54ea..4b417dc4 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -1271,6 +1271,8 @@ int PROJ_DLL proj_get_suggested_operation(PJ_CONTEXT *ctx,
/* ------------------------------------------------------------------------- */
+int PROJ_DLL proj_crs_is_derived(PJ_CONTEXT *ctx, const PJ *crs);
+
PJ PROJ_DLL *proj_crs_get_geodetic_crs(PJ_CONTEXT *ctx, const PJ *crs);
PJ PROJ_DLL *proj_crs_get_horizontal_datum(PJ_CONTEXT *ctx, const PJ *crs);
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index d43d68ce..60ad8f61 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -5183,4 +5183,30 @@ TEST_F(CApi, datum_ensemble) {
}
}
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_crs_is_derived) {
+ {
+ auto wkt =
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get());
+ auto obj = proj_create_from_wkt(m_ctxt, wkt.c_str(), nullptr, nullptr,
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr) << wkt;
+
+ EXPECT_TRUE(proj_crs_is_derived(m_ctxt, obj));
+ }
+
+ {
+ auto wkt = createProjectedCRS()->baseCRS()->exportToWKT(
+ WKTFormatter::create().get());
+ auto obj = proj_create_from_wkt(m_ctxt, wkt.c_str(), nullptr, nullptr,
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr) << wkt;
+
+ EXPECT_FALSE(proj_crs_is_derived(m_ctxt, obj));
+ }
+}
+
} // namespace