aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-12-05 23:00:30 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-05 23:00:30 +0100
commitdccf4658ac4cf9194682350ec292a086a2bb24a1 (patch)
treeee9ad448f61ebd1de70ba642d86809d604a33b8d /src
parent06fee25ae66aa6aac9955731b684fc3323de830f (diff)
downloadPROJ-dccf4658ac4cf9194682350ec292a086a2bb24a1.tar.gz
PROJ-dccf4658ac4cf9194682350ec292a086a2bb24a1.zip
experimental C API: add proj_obj_convert_conversion_to_other_method()
Diffstat (limited to 'src')
-rw-r--r--src/c_api.cpp67
-rw-r--r--src/proj_experimental.h5
2 files changed, 72 insertions, 0 deletions
diff --git a/src/c_api.cpp b/src/c_api.cpp
index a5ed1509..fed91750 100644
--- a/src/c_api.cpp
+++ b/src/c_api.cpp
@@ -55,6 +55,7 @@
#include "proj_experimental.h"
#include "projects.h"
// clang-format on
+#include "proj_constants.h"
using namespace NS_PROJ::common;
using namespace NS_PROJ::crs;
@@ -2526,6 +2527,72 @@ PJ_OBJ *proj_obj_create_conversion(PJ_CONTEXT *ctx, const char *name,
// ---------------------------------------------------------------------------
+/**
+ * \brief Return an equivalent projection.
+ *
+ * Currently implemented:
+ * <ul>
+ * <li>EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP) to
+ * EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP)</li>
+ * <li>EPSG_CODE_METHOD_MERCATOR_VARIANT_B (2SP) to
+ * EPSG_CODE_METHOD_MERCATOR_VARIANT_A (1SP)</li>
+ * <li>EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP to
+ * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP</li>
+ * <li>EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP to
+ * EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP</li>
+ * </ul>
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param conversion Object of type Conversion. Must not be NULL.
+ * @param new_method_epsg_code EPSG code of the target method. Or 0 (in which
+ * case new_method_name must be specified).
+ * @param new_method_name EPSG or PROJ target method name. Or nullptr (in which
+ * case new_method_epsg_code must be specified).
+ * @return new conversion that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_convert_conversion_to_other_method(
+ PJ_CONTEXT *ctx, const PJ_OBJ *conversion, int new_method_epsg_code,
+ const char *new_method_name) {
+ SANITIZE_CTX(ctx);
+ auto conv = dynamic_cast<const Conversion *>(conversion->obj.get());
+ if (!conv) {
+ proj_log_error(ctx, __FUNCTION__, "not a Conversion");
+ return nullptr;
+ }
+ if (new_method_epsg_code == 0) {
+ if (!new_method_name) {
+ return nullptr;
+ }
+ if (metadata::Identifier::isEquivalentName(
+ new_method_name, EPSG_NAME_METHOD_MERCATOR_VARIANT_A)) {
+ new_method_epsg_code = EPSG_CODE_METHOD_MERCATOR_VARIANT_A;
+ } else if (metadata::Identifier::isEquivalentName(
+ new_method_name, EPSG_NAME_METHOD_MERCATOR_VARIANT_B)) {
+ new_method_epsg_code = EPSG_CODE_METHOD_MERCATOR_VARIANT_B;
+ } else if (metadata::Identifier::isEquivalentName(
+ new_method_name,
+ EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_1SP)) {
+ new_method_epsg_code = EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP;
+ } else if (metadata::Identifier::isEquivalentName(
+ new_method_name,
+ EPSG_NAME_METHOD_LAMBERT_CONIC_CONFORMAL_2SP)) {
+ new_method_epsg_code = EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_2SP;
+ }
+ }
+ try {
+ auto new_conv = conv->convertToOtherMethod(new_method_epsg_code);
+ if (!new_conv)
+ return nullptr;
+ return PJ_OBJ::create(NN_NO_CHECK(new_conv));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
static CoordinateSystemAxisNNPtr createAxis(const PJ_AXIS_DESCRIPTION &axis) {
diff --git a/src/proj_experimental.h b/src/proj_experimental.h
index 19cde6fc..b8c37054 100644
--- a/src/proj_experimental.h
+++ b/src/proj_experimental.h
@@ -227,6 +227,11 @@ PJ_OBJ PROJ_DLL *proj_obj_create_conversion(PJ_CONTEXT *ctx,
int param_count,
const PJ_PARAM_DESCRIPTION* params);
+PJ_OBJ PROJ_DLL *proj_obj_convert_conversion_to_other_method(PJ_CONTEXT *ctx,
+ const PJ_OBJ *conversion,
+ int new_method_epsg_code,
+ const char *new_method_name);
+
PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs(PJ_CONTEXT *ctx,
const char* crs_name,
const PJ_OBJ* geodetic_crs,