aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@mines-paris.org>2018-12-03 17:20:48 +0100
committerGitHub <noreply@github.com>2018-12-03 17:20:48 +0100
commitd0506e19a71888f7f0c3aa8618d919624e754c4d (patch)
tree4468cd5ef29f3f7f6ce2ed950b5d1938cfbf84b5 /src
parent4794d755a8dea4f4501c61e896e1829bb720e69a (diff)
parentba111ac8323ff194039a06db87d1fb17ed8175b3 (diff)
downloadPROJ-d0506e19a71888f7f0c3aa8618d919624e754c4d.tar.gz
PROJ-d0506e19a71888f7f0c3aa8618d919624e754c4d.zip
Merge pull request #1182 from rouault/plug_new_code
Remove data/epsg, IGNF and esri.* files / support legacy +init=epsg:XXXX syntax
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/bin_cs2cs.cmake2
-rw-r--r--src/c_api.cpp4720
-rw-r--r--src/coordinateoperation.cpp362
-rw-r--r--src/coordinatesystem.cpp97
-rw-r--r--src/crs.cpp313
-rw-r--r--src/cs2cs.c463
-rw-r--r--src/cs2cs.cpp636
-rw-r--r--src/emess.h8
-rw-r--r--src/factory.cpp47
-rw-r--r--src/gie.c646
-rw-r--r--src/io.cpp802
-rw-r--r--src/lib_proj.cmake3
-rw-r--r--src/pj_apply_gridshift.c2
-rw-r--r--src/pj_ctx.c3
-rw-r--r--src/pj_fwd.c9
-rw-r--r--src/pj_init.c102
-rw-r--r--src/pj_transform.c6
-rw-r--r--src/proj.h875
-rw-r--r--src/proj_4D_api.c234
-rw-r--r--src/proj_experimental.h831
-rw-r--r--src/proj_symbol_rename.h12
-rw-r--r--src/projects.h13
-rw-r--r--src/projinfo.cpp68
-rw-r--r--src/rtodms.c7
25 files changed, 6611 insertions, 3654 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 81524e82..99158f02 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,7 @@ AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \
-DMUTEX_@MUTEX_SETTING@ @JNI_INCLUDE@ -I$(top_srcdir)/include @SQLITE3_FLAGS@
AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@ -DPROJ_COMPILATION
-include_HEADERS = proj.h proj_constants.h proj_api.h geodesic.h \
+include_HEADERS = proj.h proj_experimental.h proj_constants.h proj_api.h geodesic.h \
org_proj4_PJ.h proj_symbol_rename.h
EXTRA_DIST = bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \
@@ -19,7 +19,7 @@ EXTRA_DIST = bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \
proj_SOURCES = proj.c gen_cheb.c p_series.c
projinfo_SOURCES = projinfo.cpp
-cs2cs_SOURCES = cs2cs.c gen_cheb.c p_series.c
+cs2cs_SOURCES = cs2cs.cpp gen_cheb.c p_series.c
cct_SOURCES = cct.c proj_strtod.c proj_strtod.h optargpm.h
nad2bin_SOURCES = nad2bin.c
geod_SOURCES = geod.c geod_set.c geod_interface.c geod_interface.h
diff --git a/src/bin_cs2cs.cmake b/src/bin_cs2cs.cmake
index bdb16e1a..9c013dcc 100644
--- a/src/bin_cs2cs.cmake
+++ b/src/bin_cs2cs.cmake
@@ -1,4 +1,4 @@
-set(CS2CS_SRC cs2cs.c
+set(CS2CS_SRC cs2cs.cpp
gen_cheb.c
p_series.c)
diff --git a/src/c_api.cpp b/src/c_api.cpp
index fbba0f51..7a991765 100644
--- a/src/c_api.cpp
+++ b/src/c_api.cpp
@@ -39,6 +39,7 @@
#include "proj/common.hpp"
#include "proj/coordinateoperation.hpp"
+#include "proj/coordinatesystem.hpp"
#include "proj/crs.hpp"
#include "proj/datum.hpp"
#include "proj/io.hpp"
@@ -51,11 +52,13 @@
// clang-format off
#include "proj_internal.h"
#include "proj.h"
+#include "proj_experimental.h"
#include "projects.h"
// clang-format on
using namespace NS_PROJ::common;
using namespace NS_PROJ::crs;
+using namespace NS_PROJ::cs;
using namespace NS_PROJ::datum;
using namespace NS_PROJ::io;
using namespace NS_PROJ::internal;
@@ -90,19 +93,16 @@ static void PROJ_NO_INLINE proj_log_debug(PJ_CONTEXT *ctx, const char *function,
* Operation. Should be used by at most one thread at a time. */
struct PJ_OBJ {
//! @cond Doxygen_Suppress
- PJ_CONTEXT *ctx;
IdentifiedObjectNNPtr obj;
// cached results
- std::string lastWKT{};
- std::string lastPROJString{};
- bool gridsNeededAsked = false;
- std::vector<GridDescription> gridsNeeded{};
+ mutable std::string lastWKT{};
+ mutable std::string lastPROJString{};
+ mutable bool gridsNeededAsked = false;
+ mutable std::vector<GridDescription> gridsNeeded{};
- explicit PJ_OBJ(PJ_CONTEXT *ctxIn, const IdentifiedObjectNNPtr &objIn)
- : ctx(ctxIn), obj(objIn) {}
- static PJ_OBJ *create(PJ_CONTEXT *ctxIn,
- const IdentifiedObjectNNPtr &objIn);
+ explicit PJ_OBJ(const IdentifiedObjectNNPtr &objIn) : obj(objIn) {}
+ static PJ_OBJ *create(const IdentifiedObjectNNPtr &objIn);
PJ_OBJ(const PJ_OBJ &) = delete;
PJ_OBJ &operator=(const PJ_OBJ &) = delete;
@@ -110,8 +110,8 @@ struct PJ_OBJ {
};
//! @cond Doxygen_Suppress
-PJ_OBJ *PJ_OBJ::create(PJ_CONTEXT *ctxIn, const IdentifiedObjectNNPtr &objIn) {
- return new PJ_OBJ(ctxIn, objIn);
+PJ_OBJ *PJ_OBJ::create(const IdentifiedObjectNNPtr &objIn) {
+ return new PJ_OBJ(objIn);
}
//! @endcond
@@ -120,12 +120,10 @@ PJ_OBJ *PJ_OBJ::create(PJ_CONTEXT *ctxIn, const IdentifiedObjectNNPtr &objIn) {
/** \brief Opaque object representing a set of operation results. */
struct PJ_OBJ_LIST {
//! @cond Doxygen_Suppress
- PJ_CONTEXT *ctx;
std::vector<IdentifiedObjectNNPtr> objects;
- explicit PJ_OBJ_LIST(PJ_CONTEXT *ctxIn,
- std::vector<IdentifiedObjectNNPtr> &&objectsIn)
- : ctx(ctxIn), objects(std::move(objectsIn)) {}
+ explicit PJ_OBJ_LIST(std::vector<IdentifiedObjectNNPtr> &&objectsIn)
+ : objects(std::move(objectsIn)) {}
PJ_OBJ_LIST(const PJ_OBJ_LIST &) = delete;
PJ_OBJ_LIST &operator=(const PJ_OBJ_LIST &) = delete;
@@ -140,11 +138,11 @@ struct PJ_OBJ_LIST {
struct projCppContext {
DatabaseContextNNPtr databaseContext;
- explicit projCppContext(PJ_CONTEXT *ctxt, const char *dbPath = nullptr,
+ explicit projCppContext(PJ_CONTEXT *ctx, const char *dbPath = nullptr,
const char *const *auxDbPaths = nullptr)
: databaseContext(DatabaseContext::create(
dbPath ? dbPath : std::string(), toVector(auxDbPaths))) {
- databaseContext->attachPJContext(ctxt);
+ databaseContext->attachPJContext(ctx);
}
static std::vector<std::string> toVector(const char *const *auxDbPaths) {
@@ -250,6 +248,28 @@ const char *proj_context_get_database_path(PJ_CONTEXT *ctx) {
// ---------------------------------------------------------------------------
+/** \brief Return a metadata from the database.
+ *
+ * The returned pointer remains valid while ctx is valid, and until
+ * proj_context_get_database_metadata() is called.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param key Metadata key. Must not be NULL
+ * @return value, or nullptr
+ */
+const char *proj_context_get_database_metadata(PJ_CONTEXT *ctx,
+ const char *key) {
+ SANITIZE_CTX(ctx);
+ try {
+ return getDBcontext(ctx)->getMetadata(key);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Guess the "dialect" of the WKT string.
*
* @param ctx PROJ context, or NULL for default context
@@ -276,6 +296,43 @@ PJ_GUESSED_WKT_DIALECT proj_context_guess_wkt_dialect(PJ_CONTEXT *ctx,
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+static const char *getOptionValue(const char *option,
+ const char *keyWithEqual) noexcept {
+ if (ci_starts_with(option, keyWithEqual)) {
+ return option + strlen(keyWithEqual);
+ }
+ return nullptr;
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+/** \brief "Clone" an object.
+ *
+ * Technically this just increases the reference counter on the object, since
+ * PJ_OBJ objects are immutable.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object to clone. Must not be NULL.
+ * @return Object that must be unreferenced with proj_obj_unref(), or NULL in
+ * case of error.
+ */
+PJ_OBJ *proj_obj_clone(PJ_CONTEXT *ctx, const PJ_OBJ *obj) {
+ SANITIZE_CTX(ctx);
+ try {
+ return PJ_OBJ::create(obj->obj);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Instanciate an object from a WKT string, PROJ string or object code
* (like "EPSG:4326", "urn:ogc:def:crs:EPSG::4326",
* "urn:ogc:def:coordinateOperation:EPSG::1671").
@@ -287,7 +344,17 @@ PJ_GUESSED_WKT_DIALECT proj_context_guess_wkt_dialect(PJ_CONTEXT *ctx,
*
* @param ctx PROJ context, or NULL for default context
* @param text String (must not be NULL)
- * @param options should be set to NULL for now
+ * @param options null-terminated list of options, or NULL. Currently
+ * supported options are:
+ * <ul>
+ * <li>USE_PROJ4_INIT_RULES=YES/NO. Defaults to NO. When set to YES,
+ * init=epsg:XXXX syntax will be allowed and will be interpreted according to
+ * PROJ.4 and PROJ.5 rules, that is geodeticCRS will have longitude, latitude
+ * order and will expect/output coordinates in radians. ProjectedCRS will have
+ * easting, northing axis order (except the ones with Transverse Mercator South
+ * Orientated projection). In that mode, the epsg:XXXX syntax will be also
+ * interprated the same way.</li>
+ * </ul>
* @return Object that must be unreferenced with proj_obj_unref(), or NULL in
* case of error.
*/
@@ -298,10 +365,22 @@ PJ_OBJ *proj_obj_create_from_user_input(PJ_CONTEXT *ctx, const char *text,
(void)options;
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
+ bool usePROJ4InitRules = false;
+ for (auto iter = options; iter && iter[0]; ++iter) {
+ const char *value;
+ if ((value = getOptionValue(*iter, "USE_PROJ4_INIT_RULES="))) {
+ usePROJ4InitRules = ci_equal(value, "YES");
+ } else {
+ std::string msg("Unknown option :");
+ msg += *iter;
+ proj_log_error(ctx, __FUNCTION__, msg.c_str());
+ return nullptr;
+ }
+ }
auto identifiedObject = nn_dynamic_pointer_cast<IdentifiedObject>(
- createFromUserInput(text, dbContext));
+ createFromUserInput(text, dbContext, usePROJ4InitRules));
if (identifiedObject) {
- return PJ_OBJ::create(ctx, NN_NO_CHECK(identifiedObject));
+ return PJ_OBJ::create(NN_NO_CHECK(identifiedObject));
}
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
@@ -330,10 +409,15 @@ PJ_OBJ *proj_obj_create_from_wkt(PJ_CONTEXT *ctx, const char *wkt,
assert(wkt);
(void)options;
try {
+ WKTParser parser;
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ if (dbContext) {
+ parser.attachDatabaseContext(NN_NO_CHECK(dbContext));
+ }
auto identifiedObject = nn_dynamic_pointer_cast<IdentifiedObject>(
- WKTParser().createFromWKT(wkt));
+ parser.createFromWKT(wkt));
if (identifiedObject) {
- return PJ_OBJ::create(ctx, NN_NO_CHECK(identifiedObject));
+ return PJ_OBJ::create(NN_NO_CHECK(identifiedObject));
}
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
@@ -363,10 +447,15 @@ PJ_OBJ *proj_obj_create_from_proj_string(PJ_CONTEXT *ctx,
(void)options;
assert(proj_string);
try {
+ PROJStringParser parser;
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ if (dbContext) {
+ parser.attachDatabaseContext(NN_NO_CHECK(dbContext));
+ }
auto identifiedObject = nn_dynamic_pointer_cast<IdentifiedObject>(
- PROJStringParser().createFromPROJString(proj_string));
+ parser.createFromPROJString(proj_string));
if (identifiedObject) {
- return PJ_OBJ::create(ctx, NN_NO_CHECK(identifiedObject));
+ return PJ_OBJ::create(NN_NO_CHECK(identifiedObject));
}
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
@@ -423,7 +512,7 @@ PJ_OBJ *proj_obj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name,
.as_nullable();
break;
}
- return PJ_OBJ::create(ctx, NN_NO_CHECK(obj));
+ return PJ_OBJ::create(NN_NO_CHECK(obj));
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
}
@@ -503,6 +592,10 @@ convertPJObjectTypeToObjectType(PJ_OBJ_TYPE type, bool &valid) {
cppType = AuthorityFactory::ObjectType::COMPOUND_CRS;
break;
+ case PJ_OBJ_TYPE_ENGINEERING_CRS:
+ valid = false;
+ break;
+
case PJ_OBJ_TYPE_TEMPORAL_CRS:
valid = false;
break;
@@ -586,7 +679,7 @@ PJ_OBJ_LIST *proj_obj_create_from_name(PJ_CONTEXT *ctx, const char *auth_name,
for (const auto &obj : res) {
objects.push_back(obj);
}
- return new PJ_OBJ_LIST(ctx, std::move(objects));
+ return new PJ_OBJ_LIST(std::move(objects));
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
}
@@ -600,7 +693,7 @@ PJ_OBJ_LIST *proj_obj_create_from_name(PJ_CONTEXT *ctx, const char *auth_name,
* @param obj Object (must not be NULL)
* @return its type.
*/
-PJ_OBJ_TYPE proj_obj_get_type(PJ_OBJ *obj) {
+PJ_OBJ_TYPE proj_obj_get_type(const PJ_OBJ *obj) {
assert(obj);
auto ptr = obj->obj.get();
if (dynamic_cast<Ellipsoid *>(ptr)) {
@@ -657,6 +750,9 @@ PJ_OBJ_TYPE proj_obj_get_type(PJ_OBJ *obj) {
if (dynamic_cast<TemporalCRS *>(ptr)) {
return PJ_OBJ_TYPE_TEMPORAL_CRS;
}
+ if (dynamic_cast<EngineeringCRS *>(ptr)) {
+ return PJ_OBJ_TYPE_ENGINEERING_CRS;
+ }
if (dynamic_cast<BoundCRS *>(ptr)) {
return PJ_OBJ_TYPE_BOUND_CRS;
}
@@ -687,7 +783,7 @@ PJ_OBJ_TYPE proj_obj_get_type(PJ_OBJ *obj) {
* @param obj Object (must not be NULL)
* @return TRUE if it is deprecated, FALSE otherwise
*/
-int proj_obj_is_deprecated(PJ_OBJ *obj) {
+int proj_obj_is_deprecated(const PJ_OBJ *obj) {
assert(obj);
return obj->obj->isDeprecated();
}
@@ -701,7 +797,7 @@ int proj_obj_is_deprecated(PJ_OBJ *obj) {
* @param criterion Comparison criterion
* @return TRUE if they are equivalent
*/
-int proj_obj_is_equivalent_to(PJ_OBJ *obj, PJ_OBJ *other,
+int proj_obj_is_equivalent_to(const PJ_OBJ *obj, const PJ_OBJ *other,
PJ_COMPARISON_CRITERION criterion) {
assert(obj);
assert(other);
@@ -738,7 +834,7 @@ int proj_obj_is_equivalent_to(PJ_OBJ *obj, PJ_OBJ *other,
*
* @param obj Object (must not be NULL)
*/
-int proj_obj_is_crs(PJ_OBJ *obj) {
+int proj_obj_is_crs(const PJ_OBJ *obj) {
assert(obj);
return dynamic_cast<CRS *>(obj->obj.get()) != nullptr;
}
@@ -752,7 +848,7 @@ int proj_obj_is_crs(PJ_OBJ *obj) {
* @param obj Object (must not be NULL)
* @return a string, or NULL in case of error or missing name.
*/
-const char *proj_obj_get_name(PJ_OBJ *obj) {
+const char *proj_obj_get_name(const PJ_OBJ *obj) {
assert(obj);
const auto &desc = obj->obj->name()->description();
if (!desc.has_value()) {
@@ -773,7 +869,7 @@ const char *proj_obj_get_name(PJ_OBJ *obj) {
* @param index Index of the identifier. 0 = first identifier
* @return a string, or NULL in case of error or missing name.
*/
-const char *proj_obj_get_id_auth_name(PJ_OBJ *obj, int index) {
+const char *proj_obj_get_id_auth_name(const PJ_OBJ *obj, int index) {
assert(obj);
const auto &ids = obj->obj->identifiers();
if (static_cast<size_t>(index) >= ids.size()) {
@@ -798,7 +894,7 @@ const char *proj_obj_get_id_auth_name(PJ_OBJ *obj, int index) {
* @param index Index of the identifier. 0 = first identifier
* @return a string, or NULL in case of error or missing name.
*/
-const char *proj_obj_get_id_code(PJ_OBJ *obj, int index) {
+const char *proj_obj_get_id_code(const PJ_OBJ *obj, int index) {
assert(obj);
const auto &ids = obj->obj->identifiers();
if (static_cast<size_t>(index) >= ids.size()) {
@@ -809,18 +905,6 @@ const char *proj_obj_get_id_code(PJ_OBJ *obj, int index) {
// ---------------------------------------------------------------------------
-//! @cond Doxygen_Suppress
-static const char *getOptionValue(const char *option,
- const char *keyWithEqual) noexcept {
- if (ci_starts_with(option, keyWithEqual)) {
- return option + strlen(keyWithEqual);
- }
- return nullptr;
-}
-//! @endcond
-
-// ---------------------------------------------------------------------------
-
/** \brief Get a WKT representation of an object.
*
* The returned string is valid while the input obj parameter is valid,
@@ -831,6 +915,7 @@ static const char *getOptionValue(const char *option,
* This function may return NULL if the object is not compatible with an
* export to the requested type.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Object (must not be NULL)
* @param type WKT version.
* @param options null-terminated list of options, or NULL. Currently
@@ -846,8 +931,9 @@ static const char *getOptionValue(const char *option,
* </ul>
* @return a string, or NULL in case of error.
*/
-const char *proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
- const char *const *options) {
+const char *proj_obj_as_wkt(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ PJ_WKT_TYPE type, const char *const *options) {
+ SANITIZE_CTX(ctx);
assert(obj);
// Make sure that the C and C++ enumerations match
@@ -885,7 +971,8 @@ const char *proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
const WKTFormatter::Convention convention =
static_cast<WKTFormatter::Convention>(type);
try {
- auto formatter = WKTFormatter::create(convention);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ auto formatter = WKTFormatter::create(convention, dbContext);
for (auto iter = options; iter && iter[0]; ++iter) {
const char *value;
if ((value = getOptionValue(*iter, "MULTILINE="))) {
@@ -902,14 +989,14 @@ const char *proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
} else {
std::string msg("Unknown option :");
msg += *iter;
- proj_log_error(obj->ctx, __FUNCTION__, msg.c_str());
+ proj_log_error(ctx, __FUNCTION__, msg.c_str());
return nullptr;
}
}
obj->lastWKT = obj->obj->exportToWKT(formatter.get());
return obj->lastWKT.c_str();
} catch (const std::exception &e) {
- proj_log_error(obj->ctx, __FUNCTION__, e.what());
+ proj_log_error(ctx, __FUNCTION__, e.what());
return nullptr;
}
}
@@ -928,6 +1015,7 @@ const char *proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
* This function may return NULL if the object is not compatible with an
* export to the requested type.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Object (must not be NULL)
* @param type PROJ String version.
* @param options NULL-terminated list of strings with "KEY=VALUE" format. or
@@ -937,14 +1025,15 @@ const char *proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
* use of etmerc by utm conversions)
* @return a string, or NULL in case of error.
*/
-const char *proj_obj_as_proj_string(PJ_OBJ *obj, PJ_PROJ_STRING_TYPE type,
+const char *proj_obj_as_proj_string(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ PJ_PROJ_STRING_TYPE type,
const char *const *options) {
+ SANITIZE_CTX(ctx);
assert(obj);
auto exportable =
dynamic_cast<const IPROJStringExportable *>(obj->obj.get());
if (!exportable) {
- proj_log_error(obj->ctx, __FUNCTION__,
- "Object type not exportable to PROJ");
+ proj_log_error(ctx, __FUNCTION__, "Object type not exportable to PROJ");
return nullptr;
}
// Make sure that the C and C++ enumeration match
@@ -963,7 +1052,7 @@ const char *proj_obj_as_proj_string(PJ_OBJ *obj, PJ_PROJ_STRING_TYPE type,
}
const PROJStringFormatter::Convention convention =
static_cast<PROJStringFormatter::Convention>(type);
- auto dbContext = getDBcontextNoException(obj->ctx, __FUNCTION__);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
auto formatter = PROJStringFormatter::create(convention, dbContext);
if (options != nullptr && options[0] != nullptr) {
@@ -976,7 +1065,7 @@ const char *proj_obj_as_proj_string(PJ_OBJ *obj, PJ_PROJ_STRING_TYPE type,
obj->lastPROJString = exportable->exportToPROJString(formatter.get());
return obj->lastPROJString.c_str();
} catch (const std::exception &e) {
- proj_log_error(obj->ctx, __FUNCTION__, e.what());
+ proj_log_error(ctx, __FUNCTION__, e.what());
return nullptr;
}
}
@@ -985,29 +1074,34 @@ const char *proj_obj_as_proj_string(PJ_OBJ *obj, PJ_PROJ_STRING_TYPE type,
/** \brief Return the area of use of an object.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Object (must not be NULL)
- * @param p_west_lon Pointer to a double to receive the west longitude (in
- * degrees). Or NULL. If the returned value is -1000, the bounding box is
+ * @param out_west_lon_degree Pointer to a double to receive the west longitude
+ * (in degrees). Or NULL. If the returned value is -1000, the bounding box is
* unknown.
- * @param p_south_lat Pointer to a double to receive the south latitude (in
- * degrees). Or NULL. If the returned value is -1000, the bounding box is
+ * @param out_south_lat_degree Pointer to a double to receive the south latitude
+ * (in degrees). Or NULL. If the returned value is -1000, the bounding box is
* unknown.
- * @param p_east_lon Pointer to a double to receive the east longitude (in
- * degrees). Or NULL. If the returned value is -1000, the bounding box is
+ * @param out_east_lon_degree Pointer to a double to receive the east longitude
+ * (in degrees). Or NULL. If the returned value is -1000, the bounding box is
* unknown.
- * @param p_north_lat Pointer to a double to receive the north latitude (in
- * degrees). Or NULL. If the returned value is -1000, the bounding box is
+ * @param out_north_lat_degree Pointer to a double to receive the north latitude
+ * (in degrees). Or NULL. If the returned value is -1000, the bounding box is
* unknown.
- * @param p_area_name Pointer to a string to receive the name of the area of
+ * @param out_area_name Pointer to a string to receive the name of the area of
* use. Or NULL. *p_area_name is valid while obj is valid itself.
* @return TRUE in case of success, FALSE in case of error or if the area
* of use is unknown.
*/
-int proj_obj_get_area_of_use(PJ_OBJ *obj, double *p_west_lon,
- double *p_south_lat, double *p_east_lon,
- double *p_north_lat, const char **p_area_name) {
- if (p_area_name) {
- *p_area_name = nullptr;
+int proj_obj_get_area_of_use(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ double *out_west_lon_degree,
+ double *out_south_lat_degree,
+ double *out_east_lon_degree,
+ double *out_north_lat_degree,
+ const char **out_area_name) {
+ (void)ctx;
+ if (out_area_name) {
+ *out_area_name = nullptr;
}
auto objectUsage = dynamic_cast<const ObjectUsage *>(obj->obj.get());
if (!objectUsage) {
@@ -1022,8 +1116,8 @@ int proj_obj_get_area_of_use(PJ_OBJ *obj, double *p_west_lon,
return false;
}
const auto &desc = extent->description();
- if (desc.has_value() && p_area_name) {
- *p_area_name = desc->c_str();
+ if (desc.has_value() && out_area_name) {
+ *out_area_name = desc->c_str();
}
const auto &geogElements = extent->geographicElements();
@@ -1031,48 +1125,49 @@ int proj_obj_get_area_of_use(PJ_OBJ *obj, double *p_west_lon,
auto bbox =
dynamic_cast<const GeographicBoundingBox *>(geogElements[0].get());
if (bbox) {
- if (p_west_lon) {
- *p_west_lon = bbox->westBoundLongitude();
+ if (out_west_lon_degree) {
+ *out_west_lon_degree = bbox->westBoundLongitude();
}
- if (p_south_lat) {
- *p_south_lat = bbox->southBoundLatitude();
+ if (out_south_lat_degree) {
+ *out_south_lat_degree = bbox->southBoundLatitude();
}
- if (p_east_lon) {
- *p_east_lon = bbox->eastBoundLongitude();
+ if (out_east_lon_degree) {
+ *out_east_lon_degree = bbox->eastBoundLongitude();
}
- if (p_north_lat) {
- *p_north_lat = bbox->northBoundLatitude();
+ if (out_north_lat_degree) {
+ *out_north_lat_degree = bbox->northBoundLatitude();
}
return true;
}
}
- if (p_west_lon) {
- *p_west_lon = -1000;
+ if (out_west_lon_degree) {
+ *out_west_lon_degree = -1000;
}
- if (p_south_lat) {
- *p_south_lat = -1000;
+ if (out_south_lat_degree) {
+ *out_south_lat_degree = -1000;
}
- if (p_east_lon) {
- *p_east_lon = -1000;
+ if (out_east_lon_degree) {
+ *out_east_lon_degree = -1000;
}
- if (p_north_lat) {
- *p_north_lat = -1000;
+ if (out_north_lat_degree) {
+ *out_north_lat_degree = -1000;
}
return true;
}
// ---------------------------------------------------------------------------
-static const GeodeticCRS *extractGeodeticCRS(PJ_OBJ *crs, const char *fname) {
+static const GeodeticCRS *extractGeodeticCRS(PJ_CONTEXT *ctx, const PJ_OBJ *crs,
+ const char *fname) {
assert(crs);
auto l_crs = dynamic_cast<const CRS *>(crs->obj.get());
if (!l_crs) {
- proj_log_error(crs->ctx, fname, "Object is not a CRS");
+ proj_log_error(ctx, fname, "Object is not a CRS");
return nullptr;
}
auto geodCRS = l_crs->extractGeodeticCRSRaw();
if (!geodCRS) {
- proj_log_error(crs->ctx, fname, "CRS has no geodetic CRS");
+ proj_log_error(ctx, fname, "CRS has no geodetic CRS");
}
return geodCRS;
}
@@ -1085,18 +1180,19 @@ static const GeodeticCRS *extractGeodeticCRS(PJ_OBJ *crs, const char *fname) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param crs Objet of type CRS (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_crs_get_geodetic_crs(PJ_OBJ *crs) {
- auto geodCRS = extractGeodeticCRS(crs, __FUNCTION__);
+PJ_OBJ *proj_obj_crs_get_geodetic_crs(PJ_CONTEXT *ctx, const PJ_OBJ *crs) {
+ SANITIZE_CTX(ctx);
+ auto geodCRS = extractGeodeticCRS(ctx, crs, __FUNCTION__);
if (!geodCRS) {
return nullptr;
}
- return PJ_OBJ::create(crs->ctx,
- NN_NO_CHECK(nn_dynamic_pointer_cast<IdentifiedObject>(
- geodCRS->shared_from_this())));
+ return PJ_OBJ::create(NN_NO_CHECK(nn_dynamic_pointer_cast<IdentifiedObject>(
+ geodCRS->shared_from_this())));
}
// ---------------------------------------------------------------------------
@@ -1107,24 +1203,75 @@ PJ_OBJ *proj_obj_crs_get_geodetic_crs(PJ_OBJ *crs) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param crs Objet of type CRS (must not be NULL)
* @param index Index of the CRS component (typically 0 = horizontal, 1 =
* vertical)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_crs_get_sub_crs(PJ_OBJ *crs, int index) {
+PJ_OBJ *proj_obj_crs_get_sub_crs(PJ_CONTEXT *ctx, const PJ_OBJ *crs,
+ int index) {
+ SANITIZE_CTX(ctx);
assert(crs);
auto l_crs = dynamic_cast<CompoundCRS *>(crs->obj.get());
if (!l_crs) {
- proj_log_error(crs->ctx, __FUNCTION__, "Object is not a CompoundCRS");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CompoundCRS");
return nullptr;
}
const auto &components = l_crs->componentReferenceSystems();
if (static_cast<size_t>(index) >= components.size()) {
return nullptr;
}
- return PJ_OBJ::create(crs->ctx, components[index]);
+ return PJ_OBJ::create(components[index]);
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns a BoundCRS
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param base_crs Base CRS (must not be NULL)
+ * @param hub_crs Hub CRS (must not be NULL)
+ * @param transformation Transformation (must not be NULL)
+ * @return Object that must be unreferenced with proj_obj_unref(), or NULL
+ * in case of error.
+ */
+PJ_OBJ *proj_obj_crs_create_bound_crs(PJ_CONTEXT *ctx, const PJ_OBJ *base_crs,
+ const PJ_OBJ *hub_crs,
+ const PJ_OBJ *transformation) {
+ SANITIZE_CTX(ctx);
+ assert(base_crs);
+ assert(hub_crs);
+ assert(transformation);
+ auto l_base_crs = util::nn_dynamic_pointer_cast<CRS>(base_crs->obj);
+ if (!l_base_crs) {
+ proj_log_error(ctx, __FUNCTION__, "base_crs is not a CRS");
+ return nullptr;
+ }
+ auto l_hub_crs = util::nn_dynamic_pointer_cast<CRS>(hub_crs->obj);
+ if (!l_hub_crs) {
+ proj_log_error(ctx, __FUNCTION__, "hub_crs is not a CRS");
+ return nullptr;
+ }
+ auto l_transformation =
+ util::nn_dynamic_pointer_cast<Transformation>(transformation->obj);
+ if (!l_transformation) {
+ proj_log_error(ctx, __FUNCTION__, "transformation is not a CRS");
+ return nullptr;
+ }
+ try {
+ return PJ_OBJ::create(BoundCRS::create(NN_NO_CHECK(l_base_crs),
+ NN_NO_CHECK(l_hub_crs),
+ NN_NO_CHECK(l_transformation)));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
}
// ---------------------------------------------------------------------------
@@ -1139,20 +1286,28 @@ PJ_OBJ *proj_obj_crs_get_sub_crs(PJ_OBJ *crs, int index) {
* This is the same as method
* osgeo::proj::crs::CRS::createBoundCRSToWGS84IfPossible()
*
+ * @param ctx PROJ context, or NULL for default context
* @param crs Objet of type CRS (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_crs_create_bound_crs_to_WGS84(PJ_OBJ *crs) {
+PJ_OBJ *proj_obj_crs_create_bound_crs_to_WGS84(PJ_CONTEXT *ctx,
+ const PJ_OBJ *crs) {
+ SANITIZE_CTX(ctx);
assert(crs);
auto l_crs = dynamic_cast<const CRS *>(crs->obj.get());
if (!l_crs) {
- proj_log_error(crs->ctx, __FUNCTION__, "Object is not a CRS");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CRS");
+ return nullptr;
+ }
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ try {
+ return PJ_OBJ::create(
+ l_crs->createBoundCRSToWGS84IfPossible(dbContext));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
return nullptr;
}
- auto dbContext = getDBcontextNoException(crs->ctx, __FUNCTION__);
- return PJ_OBJ::create(crs->ctx,
- l_crs->createBoundCRSToWGS84IfPossible(dbContext));
}
// ---------------------------------------------------------------------------
@@ -1163,24 +1318,26 @@ PJ_OBJ *proj_obj_crs_create_bound_crs_to_WGS84(PJ_OBJ *crs) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Objet of type CRS or GeodeticReferenceFrame (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_get_ellipsoid(PJ_OBJ *obj) {
+PJ_OBJ *proj_obj_get_ellipsoid(PJ_CONTEXT *ctx, const PJ_OBJ *obj) {
+ SANITIZE_CTX(ctx);
auto ptr = obj->obj.get();
if (dynamic_cast<const CRS *>(ptr)) {
- auto geodCRS = extractGeodeticCRS(obj, __FUNCTION__);
+ auto geodCRS = extractGeodeticCRS(ctx, obj, __FUNCTION__);
if (geodCRS) {
- return PJ_OBJ::create(obj->ctx, geodCRS->ellipsoid());
+ return PJ_OBJ::create(geodCRS->ellipsoid());
}
} else {
auto datum = dynamic_cast<const GeodeticReferenceFrame *>(ptr);
if (datum) {
- return PJ_OBJ::create(obj->ctx, datum->ellipsoid());
+ return PJ_OBJ::create(datum->ellipsoid());
}
}
- proj_log_error(obj->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a CRS or GeodeticReferenceFrame");
return nullptr;
}
@@ -1193,25 +1350,27 @@ PJ_OBJ *proj_obj_get_ellipsoid(PJ_OBJ *obj) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param crs Objet of type CRS (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_crs_get_horizontal_datum(PJ_OBJ *crs) {
- auto geodCRS = extractGeodeticCRS(crs, __FUNCTION__);
+PJ_OBJ *proj_obj_crs_get_horizontal_datum(PJ_CONTEXT *ctx, const PJ_OBJ *crs) {
+ SANITIZE_CTX(ctx);
+ auto geodCRS = extractGeodeticCRS(ctx, crs, __FUNCTION__);
if (!geodCRS) {
return nullptr;
}
const auto &datum = geodCRS->datum();
if (datum) {
- return PJ_OBJ::create(crs->ctx, NN_NO_CHECK(datum));
+ return PJ_OBJ::create(NN_NO_CHECK(datum));
}
const auto &datumEnsemble = geodCRS->datumEnsemble();
if (datumEnsemble) {
- return PJ_OBJ::create(crs->ctx, NN_NO_CHECK(datumEnsemble));
+ return PJ_OBJ::create(NN_NO_CHECK(datumEnsemble));
}
- proj_log_error(crs->ctx, __FUNCTION__, "CRS has no datum");
+ proj_log_error(ctx, __FUNCTION__, "CRS has no datum");
return nullptr;
}
@@ -1219,42 +1378,48 @@ PJ_OBJ *proj_obj_crs_get_horizontal_datum(PJ_OBJ *crs) {
/** \brief Return ellipsoid parameters.
*
+ * @param ctx PROJ context, or NULL for default context
* @param ellipsoid Object of type Ellipsoid (must not be NULL)
- * @param pSemiMajorMetre Pointer to a value to store the semi-major axis in
+ * @param out_semi_major_metre Pointer to a value to store the semi-major axis
+ * in
* metre. or NULL
- * @param pSemiMinorMetre Pointer to a value to store the semi-minor axis in
+ * @param out_semi_minor_metre Pointer to a value to store the semi-minor axis
+ * in
* metre. or NULL
- * @param pIsSemiMinorComputed Pointer to a boolean value to indicate if the
+ * @param out_is_semi_minor_computed Pointer to a boolean value to indicate if
+ * the
* semi-minor value was computed. If FALSE, its value comes from the
* definition. or NULL
- * @param pInverseFlattening Pointer to a value to store the inverse
+ * @param out_inv_flattening Pointer to a value to store the inverse
* flattening. or NULL
* @return TRUE in case of success.
*/
-int proj_obj_ellipsoid_get_parameters(PJ_OBJ *ellipsoid,
- double *pSemiMajorMetre,
- double *pSemiMinorMetre,
- int *pIsSemiMinorComputed,
- double *pInverseFlattening) {
+int proj_obj_ellipsoid_get_parameters(PJ_CONTEXT *ctx, const PJ_OBJ *ellipsoid,
+ double *out_semi_major_metre,
+ double *out_semi_minor_metre,
+ int *out_is_semi_minor_computed,
+ double *out_inv_flattening) {
+ SANITIZE_CTX(ctx);
assert(ellipsoid);
auto l_ellipsoid = dynamic_cast<const Ellipsoid *>(ellipsoid->obj.get());
if (!l_ellipsoid) {
- proj_log_error(ellipsoid->ctx, __FUNCTION__,
- "Object is not a Ellipsoid");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a Ellipsoid");
return FALSE;
}
- if (pSemiMajorMetre) {
- *pSemiMajorMetre = l_ellipsoid->semiMajorAxis().getSIValue();
+ if (out_semi_major_metre) {
+ *out_semi_major_metre = l_ellipsoid->semiMajorAxis().getSIValue();
}
- if (pSemiMinorMetre) {
- *pSemiMinorMetre = l_ellipsoid->computeSemiMinorAxis().getSIValue();
+ if (out_semi_minor_metre) {
+ *out_semi_minor_metre =
+ l_ellipsoid->computeSemiMinorAxis().getSIValue();
}
- if (pIsSemiMinorComputed) {
- *pIsSemiMinorComputed = !(l_ellipsoid->semiMinorAxis().has_value());
+ if (out_is_semi_minor_computed) {
+ *out_is_semi_minor_computed =
+ !(l_ellipsoid->semiMinorAxis().has_value());
}
- if (pInverseFlattening) {
- *pInverseFlattening = l_ellipsoid->computedInverseFlattening();
+ if (out_inv_flattening) {
+ *out_inv_flattening = l_ellipsoid->computedInverseFlattening();
}
return TRUE;
}
@@ -1267,25 +1432,27 @@ int proj_obj_ellipsoid_get_parameters(PJ_OBJ *ellipsoid,
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Objet of type CRS or GeodeticReferenceFrame (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error.
*/
-PJ_OBJ *proj_obj_get_prime_meridian(PJ_OBJ *obj) {
+PJ_OBJ *proj_obj_get_prime_meridian(PJ_CONTEXT *ctx, const PJ_OBJ *obj) {
+ SANITIZE_CTX(ctx);
auto ptr = obj->obj.get();
if (dynamic_cast<CRS *>(ptr)) {
- auto geodCRS = extractGeodeticCRS(obj, __FUNCTION__);
+ auto geodCRS = extractGeodeticCRS(ctx, obj, __FUNCTION__);
if (geodCRS) {
- return PJ_OBJ::create(obj->ctx, geodCRS->primeMeridian());
+ return PJ_OBJ::create(geodCRS->primeMeridian());
}
} else {
auto datum = dynamic_cast<const GeodeticReferenceFrame *>(ptr);
if (datum) {
- return PJ_OBJ::create(obj->ctx, datum->primeMeridian());
+ return PJ_OBJ::create(datum->primeMeridian());
}
}
- proj_log_error(obj->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a CRS or GeodeticReferenceFrame");
return nullptr;
}
@@ -1294,69 +1461,77 @@ PJ_OBJ *proj_obj_get_prime_meridian(PJ_OBJ *obj) {
/** \brief Return prime meridian parameters.
*
+ * @param ctx PROJ context, or NULL for default context
* @param prime_meridian Object of type PrimeMeridian (must not be NULL)
- * @param pLongitude Pointer to a value to store the longitude of the prime
+ * @param out_longitude Pointer to a value to store the longitude of the prime
* meridian, in its native unit. or NULL
- * @param pLongitudeUnitConvFactor Pointer to a value to store the conversion
+ * @param out_unit_conv_factor Pointer to a value to store the conversion
* factor of the prime meridian longitude unit to radian. or NULL
- * @param pLongitudeUnitName Pointer to a string value to store the unit name.
+ * @param out_unit_name Pointer to a string value to store the unit name.
* or NULL
* @return TRUE in case of success.
*/
-int proj_obj_prime_meridian_get_parameters(PJ_OBJ *prime_meridian,
- double *pLongitude,
- double *pLongitudeUnitConvFactor,
- const char **pLongitudeUnitName) {
+int proj_obj_prime_meridian_get_parameters(PJ_CONTEXT *ctx,
+ const PJ_OBJ *prime_meridian,
+ double *out_longitude,
+ double *out_unit_conv_factor,
+ const char **out_unit_name) {
+ SANITIZE_CTX(ctx);
assert(prime_meridian);
auto l_pm = dynamic_cast<const PrimeMeridian *>(prime_meridian->obj.get());
if (!l_pm) {
- proj_log_error(prime_meridian->ctx, __FUNCTION__,
- "Object is not a PrimeMeridian");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a PrimeMeridian");
return false;
}
const auto &longitude = l_pm->longitude();
- if (pLongitude) {
- *pLongitude = longitude.value();
+ if (out_longitude) {
+ *out_longitude = longitude.value();
}
const auto &unit = longitude.unit();
- if (pLongitudeUnitConvFactor) {
- *pLongitudeUnitConvFactor = unit.conversionToSI();
+ if (out_unit_conv_factor) {
+ *out_unit_conv_factor = unit.conversionToSI();
}
- if (pLongitudeUnitName) {
- *pLongitudeUnitName = unit.name().c_str();
+ if (out_unit_name) {
+ *out_unit_name = unit.name().c_str();
}
return true;
}
// ---------------------------------------------------------------------------
-/** \brief Return the base CRS of a BoundCRS or the source CRS of a
- * CoordinateOperation.
+/** \brief Return the base CRS of a BoundCRS or a DerivedCRS/ProjectedCRS, or
+ * the source CRS of a CoordinateOperation.
*
* The returned object must be unreferenced with proj_obj_unref() after
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Objet of type BoundCRS or CoordinateOperation (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error, or missing source CRS.
*/
-PJ_OBJ *proj_obj_get_source_crs(PJ_OBJ *obj) {
+PJ_OBJ *proj_obj_get_source_crs(PJ_CONTEXT *ctx, const PJ_OBJ *obj) {
+ SANITIZE_CTX(ctx);
assert(obj);
auto ptr = obj->obj.get();
auto boundCRS = dynamic_cast<const BoundCRS *>(ptr);
if (boundCRS) {
- return PJ_OBJ::create(obj->ctx, boundCRS->baseCRS());
+ return PJ_OBJ::create(boundCRS->baseCRS());
+ }
+ auto derivedCRS = dynamic_cast<const DerivedCRS *>(ptr);
+ if (derivedCRS) {
+ return PJ_OBJ::create(derivedCRS->baseCRS());
}
auto co = dynamic_cast<const CoordinateOperation *>(ptr);
if (co) {
auto sourceCRS = co->sourceCRS();
if (sourceCRS) {
- return PJ_OBJ::create(obj->ctx, NN_NO_CHECK(sourceCRS));
+ return PJ_OBJ::create(NN_NO_CHECK(sourceCRS));
}
return nullptr;
}
- proj_log_error(obj->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a BoundCRS or a CoordinateOperation");
return nullptr;
}
@@ -1370,26 +1545,28 @@ PJ_OBJ *proj_obj_get_source_crs(PJ_OBJ *obj) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Objet of type BoundCRS or CoordinateOperation (must not be NULL)
* @return Object that must be unreferenced with proj_obj_unref(), or NULL
* in case of error, or missing target CRS.
*/
-PJ_OBJ *proj_obj_get_target_crs(PJ_OBJ *obj) {
+PJ_OBJ *proj_obj_get_target_crs(PJ_CONTEXT *ctx, const PJ_OBJ *obj) {
+ SANITIZE_CTX(ctx);
assert(obj);
auto ptr = obj->obj.get();
auto boundCRS = dynamic_cast<const BoundCRS *>(ptr);
if (boundCRS) {
- return PJ_OBJ::create(obj->ctx, boundCRS->hubCRS());
+ return PJ_OBJ::create(boundCRS->hubCRS());
}
auto co = dynamic_cast<const CoordinateOperation *>(ptr);
if (co) {
auto targetCRS = co->targetCRS();
if (targetCRS) {
- return PJ_OBJ::create(obj->ctx, NN_NO_CHECK(targetCRS));
+ return PJ_OBJ::create(NN_NO_CHECK(targetCRS));
}
return nullptr;
}
- proj_log_error(obj->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a BoundCRS or a CoordinateOperation");
return nullptr;
}
@@ -1415,36 +1592,40 @@ PJ_OBJ *proj_obj_get_target_crs(PJ_OBJ *obj) {
* This is implemented for GeodeticCRS, ProjectedCRS, VerticalCRS and
* CompoundCRS.
*
+ * @param ctx PROJ context, or NULL for default context
* @param obj Object of type CRS. Must not be NULL
* @param auth_name Authority name, or NULL for all authorities
* @param options Placeholder for future options. Should be set to NULL.
- * @param confidence Output parameter. Pointer to an array of integers that will
- * be allocated by the function and filled with the confidence values
+ * @param out_confidence Output parameter. Pointer to an array of integers that
+ * will be allocated by the function and filled with the confidence values
* (0-100). There are as many elements in this array as
* proj_obj_list_get_count()
* returns on the return value of this function. *confidence should be
* released with proj_free_int_list().
* @return a list of matching reference CRS, or nullptr in case of error.
*/
-PJ_OBJ_LIST *proj_obj_identify(PJ_OBJ *obj, const char *auth_name,
- const char *const *options, int **confidence) {
+PJ_OBJ_LIST *proj_obj_identify(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ const char *auth_name,
+ const char *const *options,
+ int **out_confidence) {
+ SANITIZE_CTX(ctx);
assert(obj);
(void)options;
- if (confidence) {
- *confidence = nullptr;
+ if (out_confidence) {
+ *out_confidence = nullptr;
}
auto ptr = obj->obj.get();
auto crs = dynamic_cast<const CRS *>(ptr);
if (!crs) {
- proj_log_error(obj->ctx, __FUNCTION__, "Object is not a CRS");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CRS");
} else {
int *confidenceTemp = nullptr;
try {
- auto factory = AuthorityFactory::create(getDBcontext(obj->ctx),
+ auto factory = AuthorityFactory::create(getDBcontext(ctx),
auth_name ? auth_name : "");
auto res = crs->identify(factory);
std::vector<IdentifiedObjectNNPtr> objects;
- confidenceTemp = confidence ? new int[res.size()] : nullptr;
+ confidenceTemp = out_confidence ? new int[res.size()] : nullptr;
size_t i = 0;
for (const auto &pair : res) {
objects.push_back(pair.first);
@@ -1453,16 +1634,15 @@ PJ_OBJ_LIST *proj_obj_identify(PJ_OBJ *obj, const char *auth_name,
++i;
}
}
- auto ret = internal::make_unique<PJ_OBJ_LIST>(obj->ctx,
- std::move(objects));
- if (confidence) {
- *confidence = confidenceTemp;
+ auto ret = internal::make_unique<PJ_OBJ_LIST>(std::move(objects));
+ if (out_confidence) {
+ *out_confidence = confidenceTemp;
confidenceTemp = nullptr;
}
return ret.release();
} catch (const std::exception &e) {
delete[] confidenceTemp;
- proj_log_error(obj->ctx, __FUNCTION__, e.what());
+ proj_log_error(ctx, __FUNCTION__, e.what());
}
}
return nullptr;
@@ -1567,19 +1747,22 @@ void proj_free_string_list(PROJ_STRING_LIST list) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param crs Objet of type DerivedCRS or BoundCRSs (must not be NULL)
- * @param pMethodName Pointer to a string value to store the method
+ * @param out_method_name Pointer to a string value to store the method
* (projection) name. or NULL
- * @param pMethodAuthorityName Pointer to a string value to store the method
+ * @param out_method_auth_name Pointer to a string value to store the method
* authority name. or NULL
- * @param pMethodCode Pointer to a string value to store the method
+ * @param out_method_code Pointer to a string value to store the method
* code. or NULL
* @return Object of type SingleOperation that must be unreferenced with
* proj_obj_unref(), or NULL in case of error.
*/
-PJ_OBJ *proj_obj_crs_get_coordoperation(PJ_OBJ *crs, const char **pMethodName,
- const char **pMethodAuthorityName,
- const char **pMethodCode) {
+PJ_OBJ *proj_obj_crs_get_coordoperation(PJ_CONTEXT *ctx, const PJ_OBJ *crs,
+ const char **out_method_name,
+ const char **out_method_auth_name,
+ const char **out_method_code) {
+ SANITIZE_CTX(ctx);
assert(crs);
SingleOperationPtr co;
@@ -1591,7 +1774,7 @@ PJ_OBJ *proj_obj_crs_get_coordoperation(PJ_OBJ *crs, const char **pMethodName,
if (boundCRS) {
co = boundCRS->transformation().as_nullable();
} else {
- proj_log_error(crs->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a DerivedCRS or BoundCRS");
return nullptr;
}
@@ -1599,24 +1782,24 @@ PJ_OBJ *proj_obj_crs_get_coordoperation(PJ_OBJ *crs, const char **pMethodName,
const auto &method = co->method();
const auto &method_ids = method->identifiers();
- if (pMethodName) {
- *pMethodName = method->name()->description()->c_str();
+ if (out_method_name) {
+ *out_method_name = method->name()->description()->c_str();
}
- if (pMethodAuthorityName) {
+ if (out_method_auth_name) {
if (!method_ids.empty()) {
- *pMethodAuthorityName = method_ids[0]->codeSpace()->c_str();
+ *out_method_auth_name = method_ids[0]->codeSpace()->c_str();
} else {
- *pMethodAuthorityName = nullptr;
+ *out_method_auth_name = nullptr;
}
}
- if (pMethodCode) {
+ if (out_method_code) {
if (!method_ids.empty()) {
- *pMethodCode = method_ids[0]->code().c_str();
+ *out_method_code = method_ids[0]->code().c_str();
} else {
- *pMethodCode = nullptr;
+ *out_method_code = nullptr;
}
}
- return PJ_OBJ::create(crs->ctx, NN_NO_CHECK(co));
+ return PJ_OBJ::create(NN_NO_CHECK(co));
}
// ---------------------------------------------------------------------------
@@ -1630,8 +1813,9 @@ static PropertyMap createPropertyMapName(const char *name) {
// ---------------------------------------------------------------------------
static UnitOfMeasure createLinearUnit(const char *name, double convFactor) {
- return name == nullptr ? UnitOfMeasure::METRE
- : UnitOfMeasure(name, convFactor);
+ return name == nullptr
+ ? UnitOfMeasure::METRE
+ : UnitOfMeasure(name, convFactor, UnitOfMeasure::Type::LINEAR);
}
// ---------------------------------------------------------------------------
@@ -1641,75 +1825,117 @@ static UnitOfMeasure createAngularUnit(const char *name, double convFactor) {
? UnitOfMeasure::DEGREE
: ci_equal(name, "grad")
? UnitOfMeasure::GRAD
- : UnitOfMeasure(name, convFactor))
+ : UnitOfMeasure(name, convFactor,
+ UnitOfMeasure::Type::ANGULAR))
: UnitOfMeasure::DEGREE;
}
+
+// ---------------------------------------------------------------------------
+
+static GeodeticReferenceFrameNNPtr createGeodeticReferenceFrame(
+ PJ_CONTEXT *ctx, const char *datum_name, const char *ellps_name,
+ double semi_major_metre, double inv_flattening,
+ const char *prime_meridian_name, double prime_meridian_offset,
+ const char *angular_units, double angular_units_conv) {
+ const UnitOfMeasure angUnit(
+ createAngularUnit(angular_units, angular_units_conv));
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
+ auto body = Ellipsoid::guessBodyName(dbContext, semi_major_metre);
+ auto ellpsName = createPropertyMapName(ellps_name);
+ auto ellps = inv_flattening != 0.0
+ ? Ellipsoid::createFlattenedSphere(
+ ellpsName, Length(semi_major_metre),
+ Scale(inv_flattening), body)
+ : Ellipsoid::createSphere(ellpsName,
+ Length(semi_major_metre), body);
+ auto pm = PrimeMeridian::create(
+ PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ prime_meridian_name
+ ? prime_meridian_name
+ : prime_meridian_offset == 0.0
+ ? (ellps->celestialBody() == Ellipsoid::EARTH
+ ? "Greenwich"
+ : "Reference meridian")
+ : "unnamed"),
+ Angle(prime_meridian_offset, angUnit));
+
+ std::string datumName(datum_name ? datum_name : "unnamed");
+ if (datumName == "WGS_1984") {
+ datumName = GeodeticReferenceFrame::EPSG_6326->nameStr();
+ } else if (datumName.find('_') != std::string::npos) {
+ // Likely coming from WKT1
+ if (dbContext) {
+ auto authFactory =
+ AuthorityFactory::create(NN_NO_CHECK(dbContext), std::string());
+ auto res = authFactory->createObjectsFromName(
+ datumName,
+ {AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME}, true,
+ 1);
+ if (!res.empty()) {
+ const auto &refDatum = res.front();
+ if (metadata::Identifier::isEquivalentName(
+ datumName.c_str(), refDatum->nameStr().c_str())) {
+ datumName = refDatum->nameStr();
+ }
+ }
+ }
+ }
+
+ return GeodeticReferenceFrame::create(
+ createPropertyMapName(datumName.c_str()), ellps,
+ util::optional<std::string>(), pm);
+}
+
//! @endcond
// ---------------------------------------------------------------------------
-/** \brief Create a GeographicCRS 2D from its definition.
+/** \brief Create a GeographicCRS.
*
* The returned object must be unreferenced with proj_obj_unref() after
* use.
* It should be used by at most one thread at a time.
*
* @param ctx PROJ context, or NULL for default context
- * @param geogName Name of the GeographicCRS. Or NULL
- * @param datumName Name of the GeodeticReferenceFrame. Or NULL
- * @param ellipsoidName Name of the Ellipsoid. Or NULL
- * @param semiMajorMetre Ellipsoid semi-major axis, in metres.
- * @param invFlattening Ellipsoid inverse flattening. Or 0 for a sphere.
- * @param primeMeridianName Name of the PrimeMeridian. Or NULL
- * @param primeMeridianOffset Offset of the prime meridian, expressed in the
+ * @param crs_name Name of the GeographicCRS. Or NULL
+ * @param datum_name Name of the GeodeticReferenceFrame. Or NULL
+ * @param ellps_name Name of the Ellipsoid. Or NULL
+ * @param semi_major_metre Ellipsoid semi-major axis, in metres.
+ * @param inv_flattening Ellipsoid inverse flattening. Or 0 for a sphere.
+ * @param prime_meridian_name Name of the PrimeMeridian. Or NULL
+ * @param prime_meridian_offset Offset of the prime meridian, expressed in the
* specified angular units.
- * @param angularUnits Name of the angular units. Or NULL for Degree
- * @param angularUnitsConv Conversion factor from the angular unit to radian. Or
- * 0 for Degree if angularUnits == NULL. Otherwise should be not NULL
- * @param latLongOrder TRUE for Latitude Longitude axis order.
+ * @param pm_angular_units Name of the angular units. Or NULL for Degree
+ * @param pm_angular_units_conv Conversion factor from the angular unit to
+ * radian.
+ * Or
+ * 0 for Degree if pm_angular_units == NULL. Otherwise should be not NULL
+ * @param ellipsoidal_cs Coordinate system. Must not be NULL.
*
* @return Object of type GeographicCRS that must be unreferenced with
* proj_obj_unref(), or NULL in case of error.
*/
PJ_OBJ *proj_obj_create_geographic_crs(
- PJ_CONTEXT *ctx, const char *geogName, const char *datumName,
- const char *ellipsoidName, double semiMajorMetre, double invFlattening,
- const char *primeMeridianName, double primeMeridianOffset,
- const char *angularUnits, double angularUnitsConv, int latLongOrder) {
+ PJ_CONTEXT *ctx, const char *crs_name, const char *datum_name,
+ const char *ellps_name, double semi_major_metre, double inv_flattening,
+ const char *prime_meridian_name, double prime_meridian_offset,
+ const char *pm_angular_units, double pm_angular_units_conv,
+ PJ_OBJ *ellipsoidal_cs) {
SANITIZE_CTX(ctx);
+ auto cs = util::nn_dynamic_pointer_cast<EllipsoidalCS>(ellipsoidal_cs->obj);
+ if (!cs) {
+ return nullptr;
+ }
try {
- const UnitOfMeasure angUnit(
- createAngularUnit(angularUnits, angularUnitsConv));
- auto dbContext = getDBcontext(ctx);
- auto body = Ellipsoid::guessBodyName(dbContext, semiMajorMetre);
- auto ellpsName = createPropertyMapName(ellipsoidName);
- auto ellps =
- invFlattening != 0.0
- ? Ellipsoid::createFlattenedSphere(ellpsName,
- Length(semiMajorMetre),
- Scale(invFlattening), body)
- : Ellipsoid::createSphere(ellpsName, Length(semiMajorMetre),
- body);
- auto pm = PrimeMeridian::create(
- PropertyMap().set(
- common::IdentifiedObject::NAME_KEY,
- primeMeridianName
- ? primeMeridianName
- : primeMeridianOffset == 0.0
- ? (ellps->celestialBody() == Ellipsoid::EARTH
- ? "Greenwich"
- : "Reference meridian")
- : "unnamed"),
- Angle(primeMeridianOffset, angUnit));
- auto datum = GeodeticReferenceFrame::create(
- createPropertyMapName(datumName), ellps,
- util::optional<std::string>(), pm);
- auto geogCRS = GeographicCRS::create(
- createPropertyMapName(geogName), datum,
- latLongOrder ? cs::EllipsoidalCS::createLatitudeLongitude(angUnit)
- : cs::EllipsoidalCS::createLongitudeLatitude(angUnit));
- return PJ_OBJ::create(ctx, geogCRS);
+ auto datum = createGeodeticReferenceFrame(
+ ctx, datum_name, ellps_name, semi_major_metre, inv_flattening,
+ prime_meridian_name, prime_meridian_offset, pm_angular_units,
+ pm_angular_units_conv);
+ auto geogCRS = GeographicCRS::create(createPropertyMapName(crs_name),
+ datum, NN_NO_CHECK(cs));
+ return PJ_OBJ::create(geogCRS);
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
}
@@ -1718,22 +1944,775 @@ PJ_OBJ *proj_obj_create_geographic_crs(
// ---------------------------------------------------------------------------
+/** \brief Create a GeographicCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs_name Name of the GeographicCRS. Or NULL
+ * @param datum Datum. Must not be NULL.
+ * @param ellipsoidal_cs Coordinate system. Must not be NULL.
+ *
+ * @return Object of type GeographicCRS that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_create_geographic_crs_from_datum(PJ_CONTEXT *ctx,
+ const char *crs_name,
+ PJ_OBJ *datum,
+ PJ_OBJ *ellipsoidal_cs) {
+
+ SANITIZE_CTX(ctx);
+ auto l_datum =
+ util::nn_dynamic_pointer_cast<GeodeticReferenceFrame>(datum->obj);
+ if (!l_datum) {
+ proj_log_error(ctx, __FUNCTION__,
+ "datum is not a GeodeticReferenceFrame");
+ return nullptr;
+ }
+ auto cs = util::nn_dynamic_pointer_cast<EllipsoidalCS>(ellipsoidal_cs->obj);
+ if (!cs) {
+ return nullptr;
+ }
+ try {
+ auto geogCRS =
+ GeographicCRS::create(createPropertyMapName(crs_name),
+ NN_NO_CHECK(l_datum), NN_NO_CHECK(cs));
+ return PJ_OBJ::create(geogCRS);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Create a GeodeticCRS of geocentric type.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs_name Name of the GeographicCRS. Or NULL
+ * @param datum_name Name of the GeodeticReferenceFrame. Or NULL
+ * @param ellps_name Name of the Ellipsoid. Or NULL
+ * @param semi_major_metre Ellipsoid semi-major axis, in metres.
+ * @param inv_flattening Ellipsoid inverse flattening. Or 0 for a sphere.
+ * @param prime_meridian_name Name of the PrimeMeridian. Or NULL
+ * @param prime_meridian_offset Offset of the prime meridian, expressed in the
+ * specified angular units.
+ * @param angular_units Name of the angular units. Or NULL for Degree
+ * @param angular_units_conv Conversion factor from the angular unit to radian.
+ * Or
+ * 0 for Degree if angular_units == NULL. Otherwise should be not NULL
+ * @param linear_units Name of the linear units. Or NULL for Metre
+ * @param linear_units_conv Conversion factor from the linear unit to metre. Or
+ * 0 for Metre if linear_units == NULL. Otherwise should be not NULL
+ *
+ * @return Object of type GeodeticCRS that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_create_geocentric_crs(
+ PJ_CONTEXT *ctx, const char *crs_name, const char *datum_name,
+ const char *ellps_name, double semi_major_metre, double inv_flattening,
+ const char *prime_meridian_name, double prime_meridian_offset,
+ const char *angular_units, double angular_units_conv,
+ const char *linear_units, double linear_units_conv) {
+
+ SANITIZE_CTX(ctx);
+ try {
+ const UnitOfMeasure linearUnit(
+ createLinearUnit(linear_units, linear_units_conv));
+ auto datum = createGeodeticReferenceFrame(
+ ctx, datum_name, ellps_name, semi_major_metre, inv_flattening,
+ prime_meridian_name, prime_meridian_offset, angular_units,
+ angular_units_conv);
+
+ auto geodCRS =
+ GeodeticCRS::create(createPropertyMapName(crs_name), datum,
+ cs::CartesianCS::createGeocentric(linearUnit));
+ return PJ_OBJ::create(geodCRS);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Create a GeodeticCRS of geocentric type.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs_name Name of the GeographicCRS. Or NULL
+ * @param datum Datum. Must not be NULL.
+ * @param linear_units Name of the linear units. Or NULL for Metre
+ * @param linear_units_conv Conversion factor from the linear unit to metre. Or
+ * 0 for Metre if linear_units == NULL. Otherwise should be not NULL
+ *
+ * @return Object of type GeodeticCRS that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_create_geocentric_crs_from_datum(PJ_CONTEXT *ctx,
+ const char *crs_name,
+ const PJ_OBJ *datum,
+ const char *linear_units,
+ double linear_units_conv) {
+ SANITIZE_CTX(ctx);
+ try {
+ const UnitOfMeasure linearUnit(
+ createLinearUnit(linear_units, linear_units_conv));
+ auto l_datum =
+ util::nn_dynamic_pointer_cast<GeodeticReferenceFrame>(datum->obj);
+ if (!l_datum) {
+ proj_log_error(ctx, __FUNCTION__,
+ "datum is not a GeodeticReferenceFrame");
+ return nullptr;
+ }
+ auto geodCRS = GeodeticCRS::create(
+ createPropertyMapName(crs_name), NN_NO_CHECK(l_datum),
+ cs::CartesianCS::createGeocentric(linearUnit));
+ return PJ_OBJ::create(geodCRS);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return a copy of the object with its name changed
+ *
+ * Currently, only implemented on CRS objects.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type CRS. Must not be NULL
+ * @param name New name. Must not be NULL
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ PROJ_DLL *proj_obj_alter_name(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ const char *name) {
+ SANITIZE_CTX(ctx);
+ auto crs = dynamic_cast<const CRS *>(obj->obj.get());
+ if (!crs) {
+ return nullptr;
+ }
+ try {
+ return PJ_OBJ::create(crs->alterName(name));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return a copy of the CRS with its geodetic CRS changed
+ *
+ * Currently, when obj is a GeodeticCRS, it returns a clone of new_geod_crs
+ * When obj is a ProjectedCRS, it replaces its base CRS with new_geod_crs.
+ * When obj is a CompoundCRS, it replaces the GeodeticCRS part of the horizontal
+ * CRS with new_geod_crs.
+ * In other cases, it returns a clone of obj.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type CRS. Must not be NULL
+ * @param new_geod_crs Object of type GeodeticCRS. Must not be NULL
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_crs_alter_geodetic_crs(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ const PJ_OBJ *new_geod_crs) {
+ SANITIZE_CTX(ctx);
+ auto l_new_geod_crs =
+ util::nn_dynamic_pointer_cast<GeodeticCRS>(new_geod_crs->obj);
+ if (!l_new_geod_crs) {
+ proj_log_error(ctx, __FUNCTION__, "new_geod_crs is not a GeodeticCRS");
+ return nullptr;
+ }
+
+ auto crs = dynamic_cast<const CRS *>(obj->obj.get());
+ if (!crs) {
+ proj_log_error(ctx, __FUNCTION__, "obj is not a CRS");
+ return nullptr;
+ }
+
+ try {
+ return PJ_OBJ::create(
+ crs->alterGeodeticCRS(NN_NO_CHECK(l_new_geod_crs)));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return a copy of the CRS with its angular units changed
+ *
+ * The CRS must be or contain a GeographicCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type CRS. Must not be NULL
+ * @param angular_units Name of the angular units. Or NULL for Degree
+ * @param angular_units_conv Conversion factor from the angular unit to radian.
+ * Or
+ * 0 for Degree if angular_units == NULL. Otherwise should be not NULL
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_crs_alter_cs_angular_unit(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ const char *angular_units,
+ double angular_units_conv) {
+
+ SANITIZE_CTX(ctx);
+ auto geodCRS = proj_obj_crs_get_geodetic_crs(ctx, obj);
+ if (!geodCRS) {
+ return nullptr;
+ }
+ auto geogCRS = dynamic_cast<const GeographicCRS *>(geodCRS->obj.get());
+ if (!geogCRS) {
+ proj_obj_unref(geodCRS);
+ return nullptr;
+ }
+
+ PJ_OBJ *geogCRSAltered = nullptr;
+ try {
+ const UnitOfMeasure angUnit(
+ createAngularUnit(angular_units, angular_units_conv));
+ geogCRSAltered = PJ_OBJ::create(GeographicCRS::create(
+ createPropertyMapName(proj_obj_get_name(geodCRS)), geogCRS->datum(),
+ geogCRS->datumEnsemble(),
+ geogCRS->coordinateSystem()->alterAngularUnit(angUnit)));
+ proj_obj_unref(geodCRS);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ proj_obj_unref(geodCRS);
+ return nullptr;
+ }
+
+ auto ret = proj_obj_crs_alter_geodetic_crs(ctx, obj, geogCRSAltered);
+ proj_obj_unref(geogCRSAltered);
+ return ret;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return a copy of the CRS with the linear units of its coordinate
+ * system changed
+ *
+ * The CRS must be or contain a ProjectedCRS, VerticalCRS or a GeocentricCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type CRS. Must not be NULL
+ * @param linear_units Name of the linear units. Or NULL for Metre
+ * @param linear_units_conv Conversion factor from the linear unit to metre. Or
+ * 0 for Metre if linear_units == NULL. Otherwise should be not NULL
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_crs_alter_cs_linear_unit(PJ_CONTEXT *ctx, const PJ_OBJ *obj,
+ const char *linear_units,
+ double linear_units_conv) {
+ SANITIZE_CTX(ctx);
+ auto crs = dynamic_cast<const CRS *>(obj->obj.get());
+ if (!crs) {
+ return nullptr;
+ }
+
+ try {
+ const UnitOfMeasure linearUnit(
+ createLinearUnit(linear_units, linear_units_conv));
+ return PJ_OBJ::create(crs->alterCSLinearUnit(linearUnit));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return a copy of the CRS with the lineaer units of the parameters
+ * of its conversion modified.
+ *
+ * The CRS must be or contain a ProjectedCRS, VerticalCRS or a GeocentricCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param obj Object of type ProjectedCRS. Must not be NULL
+ * @param linear_units Name of the linear units. Or NULL for Metre
+ * @param linear_units_conv Conversion factor from the linear unit to metre. Or
+ * 0 for Metre if linear_units == NULL. Otherwise should be not NULL
+ * @param convert_to_new_unit TRUE if exisiting values should be converted from
+ * their current unit to the new unit. If FALSE, their value will be left
+ * unchanged and the unit overriden (so the resulting CRS will not be
+ * equivalent to the original one for reprojection purposes).
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ *proj_obj_crs_alter_parameters_linear_unit(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj,
+ const char *linear_units,
+ double linear_units_conv,
+ int convert_to_new_unit) {
+ SANITIZE_CTX(ctx);
+ auto crs = dynamic_cast<const ProjectedCRS *>(obj->obj.get());
+ if (!crs) {
+ return nullptr;
+ }
+
+ try {
+ const UnitOfMeasure linearUnit(
+ createLinearUnit(linear_units, linear_units_conv));
+ return PJ_OBJ::create(crs->alterParametersLinearUnit(
+ linearUnit, convert_to_new_unit == TRUE));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a EngineeringCRS with just a name
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs_name CRS name. Or NULL.
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+PJ_OBJ PROJ_DLL *proj_obj_create_engineering_crs(PJ_CONTEXT *ctx,
+ const char *crs_name) {
+ SANITIZE_CTX(ctx);
+ try {
+ return PJ_OBJ::create(EngineeringCRS::create(
+ createPropertyMapName(crs_name),
+ EngineeringDatum::create(PropertyMap()),
+ CartesianCS::createEastingNorthing(UnitOfMeasure::METRE)));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a Conversion
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param name Conversion name. Or NULL.
+ * @param auth_name Conversion authority name. Or NULL.
+ * @param code Conversion code. Or NULL.
+ * @param method_name Method name. Or NULL.
+ * @param method_auth_name Method authority name. Or NULL.
+ * @param method_code Method code. Or NULL.
+ * @param param_count Number of parameters (size of params argument)
+ * @param params Parameter descriptions (array of size param_count)
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+
+PJ_OBJ *proj_obj_create_conversion(PJ_CONTEXT *ctx, const char *name,
+ const char *auth_name, const char *code,
+ const char *method_name,
+ const char *method_auth_name,
+ const char *method_code, int param_count,
+ const PJ_PARAM_DESCRIPTION *params) {
+ SANITIZE_CTX(ctx);
+ try {
+ PropertyMap propConv;
+ propConv.set(common::IdentifiedObject::NAME_KEY,
+ name ? name : "unnamed");
+ if (auth_name && code) {
+ propConv.set(metadata::Identifier::CODESPACE_KEY, auth_name)
+ .set(metadata::Identifier::CODE_KEY, code);
+ }
+ PropertyMap propMethod;
+ propMethod.set(common::IdentifiedObject::NAME_KEY,
+ method_name ? method_name : "unnamed");
+ if (method_auth_name && method_code) {
+ propMethod
+ .set(metadata::Identifier::CODESPACE_KEY, method_auth_name)
+ .set(metadata::Identifier::CODE_KEY, method_code);
+ }
+ std::vector<OperationParameterNNPtr> parameters;
+ std::vector<ParameterValueNNPtr> values;
+ for (int i = 0; i < param_count; i++) {
+ PropertyMap propParam;
+ propParam.set(common::IdentifiedObject::NAME_KEY,
+ params[i].name ? params[i].name : "unnamed");
+ if (params[i].auth_name && params[i].code) {
+ propParam
+ .set(metadata::Identifier::CODESPACE_KEY,
+ params[i].auth_name)
+ .set(metadata::Identifier::CODE_KEY, params[i].code);
+ }
+ parameters.emplace_back(OperationParameter::create(propParam));
+ auto unit_type = UnitOfMeasure::Type::UNKNOWN;
+ switch (params[i].unit_type) {
+ case PJ_UT_ANGULAR:
+ unit_type = UnitOfMeasure::Type::ANGULAR;
+ break;
+ case PJ_UT_LINEAR:
+ unit_type = UnitOfMeasure::Type::LINEAR;
+ break;
+ case PJ_UT_SCALE:
+ unit_type = UnitOfMeasure::Type::SCALE;
+ break;
+ case PJ_UT_TIME:
+ unit_type = UnitOfMeasure::Type::TIME;
+ break;
+ case PJ_UT_PARAMETRIC:
+ unit_type = UnitOfMeasure::Type::PARAMETRIC;
+ break;
+ }
+
+ Measure measure(
+ params[i].value,
+ params[i].unit_type == PJ_UT_ANGULAR
+ ? createAngularUnit(params[i].unit_name,
+ params[i].unit_conv_factor)
+ : params[i].unit_type == PJ_UT_LINEAR
+ ? createLinearUnit(params[i].unit_name,
+ params[i].unit_conv_factor)
+ : UnitOfMeasure(
+ params[i].unit_name ? params[i].unit_name
+ : "unnamed",
+ params[i].unit_conv_factor, unit_type));
+ values.emplace_back(ParameterValue::create(measure));
+ }
+ return PJ_OBJ::create(
+ Conversion::create(propConv, propMethod, parameters, values));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
-static PJ_OBJ *proj_obj_create_projected_crs(PJ_OBJ *geodetic_crs,
- const char *crs_name,
- const ConversionNNPtr &conv,
- const UnitOfMeasure &linearUnit) {
- assert(geodetic_crs);
- auto geogCRS =
+static CoordinateSystemAxisNNPtr createAxis(const PJ_AXIS_DESCRIPTION &axis) {
+ const auto dir =
+ axis.direction ? AxisDirection::valueOf(axis.direction) : nullptr;
+ if (dir == nullptr)
+ throw Exception("invalid value for axis direction");
+ auto unit_type = UnitOfMeasure::Type::UNKNOWN;
+ switch (axis.unit_type) {
+ case PJ_UT_ANGULAR:
+ unit_type = UnitOfMeasure::Type::ANGULAR;
+ break;
+ case PJ_UT_LINEAR:
+ unit_type = UnitOfMeasure::Type::LINEAR;
+ break;
+ case PJ_UT_SCALE:
+ unit_type = UnitOfMeasure::Type::SCALE;
+ break;
+ case PJ_UT_TIME:
+ unit_type = UnitOfMeasure::Type::TIME;
+ break;
+ case PJ_UT_PARAMETRIC:
+ unit_type = UnitOfMeasure::Type::PARAMETRIC;
+ break;
+ }
+ auto unit =
+ axis.unit_type == PJ_UT_ANGULAR
+ ? createAngularUnit(axis.unit_name, axis.unit_conv_factor)
+ : axis.unit_type == PJ_UT_LINEAR
+ ? createLinearUnit(axis.unit_name, axis.unit_conv_factor)
+ : UnitOfMeasure(axis.unit_name ? axis.unit_name : "unnamed",
+ axis.unit_conv_factor, unit_type);
+
+ return CoordinateSystemAxis::create(
+ createPropertyMapName(axis.name),
+ axis.abbreviation ? axis.abbreviation : std::string(), *dir, unit);
+}
+
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a CoordinateSystem.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param type Coordinate system type.
+ * @param axis_count Number of axis
+ * @param axis Axis description (array of size axis_count)
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+
+PJ_OBJ *proj_obj_create_cs(PJ_CONTEXT *ctx, PJ_COORDINATE_SYSTEM_TYPE type,
+ int axis_count, const PJ_AXIS_DESCRIPTION *axis) {
+ try {
+ switch (type) {
+ case PJ_CS_TYPE_UNKNOWN:
+ return nullptr;
+
+ case PJ_CS_TYPE_CARTESIAN: {
+ if (axis_count == 2) {
+ return PJ_OBJ::create(CartesianCS::create(
+ PropertyMap(), createAxis(axis[0]), createAxis(axis[1])));
+ } else if (axis_count == 3) {
+ return PJ_OBJ::create(CartesianCS::create(
+ PropertyMap(), createAxis(axis[0]), createAxis(axis[1]),
+ createAxis(axis[2])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_ELLIPSOIDAL: {
+ if (axis_count == 2) {
+ return PJ_OBJ::create(EllipsoidalCS::create(
+ PropertyMap(), createAxis(axis[0]), createAxis(axis[1])));
+ } else if (axis_count == 3) {
+ return PJ_OBJ::create(EllipsoidalCS::create(
+ PropertyMap(), createAxis(axis[0]), createAxis(axis[1]),
+ createAxis(axis[2])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_VERTICAL: {
+ if (axis_count == 1) {
+ return PJ_OBJ::create(
+ VerticalCS::create(PropertyMap(), createAxis(axis[0])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_SPHERICAL: {
+ if (axis_count == 3) {
+ return PJ_OBJ::create(EllipsoidalCS::create(
+ PropertyMap(), createAxis(axis[0]), createAxis(axis[1]),
+ createAxis(axis[2])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_PARAMETRIC: {
+ if (axis_count == 1) {
+ return PJ_OBJ::create(
+ ParametricCS::create(PropertyMap(), createAxis(axis[0])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_ORDINAL: {
+ std::vector<CoordinateSystemAxisNNPtr> axisVector;
+ for (int i = 0; i < axis_count; i++) {
+ axisVector.emplace_back(createAxis(axis[i]));
+ }
+
+ return PJ_OBJ::create(OrdinalCS::create(PropertyMap(), axisVector));
+ }
+
+ case PJ_CS_TYPE_DATETIMETEMPORAL: {
+ if (axis_count == 1) {
+ return PJ_OBJ::create(DateTimeTemporalCS::create(
+ PropertyMap(), createAxis(axis[0])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_TEMPORALCOUNT: {
+ if (axis_count == 1) {
+ return PJ_OBJ::create(TemporalCountCS::create(
+ PropertyMap(), createAxis(axis[0])));
+ }
+ break;
+ }
+
+ case PJ_CS_TYPE_TEMPORALMEASURE: {
+ if (axis_count == 1) {
+ return PJ_OBJ::create(TemporalMeasureCS::create(
+ PropertyMap(), createAxis(axis[0])));
+ }
+ break;
+ }
+ }
+
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+ proj_log_error(ctx, __FUNCTION__, "Wrong value for axis_count");
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a CartesiansCS 2D
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param type Coordinate system type.
+ * @param unit_name Unit name.
+ * @param unit_conv_factor Unit conversion factor to SI.
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+
+PJ_OBJ *proj_obj_create_cartesian_2D_cs(PJ_CONTEXT *ctx,
+ PJ_CARTESIAN_CS_2D_TYPE type,
+ const char *unit_name,
+ double unit_conv_factor) {
+ try {
+ switch (type) {
+ case PJ_CART2D_EASTING_NORTHING:
+ return PJ_OBJ::create(CartesianCS::createEastingNorthing(
+ createLinearUnit(unit_name, unit_conv_factor)));
+
+ case PJ_CART2D_NORTHING_EASTING:
+ return PJ_OBJ::create(CartesianCS::createNorthingEasting(
+ createLinearUnit(unit_name, unit_conv_factor)));
+ }
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a Ellipsoidal 2D
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param type Coordinate system type.
+ * @param unit_name Unit name.
+ * @param unit_conv_factor Unit conversion factor to SI.
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+
+PJ_OBJ *proj_obj_create_ellipsoidal_2D_cs(PJ_CONTEXT *ctx,
+ PJ_ELLIPSOIDAL_CS_2D_TYPE type,
+ const char *unit_name,
+ double unit_conv_factor) {
+ try {
+ switch (type) {
+ case PJ_ELLPS2D_LONGITUDE_LATITUDE:
+ return PJ_OBJ::create(EllipsoidalCS::createLongitudeLatitude(
+ createAngularUnit(unit_name, unit_conv_factor)));
+
+ case PJ_ELLPS2D_LATITUDE_LONGITUDE:
+ return PJ_OBJ::create(EllipsoidalCS::createLatitudeLongitude(
+ createAngularUnit(unit_name, unit_conv_factor)));
+ }
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Instanciate a ProjectedCRS
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs_name CRS name. Or NULL
+ * @param geodetic_crs Base GeodeticCRS. Must not be NULL.
+ * @param conversion Conversion. Must not be NULL.
+ * @param coordinate_system Cartesian coordinate system. Must not be NULL.
+ *
+ * @return Object that must be unreferenced with
+ * proj_obj_unref(), or NULL in case of error.
+ */
+
+PJ_OBJ *proj_obj_create_projected_crs(PJ_CONTEXT *ctx, const char *crs_name,
+ const PJ_OBJ *geodetic_crs,
+ const PJ_OBJ *conversion,
+ const PJ_OBJ *coordinate_system) {
+ SANITIZE_CTX(ctx);
+ auto geodCRS =
util::nn_dynamic_pointer_cast<GeodeticCRS>(geodetic_crs->obj);
- if (!geogCRS) {
+ if (!geodCRS) {
+ return nullptr;
+ }
+ auto conv = util::nn_dynamic_pointer_cast<Conversion>(conversion->obj);
+ if (!conv) {
return nullptr;
}
- auto crs = ProjectedCRS::create(
- createPropertyMapName(crs_name), NN_NO_CHECK(geogCRS), conv,
- cs::CartesianCS::createEastingNorthing(linearUnit));
- return PJ_OBJ::create(geodetic_crs->ctx, crs);
+ auto cs =
+ util::nn_dynamic_pointer_cast<CartesianCS>(coordinate_system->obj);
+ if (!cs) {
+ return nullptr;
+ }
+ try {
+ return PJ_OBJ::create(ProjectedCRS::create(
+ createPropertyMapName(crs_name), NN_NO_CHECK(geodCRS),
+ NN_NO_CHECK(conv), NN_NO_CHECK(cs)));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+
+static PJ_OBJ *proj_obj_create_conversion(const ConversionNNPtr &conv) {
+ return PJ_OBJ::create(conv);
}
//! @endcond
@@ -1747,15 +2726,18 @@ static PJ_OBJ *proj_obj_create_projected_crs(PJ_OBJ *geodetic_crs,
*
* See osgeo::proj::operation::Conversion::createUTM().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_UTM(PJ_OBJ *geodetic_crs,
- const char *crs_name, int zone,
- int north) {
- const auto &linearUnit = UnitOfMeasure::METRE;
- auto conv = Conversion::createUTM(PropertyMap(), zone, north != 0);
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_utm(PJ_CONTEXT *ctx, int zone, int north) {
+ SANITIZE_CTX(ctx);
+ try {
+ auto conv = Conversion::createUTM(PropertyMap(), zone, north != 0);
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1764,23 +2746,31 @@ PJ_OBJ *proj_obj_create_projected_crs_UTM(PJ_OBJ *geodetic_crs,
*
* See osgeo::proj::operation::Conversion::createTransverseMercator().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_TransverseMercator(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createTransverseMercator(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_transverse_mercator(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createTransverseMercator(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1790,23 +2780,31 @@ PJ_OBJ *proj_obj_create_projected_crs_TransverseMercator(
* See
* osgeo::proj::operation::Conversion::createGaussSchreiberTransverseMercator().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_GaussSchreiberTransverseMercator(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGaussSchreiberTransverseMercator(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_gauss_schreiber_transverse_mercator(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGaussSchreiberTransverseMercator(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1816,23 +2814,31 @@ PJ_OBJ *proj_obj_create_projected_crs_GaussSchreiberTransverseMercator(
* See
* osgeo::proj::operation::Conversion::createTransverseMercatorSouthOriented().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_TransverseMercatorSouthOriented(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createTransverseMercatorSouthOriented(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_transverse_mercator_south_oriented(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createTransverseMercatorSouthOriented(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1841,26 +2847,34 @@ PJ_OBJ *proj_obj_create_projected_crs_TransverseMercatorSouthOriented(
*
* See osgeo::proj::operation::Conversion::createTwoPointEquidistant().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_TwoPointEquidistant(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstPoint,
- double longitudeFirstPoint, double latitudeSecondPoint,
- double longitudeSeconPoint, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createTwoPointEquidistant(
- PropertyMap(), Angle(latitudeFirstPoint, angUnit),
- Angle(longitudeFirstPoint, angUnit),
- Angle(latitudeSecondPoint, angUnit),
- Angle(longitudeSeconPoint, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_two_point_equidistant(
+ PJ_CONTEXT *ctx, double latitude_first_point, double longitude_first_point,
+ double latitude_second_point, double longitude_secon_point,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createTwoPointEquidistant(
+ PropertyMap(), Angle(latitude_first_point, angUnit),
+ Angle(longitude_first_point, angUnit),
+ Angle(latitude_second_point, angUnit),
+ Angle(longitude_secon_point, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1869,22 +2883,30 @@ PJ_OBJ *proj_obj_create_projected_crs_TwoPointEquidistant(
*
* See osgeo::proj::operation::Conversion::createTunisiaMappingGrid().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_TunisiaMappingGrid(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createTunisiaMappingGrid(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_tunisia_mapping_grid(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createTunisiaMappingGrid(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1893,28 +2915,35 @@ PJ_OBJ *proj_obj_create_projected_crs_TunisiaMappingGrid(
*
* See osgeo::proj::operation::Conversion::createAlbersEqualArea().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_AlbersEqualArea(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFalseOrigin,
- double longitudeFalseOrigin, double latitudeFirstParallel,
- double latitudeSecondParallel, double eastingFalseOrigin,
- double northingFalseOrigin, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createAlbersEqualArea(
- PropertyMap(), Angle(latitudeFalseOrigin, angUnit),
- Angle(longitudeFalseOrigin, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(eastingFalseOrigin, linearUnit),
- Length(northingFalseOrigin, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_albers_equal_area(
+ PJ_CONTEXT *ctx, double latitude_false_origin,
+ double longitude_false_origin, double latitude_first_parallel,
+ double latitude_second_parallel, double easting_false_origin,
+ double northing_false_origin, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createAlbersEqualArea(
+ PropertyMap(), Angle(latitude_false_origin, angUnit),
+ Angle(longitude_false_origin, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(easting_false_origin, linearUnit),
+ Length(northing_false_origin, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1923,23 +2952,31 @@ PJ_OBJ *proj_obj_create_projected_crs_AlbersEqualArea(
*
* See osgeo::proj::operation::Conversion::createLambertConicConformal_1SP().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_1SP(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertConicConformal_1SP(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_lambert_conic_conformal_1sp(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertConicConformal_1SP(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1948,28 +2985,35 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_1SP(
*
* See osgeo::proj::operation::Conversion::createLambertConicConformal_2SP().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFalseOrigin,
- double longitudeFalseOrigin, double latitudeFirstParallel,
- double latitudeSecondParallel, double eastingFalseOrigin,
- double northingFalseOrigin, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertConicConformal_2SP(
- PropertyMap(), Angle(latitudeFalseOrigin, angUnit),
- Angle(longitudeFalseOrigin, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(eastingFalseOrigin, linearUnit),
- Length(northingFalseOrigin, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_lambert_conic_conformal_2sp(
+ PJ_CONTEXT *ctx, double latitude_false_origin,
+ double longitude_false_origin, double latitude_first_parallel,
+ double latitude_second_parallel, double easting_false_origin,
+ double northing_false_origin, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertConicConformal_2SP(
+ PropertyMap(), Angle(latitude_false_origin, angUnit),
+ Angle(longitude_false_origin, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(easting_false_origin, linearUnit),
+ Length(northing_false_origin, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -1979,28 +3023,36 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP(
* See
* osgeo::proj::operation::Conversion::createLambertConicConformal_2SP_Michigan().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP_Michigan(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFalseOrigin,
- double longitudeFalseOrigin, double latitudeFirstParallel,
- double latitudeSecondParallel, double eastingFalseOrigin,
- double northingFalseOrigin, double ellipsoidScalingFactor,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertConicConformal_2SP_Michigan(
- PropertyMap(), Angle(latitudeFalseOrigin, angUnit),
- Angle(longitudeFalseOrigin, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(eastingFalseOrigin, linearUnit),
- Length(northingFalseOrigin, linearUnit), Scale(ellipsoidScalingFactor));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_lambert_conic_conformal_2sp_michigan(
+ PJ_CONTEXT *ctx, double latitude_false_origin,
+ double longitude_false_origin, double latitude_first_parallel,
+ double latitude_second_parallel, double easting_false_origin,
+ double northing_false_origin, double ellipsoid_scaling_factor,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertConicConformal_2SP_Michigan(
+ PropertyMap(), Angle(latitude_false_origin, angUnit),
+ Angle(longitude_false_origin, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(easting_false_origin, linearUnit),
+ Length(northing_false_origin, linearUnit),
+ Scale(ellipsoid_scaling_factor));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2010,28 +3062,35 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP_Michigan(
* See
* osgeo::proj::operation::Conversion::createLambertConicConformal_2SP_Belgium().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP_Belgium(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFalseOrigin,
- double longitudeFalseOrigin, double latitudeFirstParallel,
- double latitudeSecondParallel, double eastingFalseOrigin,
- double northingFalseOrigin, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertConicConformal_2SP_Belgium(
- PropertyMap(), Angle(latitudeFalseOrigin, angUnit),
- Angle(longitudeFalseOrigin, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(eastingFalseOrigin, linearUnit),
- Length(northingFalseOrigin, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_lambert_conic_conformal_2sp_belgium(
+ PJ_CONTEXT *ctx, double latitude_false_origin,
+ double longitude_false_origin, double latitude_first_parallel,
+ double latitude_second_parallel, double easting_false_origin,
+ double northing_false_origin, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertConicConformal_2SP_Belgium(
+ PropertyMap(), Angle(latitude_false_origin, angUnit),
+ Angle(longitude_false_origin, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(easting_false_origin, linearUnit),
+ Length(northing_false_origin, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2040,23 +3099,31 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertConicConformal_2SP_Belgium(
*
* See osgeo::proj::operation::Conversion::createAzimuthalEquidistant().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_AzimuthalEquidistant(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeNatOrigin,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createAzimuthalEquidistant(
- PropertyMap(), Angle(latitudeNatOrigin, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_azimuthal_equidistant(
+ PJ_CONTEXT *ctx, double latitude_nat_origin, double longitude_nat_origin,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createAzimuthalEquidistant(
+ PropertyMap(), Angle(latitude_nat_origin, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2065,23 +3132,31 @@ PJ_OBJ *proj_obj_create_projected_crs_AzimuthalEquidistant(
*
* See osgeo::proj::operation::Conversion::createGuamProjection().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_GuamProjection(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeNatOrigin,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGuamProjection(
- PropertyMap(), Angle(latitudeNatOrigin, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_guam_projection(
+ PJ_CONTEXT *ctx, double latitude_nat_origin, double longitude_nat_origin,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGuamProjection(
+ PropertyMap(), Angle(latitude_nat_origin, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2090,23 +3165,31 @@ PJ_OBJ *proj_obj_create_projected_crs_GuamProjection(
*
* See osgeo::proj::operation::Conversion::createBonne().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Bonne(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeNatOrigin,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createBonne(
- PropertyMap(), Angle(latitudeNatOrigin, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_bonne(
+ PJ_CONTEXT *ctx, double latitude_nat_origin, double longitude_nat_origin,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createBonne(
+ PropertyMap(), Angle(latitude_nat_origin, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2116,23 +3199,31 @@ PJ_OBJ *proj_obj_create_projected_crs_Bonne(
* See
* osgeo::proj::operation::Conversion::createLambertCylindricalEqualAreaSpherical().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_LambertCylindricalEqualAreaSpherical(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstParallel,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertCylindricalEqualAreaSpherical(
- PropertyMap(), Angle(latitudeFirstParallel, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_lambert_cylindrical_equal_area_spherical(
+ PJ_CONTEXT *ctx, double latitude_first_parallel,
+ double longitude_nat_origin, double false_easting, double false_northing,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertCylindricalEqualAreaSpherical(
+ PropertyMap(), Angle(latitude_first_parallel, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2141,23 +3232,31 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertCylindricalEqualAreaSpherical(
*
* See osgeo::proj::operation::Conversion::createLambertCylindricalEqualArea().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_LambertCylindricalEqualArea(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstParallel,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertCylindricalEqualArea(
- PropertyMap(), Angle(latitudeFirstParallel, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_lambert_cylindrical_equal_area(
+ PJ_CONTEXT *ctx, double latitude_first_parallel,
+ double longitude_nat_origin, double false_easting, double false_northing,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertCylindricalEqualArea(
+ PropertyMap(), Angle(latitude_first_parallel, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2166,22 +3265,30 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertCylindricalEqualArea(
*
* See osgeo::proj::operation::Conversion::createCassiniSoldner().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_CassiniSoldner(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createCassiniSoldner(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_cassini_soldner(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createCassiniSoldner(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2190,25 +3297,34 @@ PJ_OBJ *proj_obj_create_projected_crs_CassiniSoldner(
*
* See osgeo::proj::operation::Conversion::createEquidistantConic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EquidistantConic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double latitudeFirstParallel,
- double latitudeSecondParallel, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEquidistantConic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_equidistant_conic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double latitude_first_parallel, double latitude_second_parallel,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEquidistantConic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2217,22 +3333,32 @@ PJ_OBJ *proj_obj_create_projected_crs_EquidistantConic(
*
* See osgeo::proj::operation::Conversion::createEckertI().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertI(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertI(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_i(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertI(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2241,22 +3367,30 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertI(
*
* See osgeo::proj::operation::Conversion::createEckertII().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertII(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertII(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_ii(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertII(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2265,22 +3399,30 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertII(
*
* See osgeo::proj::operation::Conversion::createEckertIII().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertIII(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertIII(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_iii(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertIII(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2289,22 +3431,30 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertIII(
*
* See osgeo::proj::operation::Conversion::createEckertIV().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertIV(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertIV(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_iv(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertIV(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2313,22 +3463,32 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertIV(
*
* See osgeo::proj::operation::Conversion::createEckertV().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertV(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertV(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_v(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertV(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2337,22 +3497,30 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertV(
*
* See osgeo::proj::operation::Conversion::createEckertVI().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EckertVI(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEckertVI(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_eckert_vi(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEckertVI(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2361,23 +3529,31 @@ PJ_OBJ *proj_obj_create_projected_crs_EckertVI(
*
* See osgeo::proj::operation::Conversion::createEquidistantCylindrical().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EquidistantCylindrical(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstParallel,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEquidistantCylindrical(
- PropertyMap(), Angle(latitudeFirstParallel, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_equidistant_cylindrical(
+ PJ_CONTEXT *ctx, double latitude_first_parallel,
+ double longitude_nat_origin, double false_easting, double false_northing,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEquidistantCylindrical(
+ PropertyMap(), Angle(latitude_first_parallel, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2387,23 +3563,31 @@ PJ_OBJ *proj_obj_create_projected_crs_EquidistantCylindrical(
* See
* osgeo::proj::operation::Conversion::createEquidistantCylindricalSpherical().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_EquidistantCylindricalSpherical(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstParallel,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEquidistantCylindricalSpherical(
- PropertyMap(), Angle(latitudeFirstParallel, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_equidistant_cylindrical_spherical(
+ PJ_CONTEXT *ctx, double latitude_first_parallel,
+ double longitude_nat_origin, double false_easting, double false_northing,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEquidistantCylindricalSpherical(
+ PropertyMap(), Angle(latitude_first_parallel, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2412,22 +3596,32 @@ PJ_OBJ *proj_obj_create_projected_crs_EquidistantCylindricalSpherical(
*
* See osgeo::proj::operation::Conversion::createGall().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Gall(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGall(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_gall(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv =
+ Conversion::createGall(PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2436,22 +3630,30 @@ PJ_OBJ *proj_obj_create_projected_crs_Gall(
*
* See osgeo::proj::operation::Conversion::createGoodeHomolosine().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_GoodeHomolosine(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGoodeHomolosine(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_goode_homolosine(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGoodeHomolosine(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2460,22 +3662,30 @@ PJ_OBJ *proj_obj_create_projected_crs_GoodeHomolosine(
*
* See osgeo::proj::operation::Conversion::createInterruptedGoodeHomolosine().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_InterruptedGoodeHomolosine(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createInterruptedGoodeHomolosine(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_interrupted_goode_homolosine(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createInterruptedGoodeHomolosine(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2485,22 +3695,30 @@ PJ_OBJ *proj_obj_create_projected_crs_InterruptedGoodeHomolosine(
*
* See osgeo::proj::operation::Conversion::createGeostationarySatelliteSweepX().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_GeostationarySatelliteSweepX(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double height, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGeostationarySatelliteSweepX(
- PropertyMap(), Angle(centerLong, angUnit), Length(height, linearUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_geostationary_satellite_sweep_x(
+ PJ_CONTEXT *ctx, double center_long, double height, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGeostationarySatelliteSweepX(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(height, linearUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2510,22 +3728,30 @@ PJ_OBJ *proj_obj_create_projected_crs_GeostationarySatelliteSweepX(
*
* See osgeo::proj::operation::Conversion::createGeostationarySatelliteSweepY().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_GeostationarySatelliteSweepY(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double height, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGeostationarySatelliteSweepY(
- PropertyMap(), Angle(centerLong, angUnit), Length(height, linearUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_geostationary_satellite_sweep_y(
+ PJ_CONTEXT *ctx, double center_long, double height, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGeostationarySatelliteSweepY(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(height, linearUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2534,22 +3760,30 @@ PJ_OBJ *proj_obj_create_projected_crs_GeostationarySatelliteSweepY(
*
* See osgeo::proj::operation::Conversion::createGnomonic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Gnomonic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createGnomonic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_gnomonic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createGnomonic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2559,26 +3793,35 @@ PJ_OBJ *proj_obj_create_projected_crs_Gnomonic(
* See
* osgeo::proj::operation::Conversion::createHotineObliqueMercatorVariantA().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_HotineObliqueMercatorVariantA(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeProjectionCentre,
- double longitudeProjectionCentre, double azimuthInitialLine,
- double angleFromRectifiedToSkrewGrid, double scale, double falseEasting,
- double falseNorthing, const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createHotineObliqueMercatorVariantA(
- PropertyMap(), Angle(latitudeProjectionCentre, angUnit),
- Angle(longitudeProjectionCentre, angUnit),
- Angle(azimuthInitialLine, angUnit),
- Angle(angleFromRectifiedToSkrewGrid, angUnit), Scale(scale),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_hotine_oblique_mercator_variant_a(
+ PJ_CONTEXT *ctx, double latitude_projection_centre,
+ double longitude_projection_centre, double azimuth_initial_line,
+ double angle_from_rectified_to_skrew_grid, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createHotineObliqueMercatorVariantA(
+ PropertyMap(), Angle(latitude_projection_centre, angUnit),
+ Angle(longitude_projection_centre, angUnit),
+ Angle(azimuth_initial_line, angUnit),
+ Angle(angle_from_rectified_to_skrew_grid, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2588,28 +3831,35 @@ PJ_OBJ *proj_obj_create_projected_crs_HotineObliqueMercatorVariantA(
* See
* osgeo::proj::operation::Conversion::createHotineObliqueMercatorVariantB().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_HotineObliqueMercatorVariantB(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeProjectionCentre,
- double longitudeProjectionCentre, double azimuthInitialLine,
- double angleFromRectifiedToSkrewGrid, double scale,
- double eastingProjectionCentre, double northingProjectionCentre,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createHotineObliqueMercatorVariantB(
- PropertyMap(), Angle(latitudeProjectionCentre, angUnit),
- Angle(longitudeProjectionCentre, angUnit),
- Angle(azimuthInitialLine, angUnit),
- Angle(angleFromRectifiedToSkrewGrid, angUnit), Scale(scale),
- Length(eastingProjectionCentre, linearUnit),
- Length(northingProjectionCentre, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_hotine_oblique_mercator_variant_b(
+ PJ_CONTEXT *ctx, double latitude_projection_centre,
+ double longitude_projection_centre, double azimuth_initial_line,
+ double angle_from_rectified_to_skrew_grid, double scale,
+ double easting_projection_centre, double northing_projection_centre,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createHotineObliqueMercatorVariantB(
+ PropertyMap(), Angle(latitude_projection_centre, angUnit),
+ Angle(longitude_projection_centre, angUnit),
+ Angle(azimuth_initial_line, angUnit),
+ Angle(angle_from_rectified_to_skrew_grid, angUnit), Scale(scale),
+ Length(easting_projection_centre, linearUnit),
+ Length(northing_projection_centre, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2619,28 +3869,38 @@ PJ_OBJ *proj_obj_create_projected_crs_HotineObliqueMercatorVariantB(
* See
* osgeo::proj::operation::Conversion::createHotineObliqueMercatorTwoPointNaturalOrigin().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
PJ_OBJ *
-proj_obj_create_projected_crs_HotineObliqueMercatorTwoPointNaturalOrigin(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeProjectionCentre,
- double latitudePoint1, double longitudePoint1, double latitudePoint2,
- double longitudePoint2, double scale, double eastingProjectionCentre,
- double northingProjectionCentre, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createHotineObliqueMercatorTwoPointNaturalOrigin(
- PropertyMap(), Angle(latitudeProjectionCentre, angUnit),
- Angle(latitudePoint1, angUnit), Angle(longitudePoint1, angUnit),
- Angle(latitudePoint2, angUnit), Angle(longitudePoint2, angUnit),
- Scale(scale), Length(eastingProjectionCentre, linearUnit),
- Length(northingProjectionCentre, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+proj_obj_create_conversion_hotine_oblique_mercator_two_point_natural_origin(
+ PJ_CONTEXT *ctx, double latitude_projection_centre, double latitude_point1,
+ double longitude_point1, double latitude_point2, double longitude_point2,
+ double scale, double easting_projection_centre,
+ double northing_projection_centre, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv =
+ Conversion::createHotineObliqueMercatorTwoPointNaturalOrigin(
+ PropertyMap(), Angle(latitude_projection_centre, angUnit),
+ Angle(latitude_point1, angUnit),
+ Angle(longitude_point1, angUnit),
+ Angle(latitude_point2, angUnit),
+ Angle(longitude_point2, angUnit), Scale(scale),
+ Length(easting_projection_centre, linearUnit),
+ Length(northing_projection_centre, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2650,25 +3910,33 @@ proj_obj_create_projected_crs_HotineObliqueMercatorTwoPointNaturalOrigin(
* See
* osgeo::proj::operation::Conversion::createInternationalMapWorldPolyconic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_InternationalMapWorldPolyconic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double latitudeFirstParallel, double latitudeSecondParallel,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createInternationalMapWorldPolyconic(
- PropertyMap(), Angle(centerLong, angUnit),
- Angle(latitudeFirstParallel, angUnit),
- Angle(latitudeSecondParallel, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_international_map_world_polyconic(
+ PJ_CONTEXT *ctx, double center_long, double latitude_first_parallel,
+ double latitude_second_parallel, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createInternationalMapWorldPolyconic(
+ PropertyMap(), Angle(center_long, angUnit),
+ Angle(latitude_first_parallel, angUnit),
+ Angle(latitude_second_parallel, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2677,27 +3945,37 @@ PJ_OBJ *proj_obj_create_projected_crs_InternationalMapWorldPolyconic(
*
* See osgeo::proj::operation::Conversion::createKrovakNorthOriented().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_KrovakNorthOriented(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeProjectionCentre,
- double longitudeOfOrigin, double colatitudeConeAxis,
- double latitudePseudoStandardParallel,
- double scaleFactorPseudoStandardParallel, double falseEasting,
- double falseNorthing, const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createKrovakNorthOriented(
- PropertyMap(), Angle(latitudeProjectionCentre, angUnit),
- Angle(longitudeOfOrigin, angUnit), Angle(colatitudeConeAxis, angUnit),
- Angle(latitudePseudoStandardParallel, angUnit),
- Scale(scaleFactorPseudoStandardParallel),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_krovak_north_oriented(
+ PJ_CONTEXT *ctx, double latitude_projection_centre,
+ double longitude_of_origin, double colatitude_cone_axis,
+ double latitude_pseudo_standard_parallel,
+ double scale_factor_pseudo_standard_parallel, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createKrovakNorthOriented(
+ PropertyMap(), Angle(latitude_projection_centre, angUnit),
+ Angle(longitude_of_origin, angUnit),
+ Angle(colatitude_cone_axis, angUnit),
+ Angle(latitude_pseudo_standard_parallel, angUnit),
+ Scale(scale_factor_pseudo_standard_parallel),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2706,27 +3984,37 @@ PJ_OBJ *proj_obj_create_projected_crs_KrovakNorthOriented(
*
* See osgeo::proj::operation::Conversion::createKrovak().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_Krovak(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeProjectionCentre,
- double longitudeOfOrigin, double colatitudeConeAxis,
- double latitudePseudoStandardParallel,
- double scaleFactorPseudoStandardParallel, double falseEasting,
- double falseNorthing, const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createKrovak(
- PropertyMap(), Angle(latitudeProjectionCentre, angUnit),
- Angle(longitudeOfOrigin, angUnit), Angle(colatitudeConeAxis, angUnit),
- Angle(latitudePseudoStandardParallel, angUnit),
- Scale(scaleFactorPseudoStandardParallel),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_krovak(
+ PJ_CONTEXT *ctx, double latitude_projection_centre,
+ double longitude_of_origin, double colatitude_cone_axis,
+ double latitude_pseudo_standard_parallel,
+ double scale_factor_pseudo_standard_parallel, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createKrovak(
+ PropertyMap(), Angle(latitude_projection_centre, angUnit),
+ Angle(longitude_of_origin, angUnit),
+ Angle(colatitude_cone_axis, angUnit),
+ Angle(latitude_pseudo_standard_parallel, angUnit),
+ Scale(scale_factor_pseudo_standard_parallel),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2735,23 +4023,31 @@ PJ_OBJ *proj_obj_create_projected_crs_Krovak(
*
* See osgeo::proj::operation::Conversion::createLambertAzimuthalEqualArea().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_LambertAzimuthalEqualArea(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeNatOrigin,
- double longitudeNatOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createLambertAzimuthalEqualArea(
- PropertyMap(), Angle(latitudeNatOrigin, angUnit),
- Angle(longitudeNatOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_lambert_azimuthal_equal_area(
+ PJ_CONTEXT *ctx, double latitude_nat_origin, double longitude_nat_origin,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createLambertAzimuthalEqualArea(
+ PropertyMap(), Angle(latitude_nat_origin, angUnit),
+ Angle(longitude_nat_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2760,22 +4056,30 @@ PJ_OBJ *proj_obj_create_projected_crs_LambertAzimuthalEqualArea(
*
* See osgeo::proj::operation::Conversion::createMillerCylindrical().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_MillerCylindrical(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createMillerCylindrical(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_miller_cylindrical(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createMillerCylindrical(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2784,23 +4088,31 @@ PJ_OBJ *proj_obj_create_projected_crs_MillerCylindrical(
*
* See osgeo::proj::operation::Conversion::createMercatorVariantA().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_MercatorVariantA(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createMercatorVariantA(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_mercator_variant_a(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createMercatorVariantA(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2809,23 +4121,30 @@ PJ_OBJ *proj_obj_create_projected_crs_MercatorVariantA(
*
* See osgeo::proj::operation::Conversion::createMercatorVariantB().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_MercatorVariantB(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeFirstParallel,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createMercatorVariantB(
- PropertyMap(), Angle(latitudeFirstParallel, angUnit),
- Angle(centerLong, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_mercator_variant_b(
+ PJ_CONTEXT *ctx, double latitude_first_parallel, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createMercatorVariantB(
+ PropertyMap(), Angle(latitude_first_parallel, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2835,22 +4154,30 @@ PJ_OBJ *proj_obj_create_projected_crs_MercatorVariantB(
* See
* osgeo::proj::operation::Conversion::createPopularVisualisationPseudoMercator().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_PopularVisualisationPseudoMercator(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createPopularVisualisationPseudoMercator(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_popular_visualisation_pseudo_mercator(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createPopularVisualisationPseudoMercator(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2859,22 +4186,30 @@ PJ_OBJ *proj_obj_create_projected_crs_PopularVisualisationPseudoMercator(
*
* See osgeo::proj::operation::Conversion::createMollweide().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Mollweide(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createMollweide(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_mollweide(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createMollweide(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2883,22 +4218,30 @@ PJ_OBJ *proj_obj_create_projected_crs_Mollweide(
*
* See osgeo::proj::operation::Conversion::createNewZealandMappingGrid().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_NewZealandMappingGrid(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createNewZealandMappingGrid(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_new_zealand_mapping_grid(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createNewZealandMappingGrid(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2907,23 +4250,31 @@ PJ_OBJ *proj_obj_create_projected_crs_NewZealandMappingGrid(
*
* See osgeo::proj::operation::Conversion::createObliqueStereographic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_ObliqueStereographic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createObliqueStereographic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_oblique_stereographic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createObliqueStereographic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2932,22 +4283,30 @@ PJ_OBJ *proj_obj_create_projected_crs_ObliqueStereographic(
*
* See osgeo::proj::operation::Conversion::createOrthographic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Orthographic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createOrthographic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_orthographic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createOrthographic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2956,22 +4315,30 @@ PJ_OBJ *proj_obj_create_projected_crs_Orthographic(
*
* See osgeo::proj::operation::Conversion::createAmericanPolyconic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_AmericanPolyconic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createAmericanPolyconic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_american_polyconic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createAmericanPolyconic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -2980,23 +4347,31 @@ PJ_OBJ *proj_obj_create_projected_crs_AmericanPolyconic(
*
* See osgeo::proj::operation::Conversion::createPolarStereographicVariantA().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_PolarStereographicVariantA(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createPolarStereographicVariantA(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_polar_stereographic_variant_a(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createPolarStereographicVariantA(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3005,23 +4380,31 @@ PJ_OBJ *proj_obj_create_projected_crs_PolarStereographicVariantA(
*
* See osgeo::proj::operation::Conversion::createPolarStereographicVariantB().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_PolarStereographicVariantB(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeStandardParallel,
- double longitudeOfOrigin, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createPolarStereographicVariantB(
- PropertyMap(), Angle(latitudeStandardParallel, angUnit),
- Angle(longitudeOfOrigin, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_polar_stereographic_variant_b(
+ PJ_CONTEXT *ctx, double latitude_standard_parallel,
+ double longitude_of_origin, double false_easting, double false_northing,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createPolarStereographicVariantB(
+ PropertyMap(), Angle(latitude_standard_parallel, angUnit),
+ Angle(longitude_of_origin, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3030,22 +4413,32 @@ PJ_OBJ *proj_obj_create_projected_crs_PolarStereographicVariantB(
*
* See osgeo::proj::operation::Conversion::createRobinson().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Robinson(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createRobinson(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_robinson(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createRobinson(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3054,22 +4447,30 @@ PJ_OBJ *proj_obj_create_projected_crs_Robinson(
*
* See osgeo::proj::operation::Conversion::createSinusoidal().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Sinusoidal(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createSinusoidal(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_sinusoidal(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createSinusoidal(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3078,23 +4479,31 @@ PJ_OBJ *proj_obj_create_projected_crs_Sinusoidal(
*
* See osgeo::proj::operation::Conversion::createStereographic().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_Stereographic(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double scale, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createStereographic(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Scale(scale), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_stereographic(
+ PJ_CONTEXT *ctx, double center_lat, double center_long, double scale,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createStereographic(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Scale(scale),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3103,22 +4512,30 @@ PJ_OBJ *proj_obj_create_projected_crs_Stereographic(
*
* See osgeo::proj::operation::Conversion::createVanDerGrinten().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_VanDerGrinten(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createVanDerGrinten(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_van_der_grinten(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createVanDerGrinten(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3127,22 +4544,32 @@ PJ_OBJ *proj_obj_create_projected_crs_VanDerGrinten(
*
* See osgeo::proj::operation::Conversion::createWagnerI().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerI(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerI(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_i(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerI(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3151,22 +4578,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerI(
*
* See osgeo::proj::operation::Conversion::createWagnerII().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerII(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerII(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_ii(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerII(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3175,23 +4610,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerII(
*
* See osgeo::proj::operation::Conversion::createWagnerIII().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerIII(
- PJ_OBJ *geodetic_crs, const char *crs_name, double latitudeTrueScale,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerIII(
- PropertyMap(), Angle(latitudeTrueScale, angUnit),
- Angle(centerLong, angUnit), Length(falseEasting, linearUnit),
- Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_iii(
+ PJ_CONTEXT *ctx, double latitude_true_scale, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerIII(
+ PropertyMap(), Angle(latitude_true_scale, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3200,22 +4642,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerIII(
*
* See osgeo::proj::operation::Conversion::createWagnerIV().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerIV(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerIV(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_iv(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerIV(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3224,22 +4674,32 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerIV(
*
* See osgeo::proj::operation::Conversion::createWagnerV().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerV(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerV(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_v(PJ_CONTEXT *ctx, double center_long,
+ double false_easting,
+ double false_northing,
+ const char *ang_unit_name,
+ double ang_unit_conv_factor,
+ const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerV(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3248,22 +4708,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerV(
*
* See osgeo::proj::operation::Conversion::createWagnerVI().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerVI(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerVI(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_vi(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerVI(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3272,22 +4740,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerVI(
*
* See osgeo::proj::operation::Conversion::createWagnerVII().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_WagnerVII(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createWagnerVII(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_wagner_vii(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createWagnerVII(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3297,22 +4773,30 @@ PJ_OBJ *proj_obj_create_projected_crs_WagnerVII(
* See
* osgeo::proj::operation::Conversion::createQuadrilateralizedSphericalCube().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_QuadrilateralizedSphericalCube(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLat,
- double centerLong, double falseEasting, double falseNorthing,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createQuadrilateralizedSphericalCube(
- PropertyMap(), Angle(centerLat, angUnit), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_quadrilateralized_spherical_cube(
+ PJ_CONTEXT *ctx, double center_lat, double center_long,
+ double false_easting, double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createQuadrilateralizedSphericalCube(
+ PropertyMap(), Angle(center_lat, angUnit),
+ Angle(center_long, angUnit), Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3321,23 +4805,30 @@ PJ_OBJ *proj_obj_create_projected_crs_QuadrilateralizedSphericalCube(
*
* See osgeo::proj::operation::Conversion::createSphericalCrossTrackHeight().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
*/
-PJ_OBJ *proj_obj_create_projected_crs_SphericalCrossTrackHeight(
- PJ_OBJ *geodetic_crs, const char *crs_name, double pegPointLat,
- double pegPointLong, double pegPointHeading, double pegPointHeight,
- const char *angUnitName, double angUnitConvFactor,
- const char *linearUnitName, double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createSphericalCrossTrackHeight(
- PropertyMap(), Angle(pegPointLat, angUnit),
- Angle(pegPointLong, angUnit), Angle(pegPointHeading, angUnit),
- Length(pegPointHeight, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+PJ_OBJ *proj_obj_create_conversion_spherical_cross_track_height(
+ PJ_CONTEXT *ctx, double peg_point_lat, double peg_point_long,
+ double peg_point_heading, double peg_point_height,
+ const char *ang_unit_name, double ang_unit_conv_factor,
+ const char *linear_unit_name, double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createSphericalCrossTrackHeight(
+ PropertyMap(), Angle(peg_point_lat, angUnit),
+ Angle(peg_point_long, angUnit), Angle(peg_point_heading, angUnit),
+ Length(peg_point_height, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
// ---------------------------------------------------------------------------
@@ -3346,22 +4837,30 @@ PJ_OBJ *proj_obj_create_projected_crs_SphericalCrossTrackHeight(
*
* See osgeo::proj::operation::Conversion::createEqualEarth().
*
- * Linear parameters are expressed in (linearUnitName, linearUnitConvFactor).
- * Angular parameters are expressed in (angUnitName, angUnitConvFactor).
- */
-PJ_OBJ *proj_obj_create_projected_crs_EqualEarth(
- PJ_OBJ *geodetic_crs, const char *crs_name, double centerLong,
- double falseEasting, double falseNorthing, const char *angUnitName,
- double angUnitConvFactor, const char *linearUnitName,
- double linearUnitConvFactor) {
- UnitOfMeasure linearUnit(
- createLinearUnit(linearUnitName, linearUnitConvFactor));
- UnitOfMeasure angUnit(createAngularUnit(angUnitName, angUnitConvFactor));
- auto conv = Conversion::createEqualEarth(
- PropertyMap(), Angle(centerLong, angUnit),
- Length(falseEasting, linearUnit), Length(falseNorthing, linearUnit));
- return proj_obj_create_projected_crs(geodetic_crs, crs_name, conv,
- linearUnit);
+ * Linear parameters are expressed in (linear_unit_name,
+ * linear_unit_conv_factor).
+ * Angular parameters are expressed in (ang_unit_name, ang_unit_conv_factor).
+ */
+PJ_OBJ *proj_obj_create_conversion_equal_earth(
+ PJ_CONTEXT *ctx, double center_long, double false_easting,
+ double false_northing, const char *ang_unit_name,
+ double ang_unit_conv_factor, const char *linear_unit_name,
+ double linear_unit_conv_factor) {
+ SANITIZE_CTX(ctx);
+ try {
+ UnitOfMeasure linearUnit(
+ createLinearUnit(linear_unit_name, linear_unit_conv_factor));
+ UnitOfMeasure angUnit(
+ createAngularUnit(ang_unit_name, ang_unit_conv_factor));
+ auto conv = Conversion::createEqualEarth(
+ PropertyMap(), Angle(center_long, angUnit),
+ Length(false_easting, linearUnit),
+ Length(false_northing, linearUnit));
+ return proj_obj_create_conversion(conv);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
+ return nullptr;
}
/* END: Generated by scripts/create_c_api_projections.py*/
@@ -3371,21 +4870,23 @@ PJ_OBJ *proj_obj_create_projected_crs_EqualEarth(
* a PROJ pipeline, checking in particular that referenced grids are
* available.
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type CoordinateOperation or derived classes
* (must not be NULL)
* @return TRUE or FALSE.
*/
-int proj_coordoperation_is_instanciable(PJ_OBJ *coordoperation) {
+int proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation) {
assert(coordoperation);
auto op =
dynamic_cast<const CoordinateOperation *>(coordoperation->obj.get());
if (!op) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a CoordinateOperation");
return 0;
}
- auto dbContext = getDBcontextNoException(coordoperation->ctx, __FUNCTION__);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
return op->isPROJInstanciable(dbContext) ? 1 : 0;
} catch (const std::exception &) {
@@ -3397,16 +4898,18 @@ int proj_coordoperation_is_instanciable(PJ_OBJ *coordoperation) {
/** \brief Return the number of parameters of a SingleOperation
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type SingleOperation or derived classes
* (must not be NULL)
*/
-int proj_coordoperation_get_param_count(PJ_OBJ *coordoperation) {
+int proj_coordoperation_get_param_count(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation) {
+ SANITIZE_CTX(ctx);
assert(coordoperation);
auto op = dynamic_cast<const SingleOperation *>(coordoperation->obj.get());
if (!op) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
- "Object is not a SingleOperation");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a SingleOperation");
return 0;
}
return static_cast<int>(op->parameterValues().size());
@@ -3416,20 +4919,22 @@ int proj_coordoperation_get_param_count(PJ_OBJ *coordoperation) {
/** \brief Return the index of a parameter of a SingleOperation
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type SingleOperation or derived classes
* (must not be NULL)
* @param name Parameter name. Must not be NULL
* @return index (>=0), or -1 in case of error.
*/
-int proj_coordoperation_get_param_index(PJ_OBJ *coordoperation,
+int proj_coordoperation_get_param_index(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation,
const char *name) {
+ SANITIZE_CTX(ctx);
assert(coordoperation);
assert(name);
auto op = dynamic_cast<const SingleOperation *>(coordoperation->obj.get());
if (!op) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
- "Object is not a SingleOperation");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a SingleOperation");
return -1;
}
int index = 0;
@@ -3446,64 +4951,66 @@ int proj_coordoperation_get_param_index(PJ_OBJ *coordoperation,
/** \brief Return a parameter of a SingleOperation
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type SingleOperation or derived classes
* (must not be NULL)
* @param index Parameter index.
- * @param pName Pointer to a string value to store the parameter name. or NULL
- * @param pNameAuthorityName Pointer to a string value to store the parameter
+ * @param out_name Pointer to a string value to store the parameter name. or
+ * NULL
+ * @param out_auth_name Pointer to a string value to store the parameter
* authority name. or NULL
- * @param pNameCode Pointer to a string value to store the parameter
+ * @param out_code Pointer to a string value to store the parameter
* code. or NULL
- * @param pValue Pointer to a double value to store the parameter
+ * @param out_value Pointer to a double value to store the parameter
* value (if numeric). or NULL
- * @param pValueString Pointer to a string value to store the parameter
+ * @param out_value_string Pointer to a string value to store the parameter
* value (if of type string). or NULL
- * @param pValueUnitConvFactor Pointer to a double value to store the parameter
+ * @param out_unit_conv_factor Pointer to a double value to store the parameter
* unit conversion factor. or NULL
- * @param pValueUnitName Pointer to a string value to store the parameter
+ * @param out_unit_name Pointer to a string value to store the parameter
* unit name. or NULL
* @return TRUE in case of success.
*/
-int proj_coordoperation_get_param(PJ_OBJ *coordoperation, int index,
- const char **pName,
- const char **pNameAuthorityName,
- const char **pNameCode, double *pValue,
- const char **pValueString,
- double *pValueUnitConvFactor,
- const char **pValueUnitName) {
+int proj_coordoperation_get_param(PJ_CONTEXT *ctx, const PJ_OBJ *coordoperation,
+ int index, const char **out_name,
+ const char **out_auth_name,
+ const char **out_code, double *out_value,
+ const char **out_value_string,
+ double *out_unit_conv_factor,
+ const char **out_unit_name) {
+ SANITIZE_CTX(ctx);
assert(coordoperation);
auto op = dynamic_cast<const SingleOperation *>(coordoperation->obj.get());
if (!op) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
- "Object is not a SingleOperation");
+ proj_log_error(ctx, __FUNCTION__, "Object is not a SingleOperation");
return false;
}
const auto &parameters = op->method()->parameters();
const auto &values = op->parameterValues();
if (static_cast<size_t>(index) >= parameters.size() ||
static_cast<size_t>(index) >= values.size()) {
- proj_log_error(coordoperation->ctx, __FUNCTION__, "Invalid index");
+ proj_log_error(ctx, __FUNCTION__, "Invalid index");
return false;
}
const auto &param = parameters[index];
const auto &param_ids = param->identifiers();
- if (pName) {
- *pName = param->name()->description()->c_str();
+ if (out_name) {
+ *out_name = param->name()->description()->c_str();
}
- if (pNameAuthorityName) {
+ if (out_auth_name) {
if (!param_ids.empty()) {
- *pNameAuthorityName = param_ids[0]->codeSpace()->c_str();
+ *out_auth_name = param_ids[0]->codeSpace()->c_str();
} else {
- *pNameAuthorityName = nullptr;
+ *out_auth_name = nullptr;
}
}
- if (pNameCode) {
+ if (out_code) {
if (!param_ids.empty()) {
- *pNameCode = param_ids[0]->code().c_str();
+ *out_code = param_ids[0]->code().c_str();
} else {
- *pNameCode = nullptr;
+ *out_code = nullptr;
}
}
@@ -3514,38 +5021,38 @@ int proj_coordoperation_get_param(PJ_OBJ *coordoperation, int index,
if (opParamValue) {
paramValue = opParamValue->parameterValue().as_nullable();
}
- if (pValue) {
- *pValue = 0;
+ if (out_value) {
+ *out_value = 0;
if (paramValue) {
if (paramValue->type() == ParameterValue::Type::MEASURE) {
- *pValue = paramValue->value().value();
+ *out_value = paramValue->value().value();
}
}
}
- if (pValueString) {
- *pValueString = nullptr;
+ if (out_value_string) {
+ *out_value_string = nullptr;
if (paramValue) {
if (paramValue->type() == ParameterValue::Type::FILENAME) {
- *pValueString = paramValue->valueFile().c_str();
+ *out_value_string = paramValue->valueFile().c_str();
} else if (paramValue->type() == ParameterValue::Type::STRING) {
- *pValueString = paramValue->stringValue().c_str();
+ *out_value_string = paramValue->stringValue().c_str();
}
}
}
- if (pValueUnitConvFactor) {
- *pValueUnitConvFactor = 0;
+ if (out_unit_conv_factor) {
+ *out_unit_conv_factor = 0;
if (paramValue) {
if (paramValue->type() == ParameterValue::Type::MEASURE) {
- *pValueUnitConvFactor =
+ *out_unit_conv_factor =
paramValue->value().unit().conversionToSI();
}
}
}
- if (pValueUnitName) {
- *pValueUnitName = nullptr;
+ if (out_unit_name) {
+ *out_unit_name = nullptr;
if (paramValue) {
if (paramValue->type() == ParameterValue::Type::MEASURE) {
- *pValueUnitName = paramValue->value().unit().name().c_str();
+ *out_unit_name = paramValue->value().unit().name().c_str();
}
}
}
@@ -3557,20 +5064,23 @@ int proj_coordoperation_get_param(PJ_OBJ *coordoperation, int index,
/** \brief Return the number of grids used by a CoordinateOperation
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type CoordinateOperation or derived classes
* (must not be NULL)
*/
-int proj_coordoperation_get_grid_used_count(PJ_OBJ *coordoperation) {
+int proj_coordoperation_get_grid_used_count(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation) {
+ SANITIZE_CTX(ctx);
assert(coordoperation);
auto co =
dynamic_cast<const CoordinateOperation *>(coordoperation->obj.get());
if (!co) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a CoordinateOperation");
return 0;
}
- auto dbContext = getDBcontextNoException(coordoperation->ctx, __FUNCTION__);
+ auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
if (!coordoperation->gridsNeededAsked) {
coordoperation->gridsNeededAsked = true;
@@ -3581,7 +5091,7 @@ int proj_coordoperation_get_grid_used_count(PJ_OBJ *coordoperation) {
}
return static_cast<int>(coordoperation->gridsNeeded.size());
} catch (const std::exception &e) {
- proj_log_error(coordoperation->ctx, __FUNCTION__, e.what());
+ proj_log_error(ctx, __FUNCTION__, e.what());
return 0;
}
}
@@ -3590,65 +5100,68 @@ int proj_coordoperation_get_grid_used_count(PJ_OBJ *coordoperation) {
/** \brief Return a parameter of a SingleOperation
*
+ * @param ctx PROJ context, or NULL for default context
* @param coordoperation Objet of type SingleOperation or derived classes
* (must not be NULL)
* @param index Parameter index.
- * @param pShortName Pointer to a string value to store the grid short name. or
- * NULL
- * @param pFullName Pointer to a string value to store the grid full filename.
+ * @param out_short_name Pointer to a string value to store the grid short name.
* or NULL
- * @param pPackageName Pointer to a string value to store the package name where
+ * @param out_full_name Pointer to a string value to store the grid full
+ * filename. or NULL
+ * @param out_package_name Pointer to a string value to store the package name
+ * where
* the grid might be found. or NULL
- * @param pURL Pointer to a string value to store the grid URL or the
+ * @param out_url Pointer to a string value to store the grid URL or the
* package URL where the grid might be found. or NULL
- * @param pDirectDownload Pointer to a int (boolean) value to store whether
- * *pURL can be downloaded directly. or NULL
- * @param pOpenLicense Pointer to a int (boolean) value to store whether
+ * @param out_direct_download Pointer to a int (boolean) value to store whether
+ * *out_url can be downloaded directly. or NULL
+ * @param out_open_license Pointer to a int (boolean) value to store whether
* the grid is released with an open license. or NULL
- * @param pAvailable Pointer to a int (boolean) value to store whether the grid
- * is available at runtime. or NULL
+ * @param out_available Pointer to a int (boolean) value to store whether the
+ * grid is available at runtime. or NULL
* @return TRUE in case of success.
*/
-int proj_coordoperation_get_grid_used(PJ_OBJ *coordoperation, int index,
- const char **pShortName,
- const char **pFullName,
- const char **pPackageName,
- const char **pURL, int *pDirectDownload,
- int *pOpenLicense, int *pAvailable) {
- const int count = proj_coordoperation_get_grid_used_count(coordoperation);
+int proj_coordoperation_get_grid_used(
+ PJ_CONTEXT *ctx, const PJ_OBJ *coordoperation, int index,
+ const char **out_short_name, const char **out_full_name,
+ const char **out_package_name, const char **out_url,
+ int *out_direct_download, int *out_open_license, int *out_available) {
+ SANITIZE_CTX(ctx);
+ const int count =
+ proj_coordoperation_get_grid_used_count(ctx, coordoperation);
if (index < 0 || index >= count) {
- proj_log_error(coordoperation->ctx, __FUNCTION__, "Invalid index");
+ proj_log_error(ctx, __FUNCTION__, "Invalid index");
return false;
}
const auto &gridDesc = coordoperation->gridsNeeded[index];
- if (pShortName) {
- *pShortName = gridDesc.shortName.c_str();
+ if (out_short_name) {
+ *out_short_name = gridDesc.shortName.c_str();
}
- if (pFullName) {
- *pFullName = gridDesc.fullName.c_str();
+ if (out_full_name) {
+ *out_full_name = gridDesc.fullName.c_str();
}
- if (pPackageName) {
- *pPackageName = gridDesc.packageName.c_str();
+ if (out_package_name) {
+ *out_package_name = gridDesc.packageName.c_str();
}
- if (pURL) {
- *pURL = gridDesc.url.c_str();
+ if (out_url) {
+ *out_url = gridDesc.url.c_str();
}
- if (pDirectDownload) {
- *pDirectDownload = gridDesc.directDownload;
+ if (out_direct_download) {
+ *out_direct_download = gridDesc.directDownload;
}
- if (pOpenLicense) {
- *pOpenLicense = gridDesc.openLicense;
+ if (out_open_license) {
+ *out_open_license = gridDesc.openLicense;
}
- if (pAvailable) {
- *pAvailable = gridDesc.available;
+ if (out_available) {
+ *out_available = gridDesc.available;
}
return true;
@@ -3659,12 +5172,11 @@ int proj_coordoperation_get_grid_used(PJ_OBJ *coordoperation, int index,
/** \brief Opaque object representing an operation factory context. */
struct PJ_OPERATION_FACTORY_CONTEXT {
//! @cond Doxygen_Suppress
- PJ_CONTEXT *ctx;
CoordinateOperationContextNNPtr operationContext;
explicit PJ_OPERATION_FACTORY_CONTEXT(
- PJ_CONTEXT *ctxIn, CoordinateOperationContextNNPtr &&operationContextIn)
- : ctx(ctxIn), operationContext(std::move(operationContextIn)) {}
+ CoordinateOperationContextNNPtr &&operationContextIn)
+ : operationContext(std::move(operationContextIn)) {}
PJ_OPERATION_FACTORY_CONTEXT(const PJ_OPERATION_FACTORY_CONTEXT &) = delete;
PJ_OPERATION_FACTORY_CONTEXT &
@@ -3700,12 +5212,12 @@ proj_create_operation_factory_context(PJ_CONTEXT *ctx, const char *authority) {
auto operationContext =
CoordinateOperationContext::create(authFactory, nullptr, 0.0);
return new PJ_OPERATION_FACTORY_CONTEXT(
- ctx, std::move(operationContext));
+ std::move(operationContext));
} else {
auto operationContext =
CoordinateOperationContext::create(nullptr, nullptr, 0.0);
return new PJ_OPERATION_FACTORY_CONTEXT(
- ctx, std::move(operationContext));
+ std::move(operationContext));
}
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
@@ -3720,22 +5232,29 @@ proj_create_operation_factory_context(PJ_CONTEXT *ctx, const char *authority) {
* This method should be called one and exactly one for each function
* returning a PJ_OPERATION_FACTORY_CONTEXT*
*
- * @param ctxt Object, or NULL.
+ * @param ctx Object, or NULL.
*/
-void proj_operation_factory_context_unref(PJ_OPERATION_FACTORY_CONTEXT *ctxt) {
- delete ctxt;
+void proj_operation_factory_context_unref(PJ_OPERATION_FACTORY_CONTEXT *ctx) {
+ delete ctx;
}
// ---------------------------------------------------------------------------
/** \brief Set the desired accuracy of the resulting coordinate transformations.
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param accuracy Accuracy in meter (or 0 to disable the filter).
*/
void proj_operation_factory_context_set_desired_accuracy(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, double accuracy) {
- assert(ctxt);
- ctxt->operationContext->setDesiredAccuracy(accuracy);
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ double accuracy) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ factory_ctx->operationContext->setDesiredAccuracy(accuracy);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
}
// ---------------------------------------------------------------------------
@@ -3743,21 +5262,29 @@ void proj_operation_factory_context_set_desired_accuracy(
/** \brief Set the desired area of interest for the resulting coordinate
* transformations.
*
- * For an area of interest crossing the anti-meridian, west_lon will be
- * greater than east_lon.
+ * For an area of interest crossing the anti-meridian, west_lon_degree will be
+ * greater than east_lon_degree.
*
- * @param ctxt Operation factory context. must not be NULL
- * @param west_lon West longitude (in degrees).
- * @param south_lat South latitude (in degrees).
- * @param east_lon East longitude (in degrees).
- * @param north_lat North latitude (in degrees).
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
+ * @param west_lon_degree West longitude (in degrees).
+ * @param south_lat_degree South latitude (in degrees).
+ * @param east_lon_degree East longitude (in degrees).
+ * @param north_lat_degree North latitude (in degrees).
*/
void proj_operation_factory_context_set_area_of_interest(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, double west_lon, double south_lat,
- double east_lon, double north_lat) {
- assert(ctxt);
- ctxt->operationContext->setAreaOfInterest(
- Extent::createFromBBOX(west_lon, south_lat, east_lon, north_lat));
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ double west_lon_degree, double south_lat_degree, double east_lon_degree,
+ double north_lat_degree) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ factory_ctx->operationContext->setAreaOfInterest(
+ Extent::createFromBBOX(west_lon_degree, south_lat_degree,
+ east_lon_degree, north_lat_degree));
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
}
// ---------------------------------------------------------------------------
@@ -3768,32 +5295,40 @@ void proj_operation_factory_context_set_area_of_interest(
*
* The default is PJ_CRS_EXTENT_SMALLEST.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param use How source and target CRS extent should be used.
*/
void proj_operation_factory_context_set_crs_extent_use(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, PROJ_CRS_EXTENT_USE use) {
- assert(ctxt);
- switch (use) {
- case PJ_CRS_EXTENT_NONE:
- ctxt->operationContext->setSourceAndTargetCRSExtentUse(
- CoordinateOperationContext::SourceTargetCRSExtentUse::NONE);
- break;
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ PROJ_CRS_EXTENT_USE use) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ switch (use) {
+ case PJ_CRS_EXTENT_NONE:
+ factory_ctx->operationContext->setSourceAndTargetCRSExtentUse(
+ CoordinateOperationContext::SourceTargetCRSExtentUse::NONE);
+ break;
- case PJ_CRS_EXTENT_BOTH:
- ctxt->operationContext->setSourceAndTargetCRSExtentUse(
- CoordinateOperationContext::SourceTargetCRSExtentUse::BOTH);
- break;
+ case PJ_CRS_EXTENT_BOTH:
+ factory_ctx->operationContext->setSourceAndTargetCRSExtentUse(
+ CoordinateOperationContext::SourceTargetCRSExtentUse::BOTH);
+ break;
- case PJ_CRS_EXTENT_INTERSECTION:
- ctxt->operationContext->setSourceAndTargetCRSExtentUse(
- CoordinateOperationContext::SourceTargetCRSExtentUse::INTERSECTION);
- break;
+ case PJ_CRS_EXTENT_INTERSECTION:
+ factory_ctx->operationContext->setSourceAndTargetCRSExtentUse(
+ CoordinateOperationContext::SourceTargetCRSExtentUse::
+ INTERSECTION);
+ break;
- case PJ_CRS_EXTENT_SMALLEST:
- ctxt->operationContext->setSourceAndTargetCRSExtentUse(
- CoordinateOperationContext::SourceTargetCRSExtentUse::SMALLEST);
- break;
+ case PJ_CRS_EXTENT_SMALLEST:
+ factory_ctx->operationContext->setSourceAndTargetCRSExtentUse(
+ CoordinateOperationContext::SourceTargetCRSExtentUse::SMALLEST);
+ break;
+ }
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
}
}
@@ -3806,22 +5341,31 @@ void proj_operation_factory_context_set_crs_extent_use(
*
* The default is PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param criterion patial criterion to use
*/
void PROJ_DLL proj_operation_factory_context_set_spatial_criterion(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, PROJ_SPATIAL_CRITERION criterion) {
- assert(ctxt);
- switch (criterion) {
- case PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT:
- ctxt->operationContext->setSpatialCriterion(
- CoordinateOperationContext::SpatialCriterion::STRICT_CONTAINMENT);
- break;
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ PROJ_SPATIAL_CRITERION criterion) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ switch (criterion) {
+ case PROJ_SPATIAL_CRITERION_STRICT_CONTAINMENT:
+ factory_ctx->operationContext->setSpatialCriterion(
+ CoordinateOperationContext::SpatialCriterion::
+ STRICT_CONTAINMENT);
+ break;
- case PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION:
- ctxt->operationContext->setSpatialCriterion(
- CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
- break;
+ case PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION:
+ factory_ctx->operationContext->setSpatialCriterion(
+ CoordinateOperationContext::SpatialCriterion::
+ PARTIAL_INTERSECTION);
+ break;
+ }
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
}
}
@@ -3831,29 +5375,37 @@ void PROJ_DLL proj_operation_factory_context_set_spatial_criterion(
*
* The default is USE_FOR_SORTING.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param use how grid availability is used.
*/
void PROJ_DLL proj_operation_factory_context_set_grid_availability_use(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, PROJ_GRID_AVAILABILITY_USE use) {
- assert(ctxt);
- switch (use) {
- case PROJ_GRID_AVAILABILITY_USED_FOR_SORTING:
- ctxt->operationContext->setGridAvailabilityUse(
- CoordinateOperationContext::GridAvailabilityUse::USE_FOR_SORTING);
- break;
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ PROJ_GRID_AVAILABILITY_USE use) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ switch (use) {
+ case PROJ_GRID_AVAILABILITY_USED_FOR_SORTING:
+ factory_ctx->operationContext->setGridAvailabilityUse(
+ CoordinateOperationContext::GridAvailabilityUse::
+ USE_FOR_SORTING);
+ break;
- case PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID:
- ctxt->operationContext->setGridAvailabilityUse(
- CoordinateOperationContext::GridAvailabilityUse::
- DISCARD_OPERATION_IF_MISSING_GRID);
- break;
+ case PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID:
+ factory_ctx->operationContext->setGridAvailabilityUse(
+ CoordinateOperationContext::GridAvailabilityUse::
+ DISCARD_OPERATION_IF_MISSING_GRID);
+ break;
- case PROJ_GRID_AVAILABILITY_IGNORED:
- ctxt->operationContext->setGridAvailabilityUse(
- CoordinateOperationContext::GridAvailabilityUse::
- IGNORE_GRID_AVAILABILITY);
- break;
+ case PROJ_GRID_AVAILABILITY_IGNORED:
+ factory_ctx->operationContext->setGridAvailabilityUse(
+ CoordinateOperationContext::GridAvailabilityUse::
+ IGNORE_GRID_AVAILABILITY);
+ break;
+ }
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
}
}
@@ -3864,13 +5416,21 @@ void PROJ_DLL proj_operation_factory_context_set_grid_availability_use(
*
* The default is true.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param usePROJNames whether PROJ alternative grid names should be used
*/
void proj_operation_factory_context_set_use_proj_alternative_grid_names(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, int usePROJNames) {
- assert(ctxt);
- ctxt->operationContext->setUsePROJAlternativeGridNames(usePROJNames != 0);
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ int usePROJNames) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ factory_ctx->operationContext->setUsePROJAlternativeGridNames(
+ usePROJNames != 0);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
}
// ---------------------------------------------------------------------------
@@ -3892,13 +5452,19 @@ void proj_operation_factory_context_set_use_proj_alternative_grid_names(
*
* The default is true.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param allow whether intermediate CRS may be used.
*/
void proj_operation_factory_context_set_allow_use_intermediate_crs(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, int allow) {
- assert(ctxt);
- ctxt->operationContext->setAllowUseIntermediateCRS(allow != 0);
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx, int allow) {
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ factory_ctx->operationContext->setAllowUseIntermediateCRS(allow != 0);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ }
}
// ---------------------------------------------------------------------------
@@ -3906,21 +5472,27 @@ void proj_operation_factory_context_set_allow_use_intermediate_crs(
/** \brief Restrict the potential pivot CRSs that can be used when trying to
* build a coordinate operation between two CRS that have no direct operation.
*
- * @param ctxt Operation factory context. must not be NULL
+ * @param ctx PROJ context, or NULL for default context
+ * @param factory_ctx Operation factory context. must not be NULL
* @param list_of_auth_name_codes an array of strings NLL terminated,
* with the format { "auth_name1", "code1", "auth_name2", "code2", ... NULL }
*/
void proj_operation_factory_context_set_allowed_intermediate_crs(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
const char *const *list_of_auth_name_codes) {
- assert(ctxt);
- std::vector<std::pair<std::string, std::string>> pivots;
- for (auto iter = list_of_auth_name_codes; iter && iter[0] && iter[1];
- iter += 2) {
- pivots.emplace_back(std::pair<std::string, std::string>(
- std::string(iter[0]), std::string(iter[1])));
+ SANITIZE_CTX(ctx);
+ assert(factory_ctx);
+ try {
+ std::vector<std::pair<std::string, std::string>> pivots;
+ for (auto iter = list_of_auth_name_codes; iter && iter[0] && iter[1];
+ iter += 2) {
+ pivots.emplace_back(std::pair<std::string, std::string>(
+ std::string(iter[0]), std::string(iter[1])));
+ }
+ factory_ctx->operationContext->setIntermediateCRS(pivots);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
}
- ctxt->operationContext->setIntermediateCRS(pivots);
}
// ---------------------------------------------------------------------------
@@ -3935,29 +5507,29 @@ void proj_operation_factory_context_set_allowed_intermediate_crs(
* by increasing accuracy. Operations with unknown accuracy are sorted last,
* whatever their area.
*
+ * @param ctx PROJ context, or NULL for default context
* @param source_crs source CRS. Must not be NULL.
* @param target_crs source CRS. Must not be NULL.
* @param operationContext Search context. Must not be NULL.
* @return a result set that must be unreferenced with
* proj_obj_list_unref(), or NULL in case of error.
*/
-PJ_OBJ_LIST *
-proj_obj_create_operations(PJ_OBJ *source_crs, PJ_OBJ *target_crs,
- PJ_OPERATION_FACTORY_CONTEXT *operationContext) {
+PJ_OBJ_LIST *proj_obj_create_operations(
+ PJ_CONTEXT *ctx, const PJ_OBJ *source_crs, const PJ_OBJ *target_crs,
+ const PJ_OPERATION_FACTORY_CONTEXT *operationContext) {
+ SANITIZE_CTX(ctx);
assert(source_crs);
assert(target_crs);
assert(operationContext);
auto sourceCRS = nn_dynamic_pointer_cast<CRS>(source_crs->obj);
if (!sourceCRS) {
- proj_log_error(operationContext->ctx, __FUNCTION__,
- "source_crs is not a CRS");
+ proj_log_error(ctx, __FUNCTION__, "source_crs is not a CRS");
return nullptr;
}
auto targetCRS = nn_dynamic_pointer_cast<CRS>(target_crs->obj);
if (!targetCRS) {
- proj_log_error(operationContext->ctx, __FUNCTION__,
- "target_crs is not a CRS");
+ proj_log_error(ctx, __FUNCTION__, "target_crs is not a CRS");
return nullptr;
}
@@ -3970,9 +5542,9 @@ proj_obj_create_operations(PJ_OBJ *source_crs, PJ_OBJ *target_crs,
for (const auto &op : ops) {
objects.emplace_back(op);
}
- return new PJ_OBJ_LIST(operationContext->ctx, std::move(objects));
+ return new PJ_OBJ_LIST(std::move(objects));
} catch (const std::exception &e) {
- proj_log_error(operationContext->ctx, __FUNCTION__, e.what());
+ proj_log_error(ctx, __FUNCTION__, e.what());
return nullptr;
}
}
@@ -3983,7 +5555,7 @@ proj_obj_create_operations(PJ_OBJ *source_crs, PJ_OBJ *target_crs,
*
* @param result Objet of type PJ_OBJ_LIST (must not be NULL)
*/
-int proj_obj_list_get_count(PJ_OBJ_LIST *result) {
+int proj_obj_list_get_count(const PJ_OBJ_LIST *result) {
assert(result);
return static_cast<int>(result->objects.size());
}
@@ -3996,19 +5568,22 @@ int proj_obj_list_get_count(PJ_OBJ_LIST *result) {
* use.
* It should be used by at most one thread at a time.
*
+ * @param ctx PROJ context, or NULL for default context
* @param result Objet of type PJ_OBJ_LIST (must not be NULL)
* @param index Index
* @return a new object that must be unreferenced with proj_obj_unref(),
* or nullptr in case of error.
*/
-PJ_OBJ *proj_obj_list_get(PJ_OBJ_LIST *result, int index) {
+PJ_OBJ *proj_obj_list_get(PJ_CONTEXT *ctx, const PJ_OBJ_LIST *result,
+ int index) {
+ SANITIZE_CTX(ctx);
assert(result);
if (index < 0 || index >= proj_obj_list_get_count(result)) {
- proj_log_error(result->ctx, __FUNCTION__, "Invalid index");
+ proj_log_error(ctx, __FUNCTION__, "Invalid index");
return nullptr;
}
- return PJ_OBJ::create(result->ctx, result->objects[index]);
+ return PJ_OBJ::create(result->objects[index]);
}
// ---------------------------------------------------------------------------
@@ -4026,14 +5601,18 @@ void proj_obj_list_unref(PJ_OBJ_LIST *result) { delete result; }
/** \brief Return the accuracy (in metre) of a coordinate operation.
*
+ * @param ctx PROJ context, or NULL for default context
+ * @param coordoperation Coordinate operation. Must not be NULL.
* @return the accuracy, or a negative value if unknown or in case of error.
*/
-double proj_coordoperation_get_accuracy(PJ_OBJ *coordoperation) {
+double proj_coordoperation_get_accuracy(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation) {
+ SANITIZE_CTX(ctx);
assert(coordoperation);
auto co =
dynamic_cast<const CoordinateOperation *>(coordoperation->obj.get());
if (!co) {
- proj_log_error(coordoperation->ctx, __FUNCTION__,
+ proj_log_error(ctx, __FUNCTION__,
"Object is not a CoordinateOperation");
return -1;
}
@@ -4047,3 +5626,176 @@ double proj_coordoperation_get_accuracy(PJ_OBJ *coordoperation) {
}
return -1;
}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns the datum of a SingleCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs Objet of type SingleCRS (must not be NULL)
+ * @return Object that must be unreferenced with proj_obj_unref(), or NULL
+ * in case of error (or if there is no datum)
+ */
+PJ_OBJ *proj_obj_crs_get_datum(PJ_CONTEXT *ctx, const PJ_OBJ *crs) {
+ SANITIZE_CTX(ctx);
+ assert(crs);
+ auto l_crs = dynamic_cast<const SingleCRS *>(crs->obj.get());
+ if (!l_crs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a SingleCRS");
+ return nullptr;
+ }
+ const auto &datum = l_crs->datum();
+ if (!datum) {
+ return nullptr;
+ }
+ return PJ_OBJ::create(NN_NO_CHECK(datum));
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns the coordinate system of a SingleCRS.
+ *
+ * The returned object must be unreferenced with proj_obj_unref() after
+ * use.
+ * It should be used by at most one thread at a time.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param crs Objet of type SingleCRS (must not be NULL)
+ * @return Object that must be unreferenced with proj_obj_unref(), or NULL
+ * in case of error.
+ */
+PJ_OBJ *proj_obj_crs_get_coordinate_system(PJ_CONTEXT *ctx, const PJ_OBJ *crs) {
+ SANITIZE_CTX(ctx);
+ assert(crs);
+ auto l_crs = dynamic_cast<const SingleCRS *>(crs->obj.get());
+ if (!l_crs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a SingleCRS");
+ return nullptr;
+ }
+ return PJ_OBJ::create(l_crs->coordinateSystem());
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns the type of the coordinate system.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param cs Objet of type CoordinateSystem (must not be NULL)
+ * @return type, or PJ_CS_TYPE_UNKNOWN in case of error.
+ */
+PJ_COORDINATE_SYSTEM_TYPE proj_obj_cs_get_type(PJ_CONTEXT *ctx,
+ const PJ_OBJ *cs) {
+ SANITIZE_CTX(ctx);
+ assert(cs);
+ auto l_cs = dynamic_cast<const CoordinateSystem *>(cs->obj.get());
+ if (!l_cs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CoordinateSystem");
+ return PJ_CS_TYPE_UNKNOWN;
+ }
+ if (dynamic_cast<const CartesianCS *>(l_cs)) {
+ return PJ_CS_TYPE_CARTESIAN;
+ }
+ if (dynamic_cast<const EllipsoidalCS *>(l_cs)) {
+ return PJ_CS_TYPE_ELLIPSOIDAL;
+ }
+ if (dynamic_cast<const VerticalCS *>(l_cs)) {
+ return PJ_CS_TYPE_VERTICAL;
+ }
+ if (dynamic_cast<const SphericalCS *>(l_cs)) {
+ return PJ_CS_TYPE_SPHERICAL;
+ }
+ if (dynamic_cast<const OrdinalCS *>(l_cs)) {
+ return PJ_CS_TYPE_ORDINAL;
+ }
+ if (dynamic_cast<const ParametricCS *>(l_cs)) {
+ return PJ_CS_TYPE_PARAMETRIC;
+ }
+ if (dynamic_cast<const DateTimeTemporalCS *>(l_cs)) {
+ return PJ_CS_TYPE_DATETIMETEMPORAL;
+ }
+ if (dynamic_cast<const TemporalCountCS *>(l_cs)) {
+ return PJ_CS_TYPE_TEMPORALCOUNT;
+ }
+ if (dynamic_cast<const TemporalMeasureCS *>(l_cs)) {
+ return PJ_CS_TYPE_TEMPORALMEASURE;
+ }
+ return PJ_CS_TYPE_UNKNOWN;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns the number of axis of the coordinate system.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param cs Objet of type CoordinateSystem (must not be NULL)
+ * @return number of axis, or -1 in case of error.
+ */
+int proj_obj_cs_get_axis_count(PJ_CONTEXT *ctx, const PJ_OBJ *cs) {
+ SANITIZE_CTX(ctx);
+ assert(cs);
+ auto l_cs = dynamic_cast<const CoordinateSystem *>(cs->obj.get());
+ if (!l_cs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CoordinateSystem");
+ return -1;
+ }
+ return static_cast<int>(l_cs->axisList().size());
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Returns information on an axis
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param cs Objet of type CoordinateSystem (must not be NULL)
+ * @param index Index of the coordinate system (between 0 and
+ * proj_obj_cs_get_axis_count() - 1)
+ * @param out_name Pointer to a string value to store the axis name. or NULL
+ * @param out_abbrev Pointer to a string value to store the axis abbreviation.
+ * or NULL
+ * @param out_direction Pointer to a string value to store the axis direction.
+ * or NULL
+ * @param out_unit_conv_factor Pointer to a double value to store the axis
+ * unit conversion factor. or NULL
+ * @param out_unit_name Pointer to a string value to store the axis
+ * unit name. or NULL
+ * @return TRUE in case of success
+ */
+int proj_obj_cs_get_axis_info(PJ_CONTEXT *ctx, const PJ_OBJ *cs, int index,
+ const char **out_name, const char **out_abbrev,
+ const char **out_direction,
+ double *out_unit_conv_factor,
+ const char **out_unit_name) {
+ SANITIZE_CTX(ctx);
+ assert(cs);
+ auto l_cs = dynamic_cast<const CoordinateSystem *>(cs->obj.get());
+ if (!l_cs) {
+ proj_log_error(ctx, __FUNCTION__, "Object is not a CoordinateSystem");
+ return false;
+ }
+ const auto &axisList = l_cs->axisList();
+ if (index < 0 || static_cast<size_t>(index) >= axisList.size()) {
+ proj_log_error(ctx, __FUNCTION__, "Invalid index");
+ return false;
+ }
+ const auto &axis = axisList[index];
+ if (out_name) {
+ *out_name = axis->nameStr().c_str();
+ }
+ if (out_abbrev) {
+ *out_abbrev = axis->abbreviation().c_str();
+ }
+ if (out_direction) {
+ *out_direction = axis->direction().toString().c_str();
+ }
+ if (out_unit_conv_factor) {
+ *out_unit_conv_factor = axis->unit().conversionToSI();
+ }
+ if (out_unit_name) {
+ *out_unit_name = axis->unit().name().c_str();
+ }
+ return true;
+}
diff --git a/src/coordinateoperation.cpp b/src/coordinateoperation.cpp
index 42cc806e..bbe84698 100644
--- a/src/coordinateoperation.cpp
+++ b/src/coordinateoperation.cpp
@@ -149,6 +149,8 @@ static std::set<std::string> buildSetEquivalentParameters() {
{"latitude_of_point_2", "Latitude_Of_2nd_Point", nullptr},
{"longitude_of_point_2", "Longitude_Of_2nd_Point", nullptr},
+ {"satellite_height", "height", nullptr},
+
{EPSG_NAME_PARAMETER_FALSE_EASTING,
EPSG_NAME_PARAMETER_EASTING_FALSE_ORIGIN,
EPSG_NAME_PARAMETER_EASTING_PROJECTION_CENTRE, nullptr},
@@ -160,7 +162,8 @@ static std::set<std::string> buildSetEquivalentParameters() {
{WKT1_LATITUDE_OF_ORIGIN, WKT1_LATITUDE_OF_CENTER,
EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN,
EPSG_NAME_PARAMETER_LATITUDE_FALSE_ORIGIN,
- EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE, nullptr},
+ EPSG_NAME_PARAMETER_LATITUDE_PROJECTION_CENTRE, "Central_Parallel",
+ nullptr},
{WKT1_CENTRAL_MERIDIAN, WKT1_LONGITUDE_OF_CENTER,
EPSG_NAME_PARAMETER_LONGITUDE_OF_NATURAL_ORIGIN,
@@ -1898,6 +1901,58 @@ ConversionNNPtr Conversion::shallowClone() const {
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+ConversionNNPtr
+Conversion::alterParametersLinearUnit(const common::UnitOfMeasure &unit,
+ bool convertToNewUnit) const {
+
+ std::vector<GeneralParameterValueNNPtr> newValues;
+ bool changesDone = false;
+ for (const auto &genOpParamvalue : parameterValues()) {
+ bool updated = false;
+ auto opParamvalue = dynamic_cast<const OperationParameterValue *>(
+ genOpParamvalue.get());
+ if (opParamvalue) {
+ const auto &paramValue = opParamvalue->parameterValue();
+ if (paramValue->type() == ParameterValue::Type::MEASURE) {
+ const auto &measure = paramValue->value();
+ if (measure.unit().type() ==
+ common::UnitOfMeasure::Type::LINEAR) {
+ if (!measure.unit()._isEquivalentTo(
+ unit, util::IComparable::Criterion::EQUIVALENT)) {
+ const double newValue =
+ convertToNewUnit ? measure.convertToUnit(unit)
+ : measure.value();
+ newValues.emplace_back(OperationParameterValue::create(
+ opParamvalue->parameter(),
+ ParameterValue::create(
+ common::Measure(newValue, unit))));
+ updated = true;
+ }
+ }
+ }
+ }
+ if (updated) {
+ changesDone = true;
+ } else {
+ newValues.emplace_back(genOpParamvalue);
+ }
+ }
+ if (changesDone) {
+ auto conv = create(util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY, "unknown"),
+ method(), newValues);
+ conv->setCRSs(this, false);
+ return conv;
+ } else {
+ return NN_NO_CHECK(
+ util::nn_dynamic_pointer_cast<Conversion>(shared_from_this()));
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Instanciate a Conversion from a vector of GeneralParameterValue.
*
* @param properties See \ref general_properties. At minimum the name should be
@@ -5471,6 +5526,12 @@ Transformation::~Transformation() = default;
// ---------------------------------------------------------------------------
+Transformation::Transformation(const Transformation &other)
+ : CoordinateOperation(other), SingleOperation(other),
+ d(internal::make_unique<Private>(*other.d)) {}
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the source crs::CRS of the transformation.
*
* @return the source CRS.
@@ -5492,6 +5553,17 @@ const crs::CRSNNPtr &Transformation::targetCRS() PROJ_CONST_DEFN {
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+TransformationNNPtr Transformation::shallowClone() const {
+ auto conv = Transformation::nn_make_shared<Transformation>(*this);
+ conv->assignSelf(conv);
+ conv->setCRSs(this, false);
+ return conv;
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
/** \brief Return the TOWGS84 parameters of the transformation.
*
* If this transformation uses Coordinate Frame Rotation, Position Vector
@@ -7595,6 +7667,8 @@ void Transformation::_exportToPROJString(
"Transformation cannot be exported as a PROJ.4 string");
}
+ formatter->setCoordinateOperationOptimizations(true);
+
bool positionVectorConvention = true;
bool sevenParamsTransform = false;
bool threeParamsTransform = false;
@@ -8220,6 +8294,32 @@ bool SingleOperation::exportToPROJStringGeneric(
if (isAxisOrderReversal(methodEPSGCode)) {
formatter->addStep("axisswap");
formatter->addParam("order", "2,1");
+ auto sourceCRSGeog =
+ dynamic_cast<const crs::GeographicCRS *>(sourceCRS().get());
+ auto targetCRSGeog =
+ dynamic_cast<const crs::GeographicCRS *>(targetCRS().get());
+ if (sourceCRSGeog && targetCRSGeog) {
+ const auto &unitSrc =
+ sourceCRSGeog->coordinateSystem()->axisList()[0]->unit();
+ const auto &unitDst =
+ targetCRSGeog->coordinateSystem()->axisList()[0]->unit();
+ if (!unitSrc._isEquivalentTo(
+ unitDst, util::IComparable::Criterion::EQUIVALENT)) {
+ formatter->addStep("unitconvert");
+ auto projUnit = unitSrc.exportToPROJString();
+ if (projUnit.empty()) {
+ formatter->addParam("xy_in", unitSrc.conversionToSI());
+ } else {
+ formatter->addParam("xy_in", projUnit);
+ }
+ projUnit = unitDst.exportToPROJString();
+ if (projUnit.empty()) {
+ formatter->addParam("xy_out", unitDst.conversionToSI());
+ } else {
+ formatter->addParam("xy_out", projUnit);
+ }
+ }
+ }
return true;
}
@@ -9228,6 +9328,7 @@ struct FilterAndSort {
// Precompute a number of parameters for each operation that will be
// useful for the sorting.
std::map<CoordinateOperation *, PrecomputedOpCharacteristics> map;
+ const auto gridAvailabilityUse = context->getGridAvailabilityUse();
for (const auto &op : res) {
bool dummy = false;
auto extentOp = getExtent(op, true, dummy);
@@ -9260,14 +9361,20 @@ struct FilterAndSort {
bool gridsAvailable = true;
bool gridsKnown = true;
if (context->getAuthorityFactory() &&
- context->getGridAvailabilityUse() ==
- CoordinateOperationContext::GridAvailabilityUse::
- USE_FOR_SORTING) {
+ (gridAvailabilityUse ==
+ CoordinateOperationContext::GridAvailabilityUse::
+ USE_FOR_SORTING ||
+ gridAvailabilityUse ==
+ CoordinateOperationContext::GridAvailabilityUse::
+ IGNORE_GRID_AVAILABILITY)) {
const auto gridsNeeded = op->gridsNeeded(
context->getAuthorityFactory()->databaseContext());
for (const auto &gridDesc : gridsNeeded) {
hasGrids = true;
- if (!gridDesc.available) {
+ if (gridAvailabilityUse ==
+ CoordinateOperationContext::GridAvailabilityUse::
+ USE_FOR_SORTING &&
+ !gridDesc.available) {
gridsAvailable = false;
}
if (gridDesc.packageName.empty()) {
@@ -10130,6 +10237,72 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot(
const auto candidatesDstGeod(
findCandidateGeodCRSForDatum(authFactory, geodDst->datum()));
+ auto createTransformations = [&](const crs::CRSNNPtr &candidateSrcGeod,
+ const crs::CRSNNPtr &candidateDstGeod,
+ const CoordinateOperationNNPtr &opFirst,
+ bool isNullFirst) {
+ const auto opsSecond =
+ createOperations(candidateSrcGeod, candidateDstGeod, context);
+ const auto opsThird =
+ createOperations(candidateDstGeod, targetCRS, context);
+ assert(!opsThird.empty());
+
+ for (auto &opSecond : opsSecond) {
+ // Check that it is not a transformation synthetized by
+ // ourselves
+ if (!hasIdentifiers(opSecond)) {
+ continue;
+ }
+ // And even if it is a referenced transformation, check that
+ // it is not a trivial one
+ auto so = dynamic_cast<const SingleOperation *>(opSecond.get());
+ if (so && isAxisOrderReversal(so->method()->getEPSGCode())) {
+ continue;
+ }
+
+ std::vector<CoordinateOperationNNPtr> subOps;
+ if (isNullFirst) {
+ opSecond->setCRSs(
+ sourceCRS, NN_CHECK_ASSERT(opSecond->targetCRS()), nullptr);
+ } else {
+ subOps.emplace_back(opFirst);
+ }
+ if (isNullTransformation(opsThird[0]->nameStr())) {
+ opSecond->setCRSs(NN_CHECK_ASSERT(opSecond->sourceCRS()),
+ targetCRS, nullptr);
+ subOps.emplace_back(opSecond);
+ } else {
+ subOps.emplace_back(opSecond);
+ subOps.emplace_back(opsThird[0]);
+ }
+ res.emplace_back(ConcatenatedOperation::createComputeMetadata(
+ subOps, !allowEmptyIntersection));
+ }
+ };
+
+ // Start in priority with candidates that have exactly the same name as
+ // the sourcCRS and targetCRS. Typically for the case of init=IGNF:XXXX
+ for (const auto &candidateSrcGeod : candidatesSrcGeod) {
+ if (candidateSrcGeod->nameStr() == sourceCRS->nameStr()) {
+ for (const auto &candidateDstGeod : candidatesDstGeod) {
+ if (candidateDstGeod->nameStr() == targetCRS->nameStr()) {
+ const auto opsFirst =
+ createOperations(sourceCRS, candidateSrcGeod, context);
+ assert(!opsFirst.empty());
+ const bool isNullFirst =
+ isNullTransformation(opsFirst[0]->nameStr());
+ createTransformations(candidateSrcGeod, candidateDstGeod,
+ opsFirst[0], isNullFirst);
+ if (!res.empty()) {
+ return;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+
for (const auto &candidateSrcGeod : candidatesSrcGeod) {
const auto opsFirst =
createOperations(sourceCRS, candidateSrcGeod, context);
@@ -10137,44 +10310,8 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot(
const bool isNullFirst = isNullTransformation(opsFirst[0]->nameStr());
for (const auto &candidateDstGeod : candidatesDstGeod) {
- const auto opsSecond =
- createOperations(candidateSrcGeod, candidateDstGeod, context);
- const auto opsThird =
- createOperations(candidateDstGeod, targetCRS, context);
- assert(!opsThird.empty());
-
- for (auto &opSecond : opsSecond) {
- // Check that it is not a transformation synthetized by
- // ourselves
- if (!hasIdentifiers(opSecond)) {
- continue;
- }
- // And even if it is a referenced transformation, check that
- // it is not a trivial one
- auto so = dynamic_cast<const SingleOperation *>(opSecond.get());
- if (so && isAxisOrderReversal(so->method()->getEPSGCode())) {
- continue;
- }
-
- std::vector<CoordinateOperationNNPtr> subOps;
- if (isNullFirst) {
- opSecond->setCRSs(sourceCRS,
- NN_CHECK_ASSERT(opSecond->targetCRS()),
- nullptr);
- } else {
- subOps.emplace_back(opsFirst[0]);
- }
- if (isNullTransformation(opsThird[0]->nameStr())) {
- opSecond->setCRSs(NN_CHECK_ASSERT(opSecond->sourceCRS()),
- targetCRS, nullptr);
- subOps.emplace_back(opSecond);
- } else {
- subOps.emplace_back(opSecond);
- subOps.emplace_back(opsThird[0]);
- }
- res.emplace_back(ConcatenatedOperation::createComputeMetadata(
- subOps, !allowEmptyIntersection));
- }
+ createTransformations(candidateSrcGeod, candidateDstGeod,
+ opsFirst[0], isNullFirst);
}
if (!res.empty()) {
return;
@@ -10235,6 +10372,56 @@ CoordinateOperationFactory::Private::createOperations(
std::vector<CoordinateOperationNNPtr> res;
const bool allowEmptyIntersection = true;
+ const auto &sourceProj4Ext = sourceCRS->getExtensionProj4();
+ const auto &targetProj4Ext = targetCRS->getExtensionProj4();
+ if (!sourceProj4Ext.empty() || !targetProj4Ext.empty()) {
+
+ auto sourceProjExportable =
+ dynamic_cast<io::IPROJStringExportable *>(sourceCRS.get());
+ auto targetProjExportable =
+ dynamic_cast<io::IPROJStringExportable *>(targetCRS.get());
+ if (!sourceProjExportable) {
+ throw InvalidOperation("Source CRS is not PROJ exportable");
+ }
+ if (!targetProjExportable) {
+ throw InvalidOperation("Target CRS is not PROJ exportable");
+ }
+ auto projFormatter = io::PROJStringFormatter::create(
+ io::PROJStringFormatter::Convention::PROJ_4);
+ projFormatter->startInversion();
+ sourceProjExportable->_exportToPROJString(projFormatter.get());
+
+ auto geogSrc =
+ dynamic_cast<const crs::GeographicCRS *>(sourceCRS.get());
+ if (geogSrc) {
+ auto proj5Formatter = io::PROJStringFormatter::create(
+ io::PROJStringFormatter::Convention::PROJ_5);
+ geogSrc->addAngularUnitConvertAndAxisSwap(proj5Formatter.get());
+ projFormatter->ingestPROJString(proj5Formatter->toString());
+ }
+
+ projFormatter->stopInversion();
+
+ targetProjExportable->_exportToPROJString(projFormatter.get());
+
+ auto geogDst =
+ dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
+ if (geogDst) {
+ auto proj5Formatter = io::PROJStringFormatter::create(
+ io::PROJStringFormatter::Convention::PROJ_5);
+ geogDst->addAngularUnitConvertAndAxisSwap(proj5Formatter.get());
+ projFormatter->ingestPROJString(proj5Formatter->toString());
+ }
+
+ const auto PROJString = projFormatter->toString();
+ auto properties = util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()));
+ res.emplace_back(SingleOperation::createPROJBased(
+ properties, PROJString, sourceCRS, targetCRS, {}));
+ return res;
+ }
+
auto geodSrc = dynamic_cast<const crs::GeodeticCRS *>(sourceCRS.get());
auto geodDst = dynamic_cast<const crs::GeodeticCRS *>(targetCRS.get());
@@ -10291,7 +10478,9 @@ CoordinateOperationFactory::Private::createOperations(
const auto &dstDatum = geodDst->datum();
const bool dstHasDatumWithId =
dstDatum && !dstDatum->identifiers().empty();
- if (srcHasDatumWithId && dstHasDatumWithId) {
+ if (srcHasDatumWithId && dstHasDatumWithId &&
+ !srcDatum->_isEquivalentTo(
+ dstDatum.get(), util::IComparable::Criterion::EQUIVALENT)) {
createOperationsWithDatumPivot(res, sourceCRS, targetCRS,
geodSrc, geodDst, context);
doFilterAndCheckPerfectOp = !res.empty();
@@ -10417,11 +10606,10 @@ CoordinateOperationFactory::Private::createOperations(
dynamic_cast<const crs::GeographicCRS *>(hubSrc.get());
auto geogCRSOfBaseOfBoundSrc =
boundSrc->baseCRS()->extractGeographicCRS();
- if (hubSrcGeog &&
+ if (hubSrcGeog && geogCRSOfBaseOfBoundSrc &&
(hubSrcGeog->_isEquivalentTo(
geogDst, util::IComparable::Criterion::EQUIVALENT) ||
- hubSrcGeog->is2DPartOf3D(NN_NO_CHECK(geogDst))) &&
- geogCRSOfBaseOfBoundSrc) {
+ hubSrcGeog->is2DPartOf3D(NN_NO_CHECK(geogDst)))) {
if (boundSrc->baseCRS() == geogCRSOfBaseOfBoundSrc) {
// Optimization to avoid creating a useless concatenated
// operation
@@ -10445,6 +10633,86 @@ CoordinateOperationFactory::Private::createOperations(
return res;
}
}
+ // If the datum are equivalent, this is also fine
+ } else if (geogCRSOfBaseOfBoundSrc && hubSrcGeog->datum() &&
+ geogDst->datum() &&
+ hubSrcGeog->datum()->_isEquivalentTo(
+ geogDst->datum().get(),
+ util::IComparable::Criterion::EQUIVALENT)) {
+ auto opsFirst =
+ createOperations(boundSrc->baseCRS(),
+ NN_NO_CHECK(geogCRSOfBaseOfBoundSrc), context);
+ auto opsLast = createOperations(hubSrc, targetCRS, context);
+ if (!opsFirst.empty() && !opsLast.empty()) {
+ for (const auto &opFirst : opsFirst) {
+ for (const auto &opLast : opsLast) {
+ try {
+ res.emplace_back(
+ ConcatenatedOperation::createComputeMetadata(
+ {opFirst, boundSrc->transformation(),
+ opLast},
+ !allowEmptyIntersection));
+ } catch (const InvalidOperationEmptyIntersection &) {
+ }
+ }
+ }
+ if (!res.empty()) {
+ return res;
+ }
+ }
+ // Consider WGS 84 and NAD83 as equivalent in that context if the
+ // geogCRSOfBaseOfBoundSrc ellipsoid is Clarke66 (for NAD27)
+ // Case of "+proj=latlong +ellps=clrk66
+ // +nadgrids=ntv1_can.dat,conus"
+ // to "+proj=latlong +datum=NAD83"
+ } else if (geogCRSOfBaseOfBoundSrc && hubSrcGeog->datum() &&
+ geogDst->datum() &&
+ geogCRSOfBaseOfBoundSrc->ellipsoid()->_isEquivalentTo(
+ datum::Ellipsoid::CLARKE_1866.get(),
+ util::IComparable::Criterion::EQUIVALENT) &&
+ hubSrcGeog->datum()->_isEquivalentTo(
+ datum::GeodeticReferenceFrame::EPSG_6326.get(),
+ util::IComparable::Criterion::EQUIVALENT) &&
+ geogDst->datum()->_isEquivalentTo(
+ datum::GeodeticReferenceFrame::EPSG_6269.get(),
+ util::IComparable::Criterion::EQUIVALENT)) {
+ auto nnGeogCRSOfBaseOfBoundSrc =
+ NN_NO_CHECK(geogCRSOfBaseOfBoundSrc);
+ if (boundSrc->baseCRS()->_isEquivalentTo(
+ nnGeogCRSOfBaseOfBoundSrc.get(),
+ util::IComparable::Criterion::EQUIVALENT)) {
+ auto transf = boundSrc->transformation()->shallowClone();
+ transf->setProperties(util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ buildTransfName(boundSrc->baseCRS()->nameStr(),
+ targetCRS->nameStr())));
+ transf->setCRSs(boundSrc->baseCRS(), targetCRS, nullptr);
+ res.emplace_back(transf);
+ return res;
+ } else {
+ auto opsFirst = createOperations(
+ boundSrc->baseCRS(), nnGeogCRSOfBaseOfBoundSrc, context);
+ auto transf = boundSrc->transformation()->shallowClone();
+ transf->setProperties(util::PropertyMap().set(
+ common::IdentifiedObject::NAME_KEY,
+ buildTransfName(nnGeogCRSOfBaseOfBoundSrc->nameStr(),
+ targetCRS->nameStr())));
+ transf->setCRSs(nnGeogCRSOfBaseOfBoundSrc, targetCRS, nullptr);
+ if (!opsFirst.empty()) {
+ for (const auto &opFirst : opsFirst) {
+ try {
+ res.emplace_back(
+ ConcatenatedOperation::createComputeMetadata(
+ {opFirst, transf},
+ !allowEmptyIntersection));
+ } catch (const InvalidOperationEmptyIntersection &) {
+ }
+ }
+ if (!res.empty()) {
+ return res;
+ }
+ }
+ }
}
if (hubSrcGeog &&
diff --git a/src/coordinatesystem.cpp b/src/coordinatesystem.cpp
index f8d2d2b3..f1220878 100644
--- a/src/coordinatesystem.cpp
+++ b/src/coordinatesystem.cpp
@@ -416,6 +416,16 @@ bool CoordinateSystemAxis::_isEquivalentTo(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+CoordinateSystemAxisNNPtr
+CoordinateSystemAxis::alterUnit(const common::UnitOfMeasure &newUnit) const {
+ return create(util::PropertyMap().set(IdentifiedObject::NAME_KEY, name()),
+ abbreviation(), direction(), newUnit, meridian());
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
struct CoordinateSystem::Private {
std::vector<CoordinateSystemAxisNNPtr> axisList{};
@@ -738,6 +748,43 @@ EllipsoidalCS::AxisOrder EllipsoidalCS::axisOrder() const {
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+EllipsoidalCSNNPtr EllipsoidalCS::alterAngularUnit(
+ const common::UnitOfMeasure &angularUnit) const {
+ const auto &l_axisList = CoordinateSystem::getPrivate()->axisList;
+ if (l_axisList.size() == 2) {
+ return EllipsoidalCS::create(util::PropertyMap(),
+ l_axisList[0]->alterUnit(angularUnit),
+ l_axisList[1]->alterUnit(angularUnit));
+ } else {
+ assert(l_axisList.size() == 3);
+ return EllipsoidalCS::create(
+ util::PropertyMap(), l_axisList[0]->alterUnit(angularUnit),
+ l_axisList[1]->alterUnit(angularUnit), l_axisList[2]);
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+EllipsoidalCSNNPtr
+EllipsoidalCS::alterLinearUnit(const common::UnitOfMeasure &linearUnit) const {
+ const auto &l_axisList = CoordinateSystem::getPrivate()->axisList;
+ if (l_axisList.size() == 2) {
+ return EllipsoidalCS::create(util::PropertyMap(), l_axisList[0],
+ l_axisList[1]);
+ } else {
+ assert(l_axisList.size() == 3);
+ return EllipsoidalCS::create(util::PropertyMap(), l_axisList[0],
+ l_axisList[1],
+ l_axisList[2]->alterUnit(linearUnit));
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
VerticalCS::~VerticalCS() = default;
//! @endcond
@@ -788,6 +835,16 @@ VerticalCS::createGravityRelatedHeight(const common::UnitOfMeasure &unit) {
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+VerticalCSNNPtr VerticalCS::alterUnit(const common::UnitOfMeasure &unit) const {
+ const auto &l_axisList = CoordinateSystem::getPrivate()->axisList;
+ return VerticalCS::nn_make_shared<VerticalCS>(
+ l_axisList[0]->alterUnit(unit));
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
CartesianCS::~CartesianCS() = default;
//! @endcond
@@ -863,6 +920,27 @@ CartesianCS::createEastingNorthing(const common::UnitOfMeasure &unit) {
// ---------------------------------------------------------------------------
+/** \brief Instanciate a CartesianCS with a Northing (first) and Easting
+ * (second) axis.
+ *
+ * @param unit Linear unit of the axes.
+ * @return a new CartesianCS.
+ */
+CartesianCSNNPtr
+CartesianCS::createNorthingEasting(const common::UnitOfMeasure &unit) {
+ return create(util::PropertyMap(),
+ CoordinateSystemAxis::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ AxisName::Northing),
+ AxisAbbreviation::N, AxisDirection::NORTH, unit),
+ CoordinateSystemAxis::create(
+ util::PropertyMap().set(IdentifiedObject::NAME_KEY,
+ AxisName::Easting),
+ AxisAbbreviation::E, AxisDirection::EAST, unit));
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Instanciate a CartesianCS with the three geocentric axes.
*
* @param unit Liinear unit of the axes.
@@ -888,6 +966,25 @@ CartesianCS::createGeocentric(const common::UnitOfMeasure &unit) {
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+CartesianCSNNPtr
+CartesianCS::alterUnit(const common::UnitOfMeasure &unit) const {
+ const auto &l_axisList = CoordinateSystem::getPrivate()->axisList;
+ if (l_axisList.size() == 2) {
+ return CartesianCS::create(util::PropertyMap(),
+ l_axisList[0]->alterUnit(unit),
+ l_axisList[1]->alterUnit(unit));
+ } else {
+ assert(l_axisList.size() == 3);
+ return CartesianCS::create(
+ util::PropertyMap(), l_axisList[0]->alterUnit(unit),
+ l_axisList[1]->alterUnit(unit), l_axisList[2]->alterUnit(unit));
+ }
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
OrdinalCS::~OrdinalCS() = default;
//! @endcond
diff --git a/src/crs.cpp b/src/crs.cpp
index a204a037..31682644 100644
--- a/src/crs.cpp
+++ b/src/crs.cpp
@@ -45,6 +45,7 @@
#include "proj/internal/internal.hpp"
#include "proj/internal/io_internal.hpp"
+#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
@@ -88,6 +89,20 @@ namespace crs {
struct CRS::Private {
BoundCRSPtr canonicalBoundCRS_{};
std::string extensionProj4_{};
+ bool implicitCS_ = false;
+
+ void setImplicitCS(const util::PropertyMap &properties) {
+ auto oIter = properties.find("IMPLICIT_CS");
+ if (oIter != properties.end()) {
+ if (auto genVal = util::nn_dynamic_pointer_cast<util::BoxedValue>(
+ oIter->second)) {
+ if (genVal->type() == util::BoxedValue::Type::BOOLEAN &&
+ genVal->booleanValue()) {
+ implicitCS_ = true;
+ }
+ }
+ }
+ }
};
//! @endcond
@@ -170,6 +185,14 @@ const GeodeticCRS *CRS::extractGeodeticCRSRaw() const {
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+const std::string &CRS::getExtensionProj4() const noexcept {
+ return d->extensionProj4_;
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the GeographicCRS of the CRS.
*
* Returns the GeographicCRS contained in a CRS. This works currently with
@@ -189,6 +212,97 @@ GeographicCRSPtr CRS::extractGeographicCRS() const {
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+static util::PropertyMap createPropertyMapName(const std::string &name) {
+ return util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, name);
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+CRSNNPtr CRS::alterGeodeticCRS(const GeodeticCRSNNPtr &newGeodCRS) const {
+ auto geodCRS = dynamic_cast<const GeodeticCRS *>(this);
+ if (geodCRS) {
+ return newGeodCRS;
+ }
+
+ auto projCRS = dynamic_cast<const ProjectedCRS *>(this);
+ if (projCRS) {
+ return ProjectedCRS::create(
+ createPropertyMapName(nameStr()), newGeodCRS,
+ projCRS->derivingConversionRef(), projCRS->coordinateSystem());
+ }
+
+ auto compoundCRS = dynamic_cast<const CompoundCRS *>(this);
+ if (compoundCRS) {
+ std::vector<CRSNNPtr> components;
+ for (const auto &subCrs : compoundCRS->componentReferenceSystems()) {
+ components.emplace_back(subCrs->alterGeodeticCRS(newGeodCRS));
+ }
+ return CompoundCRS::create(createPropertyMapName(nameStr()),
+ components);
+ }
+
+ return NN_NO_CHECK(
+ std::dynamic_pointer_cast<CRS>(shared_from_this().as_nullable()));
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+CRSNNPtr CRS::alterCSLinearUnit(const common::UnitOfMeasure &unit) const {
+ {
+ auto projCRS = dynamic_cast<const ProjectedCRS *>(this);
+ if (projCRS) {
+ return ProjectedCRS::create(
+ createPropertyMapName(projCRS->nameStr().c_str()),
+ projCRS->baseCRS(), projCRS->derivingConversionRef(),
+ projCRS->coordinateSystem()->alterUnit(unit));
+ }
+ }
+
+ {
+ auto geodCRS = dynamic_cast<const GeodeticCRS *>(this);
+ if (geodCRS && geodCRS->isGeocentric()) {
+ auto cs = dynamic_cast<const cs::CartesianCS *>(
+ geodCRS->coordinateSystem().get());
+ assert(cs);
+ return GeodeticCRS::create(
+ createPropertyMapName(geodCRS->nameStr().c_str()),
+ geodCRS->datum(), geodCRS->datumEnsemble(),
+ cs->alterUnit(unit));
+ }
+ }
+
+ {
+ auto geogCRS = dynamic_cast<const GeographicCRS *>(this);
+ if (geogCRS && geogCRS->coordinateSystem()->axisList().size() == 3) {
+ return GeographicCRS::create(
+ createPropertyMapName(geogCRS->nameStr().c_str()),
+ geogCRS->datum(), geogCRS->datumEnsemble(),
+ geogCRS->coordinateSystem()->alterLinearUnit(unit));
+ }
+ }
+
+ {
+ auto vertCRS = dynamic_cast<const VerticalCRS *>(this);
+ if (vertCRS) {
+ return VerticalCRS::create(
+ createPropertyMapName(vertCRS->nameStr().c_str()),
+ vertCRS->datum(), vertCRS->datumEnsemble(),
+ vertCRS->coordinateSystem()->alterUnit(unit));
+ }
+ }
+
+ return NN_NO_CHECK(
+ std::dynamic_pointer_cast<CRS>(shared_from_this().as_nullable()));
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the VerticalCRS of the CRS.
*
* Returns the VerticalCRS contained in a CRS. This works currently with
@@ -383,6 +497,19 @@ CRSNNPtr CRS::shallowClone() const { return _shallowClone(); }
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+
+CRSNNPtr CRS::alterName(const std::string &newName) const {
+ auto crs = shallowClone();
+ crs->setProperties(
+ util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, newName));
+ return crs;
+}
+
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Identify the CRS with reference CRSs.
*
* The candidate CRSs are either hard-coded, or looked in the database when
@@ -748,6 +875,7 @@ GeodeticCRS::create(const util::PropertyMap &properties,
crs->setProperties(properties);
properties.getStringValue("EXTENSION_PROJ4",
crs->CRS::getPrivate()->extensionProj4_);
+
return crs;
}
@@ -853,7 +981,16 @@ void GeodeticCRS::_exportToWKT(io::WKTFormatter *formatter) const {
if (!isWKT2) {
unit._exportToWKT(formatter);
}
+
+ const auto oldAxisOutputRule = formatter->outputAxis();
+ if (oldAxisOutputRule ==
+ io::WKTFormatter::OutputAxisRule::WKT1_GDAL_EPSG_STYLE &&
+ isGeocentric()) {
+ formatter->setOutputAxis(io::WKTFormatter::OutputAxisRule::YES);
+ }
cs->_exportToWKT(formatter);
+ formatter->setOutputAxis(oldAxisOutputRule);
+
ObjectUsage::baseExportToWKT(formatter);
if (!isWKT2 && !formatter->useESRIDialect()) {
@@ -1062,6 +1199,12 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
std::list<Pair> res;
const auto &thisName(nameStr());
+ const bool l_implicitCS = CRS::getPrivate()->implicitCS_;
+ const auto crsCriterion =
+ l_implicitCS
+ ? util::IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS
+ : util::IComparable::Criterion::EQUIVALENT;
+
const GeographicCRSNNPtr candidatesCRS[] = {GeographicCRS::EPSG_4326,
GeographicCRS::EPSG_4267,
GeographicCRS::EPSG_4269};
@@ -1069,8 +1212,7 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
const bool nameEquivalent = metadata::Identifier::isEquivalentName(
thisName.c_str(), crs->nameStr().c_str());
const bool nameEqual = thisName == crs->nameStr();
- const bool isEq = _isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT);
+ const bool isEq = _isEquivalentTo(crs.get(), crsCriterion);
if (nameEquivalent && isEq && (!authorityFactory || nameEqual)) {
res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
nameEqual ? 100 : 90);
@@ -1105,15 +1247,13 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
const auto &thisDatum(datum());
auto searchByDatum = [this, &authorityFactory, &res, &thisDatum,
- &geodetic_crs_type]() {
+ &geodetic_crs_type, crsCriterion]() {
for (const auto &id : thisDatum->identifiers()) {
try {
auto tempRes = authorityFactory->createGeodeticCRSFromDatum(
*id->codeSpace(), id->code(), geodetic_crs_type);
for (const auto &crs : tempRes) {
- if (_isEquivalentTo(
- crs.get(),
- util::IComparable::Criterion::EQUIVALENT)) {
+ if (_isEquivalentTo(crs.get(), crsCriterion)) {
res.emplace_back(crs, 70);
}
}
@@ -1124,7 +1264,8 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
const auto &thisEllipsoid(ellipsoid());
auto searchByEllipsoid = [this, &authorityFactory, &res, &thisDatum,
- &thisEllipsoid, &geodetic_crs_type]() {
+ &thisEllipsoid, &geodetic_crs_type,
+ l_implicitCS]() {
const auto ellipsoids =
thisEllipsoid->identifiers().empty()
? authorityFactory->createEllipsoidFromExisting(
@@ -1146,11 +1287,11 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
crsDatum->primeMeridian()->_isEquivalentTo(
thisDatum->primeMeridian().get(),
util::IComparable::Criterion::EQUIVALENT) &&
- coordinateSystem()->_isEquivalentTo(
- crs->coordinateSystem().get(),
- util::IComparable::Criterion::EQUIVALENT)
-
- ) {
+ (!l_implicitCS ||
+ coordinateSystem()->_isEquivalentTo(
+ crs->coordinateSystem().get(),
+ util::IComparable::Criterion::
+ EQUIVALENT))) {
res.emplace_back(crs, 60);
}
}
@@ -1181,14 +1322,14 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
authorityFactory->databaseContext(),
*id->codeSpace())
->createGeodeticCRS(id->code());
- bool match = _isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT);
+ bool match = _isEquivalentTo(crs.get(), crsCriterion);
res.emplace_back(crs, match ? 100 : 25);
return res;
} catch (const std::exception &) {
}
}
} else {
+ bool gotAbove25Pct = false;
for (int ipass = 0; ipass < 2; ipass++) {
const bool approximateMatch = ipass == 1;
auto objects = authorityFactory->createObjectsFromName(
@@ -1198,9 +1339,7 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
auto crs = util::nn_dynamic_pointer_cast<GeodeticCRS>(obj);
assert(crs);
auto crsNN = NN_NO_CHECK(crs);
- if (_isEquivalentTo(
- crs.get(),
- util::IComparable::Criterion::EQUIVALENT)) {
+ if (_isEquivalentTo(crs.get(), crsCriterion)) {
if (crs->nameStr() == thisName) {
res.clear();
res.emplace_back(crsNN, 100);
@@ -1210,6 +1349,7 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
metadata::Identifier::isEquivalentName(
thisName.c_str(), crs->nameStr().c_str());
res.emplace_back(crsNN, eqName ? 90 : 70);
+ gotAbove25Pct = true;
} else {
res.emplace_back(crsNN, 25);
}
@@ -1218,7 +1358,7 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
break;
}
}
- if (res.empty() && thisDatum) {
+ if (!gotAbove25Pct && thisDatum) {
if (!thisDatum->identifiers().empty()) {
searchByDatum();
} else {
@@ -1446,6 +1586,7 @@ GeographicCRS::create(const util::PropertyMap &properties,
crs->setProperties(properties);
properties.getStringValue("EXTENSION_PROJ4",
crs->CRS::getPrivate()->extensionProj4_);
+ crs->CRS::getPrivate()->setImplicitCS(properties);
return crs;
}
@@ -2274,6 +2415,63 @@ const cs::CartesianCSNNPtr &ProjectedCRS::coordinateSystem() PROJ_CONST_DEFN {
void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
+ const auto &l_identifiers = identifiers();
+ // Try to perfectly round-trip ESRI projectedCRS if the current object
+ // perfectly matches the database definition
+ const auto &dbContext = formatter->databaseContext();
+
+ auto l_name = nameStr();
+ std::string l_alias;
+ if (formatter->useESRIDialect() && dbContext) {
+ l_alias = dbContext->getAliasFromOfficialName(l_name, "projected_crs",
+ "ESRI");
+ }
+
+ if (!isWKT2 && formatter->useESRIDialect() && !l_identifiers.empty() &&
+ *(l_identifiers[0]->codeSpace()) == "ESRI" && dbContext) {
+ try {
+ const auto definition = dbContext->getTextDefinition(
+ "projected_crs", "ESRI", l_identifiers[0]->code());
+ if (starts_with(definition, "PROJCS")) {
+ auto crsFromFromDef = io::WKTParser()
+ .attachDatabaseContext(dbContext)
+ .createFromWKT(definition);
+ if (_isEquivalentTo(
+ dynamic_cast<IComparable *>(crsFromFromDef.get()),
+ util::IComparable::Criterion::EQUIVALENT)) {
+ formatter->ingestWKTNode(
+ io::WKTNode::createFrom(definition));
+ return;
+ }
+ }
+ } catch (const std::exception &) {
+ }
+ } else if (!isWKT2 && formatter->useESRIDialect() && !l_alias.empty()) {
+ try {
+ auto res =
+ io::AuthorityFactory::create(NN_NO_CHECK(dbContext), "ESRI")
+ ->createObjectsFromName(
+ l_alias,
+ {io::AuthorityFactory::ObjectType::PROJECTED_CRS},
+ false);
+ if (res.size() == 1) {
+ const auto definition = dbContext->getTextDefinition(
+ "projected_crs", "ESRI",
+ res.front()->identifiers()[0]->code());
+ if (starts_with(definition, "PROJCS")) {
+ if (_isEquivalentTo(
+ dynamic_cast<IComparable *>(res.front().get()),
+ util::IComparable::Criterion::EQUIVALENT)) {
+ formatter->ingestWKTNode(
+ io::WKTNode::createFrom(definition));
+ return;
+ }
+ }
+ }
+ } catch (const std::exception &) {
+ }
+ }
+
const auto &l_coordinateSystem = d->coordinateSystem();
const auto &axisList = l_coordinateSystem->axisList();
@@ -2292,7 +2490,7 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
if (!isWKT2 && !formatter->useESRIDialect() &&
starts_with(nameStr(), "Popular Visualisation CRS / Mercator")) {
- formatter->startNode(io::WKTConstants::PROJCS, !identifiers().empty());
+ formatter->startNode(io::WKTConstants::PROJCS, !l_identifiers.empty());
formatter->addQuotedString(nameStr());
formatter->setTOWGS84Parameters({0, 0, 0, 0, 0, 0, 0});
baseCRS()->_exportToWKT(formatter);
@@ -2332,21 +2530,13 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
formatter->startNode(isWKT2 ? io::WKTConstants::PROJCRS
: io::WKTConstants::PROJCS,
- !identifiers().empty());
- auto l_name = nameStr();
+ !l_identifiers.empty());
+
if (formatter->useESRIDialect()) {
- bool aliasFound = false;
- const auto &dbContext = formatter->databaseContext();
- if (dbContext) {
- auto l_alias = dbContext->getAliasFromOfficialName(
- l_name, "projected_crs", "ESRI");
- if (!l_alias.empty()) {
- l_name = l_alias;
- aliasFound = true;
- }
- }
- if (!aliasFound) {
+ if (l_alias.empty()) {
l_name = io::WKTFormatter::morphNameToESRI(l_name);
+ } else {
+ l_name = l_alias;
}
}
if (!isWKT2 && !formatter->useESRIDialect() && isDeprecated()) {
@@ -2461,6 +2651,7 @@ ProjectedCRS::create(const util::PropertyMap &properties,
crs->setDerivingConversionCRS();
properties.getStringValue("EXTENSION_PROJ4",
crs->CRS::getPrivate()->extensionProj4_);
+ crs->CRS::getPrivate()->setImplicitCS(properties);
return crs;
}
@@ -2477,6 +2668,19 @@ bool ProjectedCRS::_isEquivalentTo(
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
+ProjectedCRSNNPtr
+ProjectedCRS::alterParametersLinearUnit(const common::UnitOfMeasure &unit,
+ bool convertToNewUnit) const {
+ return create(createPropertyMapName(nameStr()), baseCRS(),
+ derivingConversionRef()->alterParametersLinearUnit(
+ unit, convertToNewUnit),
+ coordinateSystem());
+}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter,
bool axisSpecFound) const {
const auto &axisList = d->coordinateSystem()->axisList();
@@ -2702,7 +2906,8 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
*id->codeSpace())
->createProjectedCRS(id->code());
bool match = _isEquivalentTo(
- crs.get(), util::IComparable::Criterion::EQUIVALENT);
+ crs.get(), util::IComparable::Criterion::
+ EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS);
res.emplace_back(crs, match ? 100 : 25);
return res;
} catch (const std::exception &) {
@@ -2723,13 +2928,27 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
foundEquivalentName |= eqName;
if (_isEquivalentTo(
crs.get(),
- util::IComparable::Criterion::EQUIVALENT)) {
+ util::IComparable::Criterion::
+ EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS)) {
if (crs->nameStr() == thisName) {
res.clear();
res.emplace_back(crsNN, 100);
return res;
}
res.emplace_back(crsNN, eqName ? 90 : 70);
+ } else if (crs->nameStr() == thisName &&
+ CRS::getPrivate()->implicitCS_ &&
+ l_baseCRS->_isEquivalentTo(
+ crs->baseCRS().get(),
+ util::IComparable::Criterion::
+ EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS) &&
+ derivingConversionRef()->_isEquivalentTo(
+ crs->derivingConversionRef().get(),
+ util::IComparable::Criterion::EQUIVALENT) &&
+ objects.size() == 1) {
+ res.clear();
+ res.emplace_back(crsNN, 100);
+ return res;
} else {
res.emplace_back(crsNN, 25);
}
@@ -2791,7 +3010,8 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
}
if (_isEquivalentTo(crs.get(),
- util::IComparable::Criterion::EQUIVALENT)) {
+ util::IComparable::Criterion::
+ EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS)) {
res.emplace_back(crs, unsignificantName ? 90 : 70);
} else if (ellipsoid->_isEquivalentTo(
crs->baseCRS()->ellipsoid().get(),
@@ -3529,9 +3749,26 @@ BoundCRS::_identify(const io::AuthorityFactoryPtr &authorityFactory) const {
}
} catch (const std::exception &) {
}
+ bool foundOp = false;
for (const auto &op : ops) {
std::string opTransfPROJString;
bool opTransfPROJStringValid = false;
+ if (op->nameStr().find("Null geographic") == 0) {
+ if (isTOWGS84Compatible()) {
+ auto params =
+ transformation()->getTOWGS84Parameters();
+ if (params ==
+ std::vector<double>{0, 0, 0, 0, 0, 0, 0}) {
+ res.emplace_back(create(candidateBaseCRS,
+ d->hubCRS_,
+ transformation()),
+ pair.second);
+ foundOp = true;
+ break;
+ }
+ }
+ continue;
+ }
try {
opTransfPROJString = op->exportToPROJString(
io::PROJStringFormatter::create().get());
@@ -3548,9 +3785,15 @@ BoundCRS::_identify(const io::AuthorityFactoryPtr &authorityFactory) const {
NN_NO_CHECK(util::nn_dynamic_pointer_cast<
operation::Transformation>(op))),
pair.second);
+ foundOp = true;
break;
}
}
+ if (!foundOp) {
+ res.emplace_back(
+ create(candidateBaseCRS, d->hubCRS_, transformation()),
+ std::min(70, pair.second));
+ }
}
}
}
diff --git a/src/cs2cs.c b/src/cs2cs.c
deleted file mode 100644
index d9e37528..00000000
--- a/src/cs2cs.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/******************************************************************************
- * Project: PROJ.4
- * Purpose: Mainline program sort of like ``proj'' for converting between
- * two coordinate systems.
- * Author: Frank Warmerdam, warmerda@home.com
- *
- ******************************************************************************
- * Copyright (c) 2000, Frank Warmerdam
- *
- * 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.
- *****************************************************************************/
-
-#include <ctype.h>
-#include <locale.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "proj.h"
-#include "projects.h"
-#include "emess.h"
-
-#define MAX_LINE 1000
-#define MAX_PARGS 100
-
-static projPJ fromProj, toProj;
-
-static int
-reversein = 0, /* != 0 reverse input arguments */
-reverseout = 0, /* != 0 reverse output arguments */
-echoin = 0, /* echo input data to output line */
-tag = '#'; /* beginning of line tag character */
- static char
-*oform = (char *)0, /* output format for x-y or decimal degrees */
- oform_buffer[16], /* buffer for oform when using -d */
-*oterr = "*\t*", /* output line for unprojectable input */
-*usage =
-"%s\nusage: %s [ -dDeEfIlrstvwW [args] ] [ +opts[=arg] ]\n"
-" [+to [+opts[=arg] [ files ]\n";
-
-static double (*informat)(const char *,
- char **); /* input data deformatter function */
-
-
-/************************************************************************/
-/* process() */
-/* */
-/* File processing function. */
-/************************************************************************/
-static void process(FILE *fid)
-
-{
- char line[MAX_LINE+3], *s, pline[40];
- projUV data;
-
- for (;;) {
- double z;
-
- ++emess_dat.File_line;
- if (!(s = fgets(line, MAX_LINE, fid)))
- break;
- if (!strchr(s, '\n')) { /* overlong line */
- int c;
- (void)strcat(s, "\n");
- /* gobble up to newline */
- while ((c = fgetc(fid)) != EOF && c != '\n') ;
- }
- if (*s == tag) {
- fputs(line, stdout);
- continue;
- }
-
- if (reversein) {
- data.v = (*informat)(s, &s);
- data.u = (*informat)(s, &s);
- } else {
- data.u = (*informat)(s, &s);
- data.v = (*informat)(s, &s);
- }
-
- z = strtod( s, &s );
-
- if (data.v == HUGE_VAL)
- data.u = HUGE_VAL;
-
- if (!*s && (s > line)) --s; /* assumed we gobbled \n */
-
- if ( echoin) {
- char t;
- t = *s;
- *s = '\0';
- (void)fputs(line, stdout);
- *s = t;
- putchar('\t');
- }
-
- if (data.u != HUGE_VAL) {
- if( pj_transform( fromProj, toProj, 1, 0,
- &(data.u), &(data.v), &z ) != 0 )
- {
- data.u = HUGE_VAL;
- data.v = HUGE_VAL;
- emess(-3,"pj_transform(): %s", pj_strerrno(pj_errno));
- }
- }
-
- if (data.u == HUGE_VAL) /* error output */
- fputs(oterr, stdout);
-
- else if (pj_is_latlong(toProj) && !oform) { /*ascii DMS output */
- if (reverseout) {
- fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
- putchar('\t');
- fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
- } else {
- fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
- putchar('\t');
- fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
- }
-
- } else { /* x-y or decimal degree ascii output */
- if ( proj_angular_output(toProj, PJ_FWD) ) {
- data.v *= RAD_TO_DEG;
- data.u *= RAD_TO_DEG;
- }
- if (reverseout) {
- printf(oform,data.v); putchar('\t');
- printf(oform,data.u);
- } else {
- printf(oform,data.u); putchar('\t');
- printf(oform,data.v);
- }
- }
-
- putchar(' ');
- if( oform != NULL )
- printf( oform, z );
- else
- printf( "%.3f", z );
- if( s )
- printf( "%s", s );
- else
- printf( "\n" );
- }
-}
-
-/************************************************************************/
-/* main() */
-/************************************************************************/
-
-int main(int argc, char **argv)
-{
- char *arg, **eargv = argv, *from_argv[MAX_PARGS], *to_argv[MAX_PARGS];
- FILE *fid;
- int from_argc=0, to_argc=0, eargc = 0, mon = 0;
- int have_to_flag = 0, inverse = 0, i;
- int use_env_locale = 0;
-
- /* This is just to check that pj_init() is locale-safe */
- /* Used by nad/testvarious */
- if( getenv("PROJ_USE_ENV_LOCALE") != NULL )
- use_env_locale = 1;
-
- if ((emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) != NULL)
- ++emess_dat.Prog_name;
- else emess_dat.Prog_name = *argv;
- inverse = ! strncmp(emess_dat.Prog_name, "inv", 3);
- if (argc <= 1 ) {
- (void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name);
- exit (0);
- }
- /* process run line arguments */
- while (--argc > 0) { /* collect run line arguments */
- if(**++argv == '-') for(arg = *argv;;) {
- switch(*++arg) {
- case '\0': /* position of "stdin" */
- if (arg[-1] == '-') eargv[eargc++] = "-";
- break;
- case 'v': /* monitor dump of initialization */
- mon = 1;
- continue;
- case 'I': /* alt. method to spec inverse */
- inverse = 1;
- continue;
- case 'E': /* echo ascii input to ascii output */
- echoin = 1;
- continue;
- case 't': /* set col. one char */
- if (arg[1]) tag = *++arg;
- else emess(1,"missing -t col. 1 tag");
- continue;
- case 'l': /* list projections, ellipses or units */
- if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') {
- /* list projections */
- const struct PJ_LIST *lp;
- int do_long = arg[1] == 'P', c;
- const char *str;
-
- for (lp = proj_list_operations() ; lp->id ; ++lp) {
- (void)printf("%s : ", lp->id);
- if (do_long) /* possibly multiline description */
- (void)puts(*lp->descr);
- else { /* first line, only */
- str = *lp->descr;
- while ((c = *str++) && c != '\n')
- putchar(c);
- putchar('\n');
- }
- }
- } else if (arg[1] == '=') { /* list projection 'descr' */
- const struct PJ_LIST *lp;
-
- arg += 2;
- for (lp = proj_list_operations() ; lp->id ; ++lp)
- if (!strcmp(lp->id, arg)) {
- (void)printf("%9s : %s\n", lp->id, *lp->descr);
- break;
- }
- } else if (arg[1] == 'e') { /* list ellipses */
- const struct PJ_ELLPS *le;
-
- for (le = proj_list_ellps(); le->id ; ++le)
- (void)printf("%9s %-16s %-16s %s\n",
- le->id, le->major, le->ell, le->name);
- } else if (arg[1] == 'u') { /* list units */
- const struct PJ_UNITS *lu;
-
- for (lu = proj_list_units(); lu->id ; ++lu)
- (void)printf("%12s %-20s %s\n",
- lu->id, lu->to_meter, lu->name);
- } else if (arg[1] == 'd') { /* list datums */
- const struct PJ_DATUMS *ld;
-
- printf("__datum_id__ __ellipse___ __definition/comments______________________________\n" );
- for (ld = pj_get_datums_ref(); ld->id ; ++ld)
- {
- printf("%12s %-12s %-30s\n",
- ld->id, ld->ellipse_id, ld->defn);
- if( ld->comments != NULL && strlen(ld->comments) > 0 )
- printf( "%25s %s\n", " ", ld->comments );
- }
- } else if( arg[1] == 'm') { /* list prime meridians */
- const struct PJ_PRIME_MERIDIANS *lpm;
-
- for (lpm = proj_list_prime_meridians(); lpm->id ; ++lpm)
- (void)printf("%12s %-30s\n",
- lpm->id, lpm->defn);
- } else
- emess(1,"invalid list option: l%c",arg[1]);
- exit(0);
- /* cppcheck-suppress duplicateBreak */
- continue; /* artificial */
- case 'e': /* error line alternative */
- if (--argc <= 0)
- noargument:
- emess(1,"missing argument for -%c",*arg);
- oterr = *++argv;
- continue;
- case 'W': /* specify seconds precision */
- case 'w': /* -W for constant field width */
- {
- char c = arg[1];
- if (c != 0 && isdigit(c)) {
- set_rtodms(c - '0', *arg == 'W');
- ++arg;
- } else
- emess(1,"-W argument missing or non-digit");
- continue;
- }
- case 'f': /* alternate output format degrees or xy */
- if (--argc <= 0) goto noargument;
- oform = *++argv;
- continue;
- case 'r': /* reverse input */
- reversein = 1;
- continue;
- case 's': /* reverse output */
- reverseout = 1;
- continue;
- case 'D': /* set debug level */
- if (--argc <= 0) goto noargument;
- pj_ctx_set_debug( pj_get_default_ctx(), atoi(*++argv));
- continue;
- case 'd':
- if (--argc <= 0) goto noargument;
- sprintf(oform_buffer, "%%.%df", atoi(*++argv));
- oform = oform_buffer;
- break;
- default:
- emess(1, "invalid option: -%c",*arg);
- break;
- }
- break;
-
- } else if (strcmp(*argv,"+to") == 0 ) {
- have_to_flag = 1;
-
- } else if (**argv == '+') { /* + argument */
- if( have_to_flag )
- {
- if( to_argc < MAX_PARGS )
- to_argv[to_argc++] = *argv + 1;
- else
- emess(1,"overflowed + argument table");
- }
- else
- {
- if (from_argc < MAX_PARGS)
- from_argv[from_argc++] = *argv + 1;
- else
- emess(1,"overflowed + argument table");
- }
- } else /* assumed to be input file name(s) */
- eargv[eargc++] = *argv;
- }
- if (eargc == 0 ) /* if no specific files force sysin */
- eargv[eargc++] = "-";
-
- /*
- * If the user has requested inverse, then just reverse the
- * coordinate systems.
- */
- if( inverse )
- {
- int argcount;
-
- for( i = 0; i < MAX_PARGS; i++ )
- {
- arg = from_argv[i];
- from_argv[i] = to_argv[i];
- to_argv[i] = arg;
- }
-
- argcount = from_argc;
- from_argc = to_argc;
- to_argc = argcount;
- }
-
- if( use_env_locale )
- {
- /* Set locale from environment */
- setlocale(LC_ALL, "");
- }
-
- if( from_argc == 0 && to_argc != 0 )
- {
- /* we will generate the from proj as the latlong of the +to in a bit */
- }
- else if (!(fromProj = pj_init(from_argc, from_argv)))
- {
- printf( "Using from definition: " );
- for( i = 0; i < from_argc; i++ )
- printf( "%s ", from_argv[i] );
- printf( "\n" );
-
- emess(3,"projection initialization failure\ncause: %s",
- pj_strerrno(pj_errno));
- }
-
- if( to_argc == 0 )
- {
- if (!(toProj = pj_latlong_from_proj( fromProj )))
- {
- printf( "Using to definition: " );
- for( i = 0; i < to_argc; i++ )
- printf( "%s ", to_argv[i] );
- printf( "\n" );
-
- emess(3,"projection initialization failure\ncause: %s",
- pj_strerrno(pj_errno));
- }
- }
- else if (!(toProj = pj_init(to_argc, to_argv)))
- {
- printf( "Using to definition: " );
- for( i = 0; i < to_argc; i++ )
- printf( "%s ", to_argv[i] );
- printf( "\n" );
-
- emess(3,"projection initialization failure\ncause: %s",
- pj_strerrno(pj_errno));
- }
-
- if( from_argc == 0 && toProj != NULL)
- {
- if (!(fromProj = pj_latlong_from_proj( toProj )))
- {
- printf( "Using to definition: " );
- for( i = 0; i < to_argc; i++ )
- printf( "%s ", to_argv[i] );
- printf( "\n" );
-
- emess(3,"projection initialization failure\ncause: %s",
- pj_strerrno(pj_errno));
- }
- }
-
- if( use_env_locale )
- {
- /* Restore C locale to avoid issues in parsing/outputting numbers*/
- setlocale(LC_ALL, "C");
- }
-
- if (mon) {
- printf( "%c ---- From Coordinate System ----\n", tag );
- pj_pr_list(fromProj);
- printf( "%c ---- To Coordinate System ----\n", tag );
- pj_pr_list(toProj);
- }
-
- /* set input formatting control */
- if( !fromProj->is_latlong )
- informat = strtod;
- else {
- informat = dmstor;
- }
-
- if( !toProj->is_latlong && !oform )
- oform = "%.2f";
-
- /* process input file list */
- for ( ; eargc-- ; ++eargv) {
- if (**eargv == '-') {
- fid = stdin;
- emess_dat.File_name = "<stdin>";
-
- } else {
- if ((fid = fopen(*eargv, "rt")) == NULL) {
- emess(-2, *eargv, "input file");
- continue;
- }
- emess_dat.File_name = *eargv;
- }
- emess_dat.File_line = 0;
- process(fid);
- fclose(fid);
- emess_dat.File_name = 0;
- }
-
- pj_free( fromProj );
- pj_free( toProj );
-
- pj_deallocate_grids();
-
- exit(0); /* normal completion */
-}
diff --git a/src/cs2cs.cpp b/src/cs2cs.cpp
new file mode 100644
index 00000000..a8d126cf
--- /dev/null
+++ b/src/cs2cs.cpp
@@ -0,0 +1,636 @@
+/******************************************************************************
+ * Project: PROJ.4
+ * Purpose: Mainline program sort of like ``proj'' for converting between
+ * two coordinate systems.
+ * Author: Frank Warmerdam, warmerda@home.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2000, Frank Warmerdam
+ *
+ * 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.
+ *****************************************************************************/
+
+#define FROM_PROJ_CPP
+
+#include <ctype.h>
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cassert>
+#include <string>
+
+#include <proj/internal/internal.hpp>
+
+// PROJ include order is sensitive
+// clang-format off
+#include "proj.h"
+#include "projects.h"
+#include "emess.h"
+// clang-format on
+
+#define MAX_LINE 1000
+
+static PJ *transformation = nullptr;
+
+static bool srcIsGeog = false;
+static double srcToRadians = 0.0;
+
+static bool destIsGeog = false;
+static double destToRadians = 0.0;
+static bool destIsLatLong = false;
+
+static int reversein = 0, /* != 0 reverse input arguments */
+ reverseout = 0, /* != 0 reverse output arguments */
+ echoin = 0, /* echo input data to output line */
+ tag = '#'; /* beginning of line tag character */
+
+static const char *oform =
+ nullptr; /* output format for x-y or decimal degrees */
+static char oform_buffer[16]; /* buffer for oform when using -d */
+static const char *oterr = "*\t*"; /* output line for unprojectable input */
+static const char *usage =
+ "%s\nusage: %s [ -dDeEfIlrstvwW [args] ] [ +opts[=arg] ]\n"
+ " [+to [+opts[=arg] [ files ]\n";
+
+static double (*informat)(const char *,
+ char **); /* input data deformatter function */
+
+/************************************************************************/
+/* process() */
+/* */
+/* File processing function. */
+/************************************************************************/
+static void process(FILE *fid)
+
+{
+ char line[MAX_LINE + 3], *s, pline[40];
+ projUV data;
+
+ for (;;) {
+ double z;
+
+ ++emess_dat.File_line;
+ if (!(s = fgets(line, MAX_LINE, fid)))
+ break;
+ if (!strchr(s, '\n')) { /* overlong line */
+ int c;
+ (void)strcat(s, "\n");
+ /* gobble up to newline */
+ while ((c = fgetc(fid)) != EOF && c != '\n')
+ ;
+ }
+ if (*s == tag) {
+ fputs(line, stdout);
+ continue;
+ }
+
+ if (reversein) {
+ data.v = (*informat)(s, &s);
+ data.u = (*informat)(s, &s);
+ } else {
+ data.u = (*informat)(s, &s);
+ data.v = (*informat)(s, &s);
+ }
+
+ z = strtod(s, &s);
+
+ if (data.v == HUGE_VAL)
+ data.u = HUGE_VAL;
+
+ if (!*s && (s > line))
+ --s; /* assumed we gobbled \n */
+
+ if (echoin) {
+ char t;
+ t = *s;
+ *s = '\0';
+ (void)fputs(line, stdout);
+ *s = t;
+ putchar('\t');
+ }
+
+ if (data.u != HUGE_VAL) {
+
+ if (srcIsGeog) {
+ /* dmstor gives values to radians. Convert now to the SRS unit
+ */
+ data.u /= srcToRadians;
+ data.v /= srcToRadians;
+ }
+
+ PJ_COORD coord;
+ coord.xyzt.x = data.u;
+ coord.xyzt.y = data.v;
+ coord.xyzt.z = z;
+ coord.xyzt.t = HUGE_VAL;
+ coord = proj_trans(transformation, PJ_FWD, coord);
+ data.u = coord.xyz.x;
+ data.v = coord.xyz.y;
+ z = coord.xyz.z;
+ }
+
+ if (data.u == HUGE_VAL) /* error output */
+ fputs(oterr, stdout);
+
+ else if (destIsGeog && !oform) { /*ascii DMS output */
+
+ // rtodms() expect radians: convert from the output SRS unit
+ data.u *= destToRadians;
+ data.v *= destToRadians;
+
+ if (destIsLatLong) {
+ if (reverseout) {
+ fputs(rtodms(pline, data.v, 'E', 'W'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.u, 'N', 'S'), stdout);
+ } else {
+ fputs(rtodms(pline, data.u, 'N', 'S'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.v, 'E', 'W'), stdout);
+ }
+ } else if (reverseout) {
+ fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+ } else {
+ fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+ }
+
+ } else { /* x-y or decimal degree ascii output */
+ if (destIsGeog) {
+ data.v *= destToRadians * RAD_TO_DEG;
+ data.u *= destToRadians * RAD_TO_DEG;
+ }
+ if (reverseout) {
+ printf(oform, data.v);
+ putchar('\t');
+ printf(oform, data.u);
+ } else {
+ printf(oform, data.u);
+ putchar('\t');
+ printf(oform, data.v);
+ }
+ }
+
+ putchar(' ');
+ if (oform != nullptr)
+ printf(oform, z);
+ else
+ printf("%.3f", z);
+ if (s)
+ printf("%s", s);
+ else
+ printf("\n");
+ }
+}
+
+/************************************************************************/
+/* instanciate_crs() */
+/************************************************************************/
+
+static PJ_OBJ *instanciate_crs(const std::string &definition,
+ const char *const *optionsImportCRS,
+ bool &isGeog, double &toRadians,
+ bool &isLatFirst) {
+ PJ_OBJ *crs = proj_obj_create_from_user_input(nullptr, definition.c_str(),
+ optionsImportCRS);
+ if (!crs) {
+ return nullptr;
+ }
+
+ isGeog = false;
+ toRadians = 0.0;
+ isLatFirst = false;
+
+ auto type = proj_obj_get_type(crs);
+ if (type == PJ_OBJ_TYPE_BOUND_CRS) {
+ auto base = proj_obj_get_source_crs(nullptr, crs);
+ proj_obj_unref(crs);
+ crs = base;
+ type = proj_obj_get_type(crs);
+ }
+ if (type == PJ_OBJ_TYPE_GEOGRAPHIC_2D_CRS ||
+ type == PJ_OBJ_TYPE_GEOGRAPHIC_3D_CRS) {
+ auto cs = proj_obj_crs_get_coordinate_system(nullptr, crs);
+ assert(cs);
+
+ isGeog = true;
+ const char *axisName = "";
+ proj_obj_cs_get_axis_info(nullptr, cs, 0,
+ &axisName, // name,
+ nullptr, // abbrev
+ nullptr, // direction
+ &toRadians,
+ nullptr // unit name
+ );
+ isLatFirst =
+ NS_PROJ::internal::ci_find(std::string(axisName), "latitude") !=
+ std::string::npos;
+
+ proj_obj_unref(cs);
+ }
+
+ return crs;
+}
+
+/************************************************************************/
+/* get_geog_crs_proj_string_from_proj_crs() */
+/************************************************************************/
+
+static std::string get_geog_crs_proj_string_from_proj_crs(PJ_OBJ *src,
+ double &toRadians,
+ bool &isLatFirst) {
+ auto srcType = proj_obj_get_type(src);
+ if (srcType == PJ_OBJ_TYPE_BOUND_CRS) {
+ auto base = proj_obj_get_source_crs(nullptr, src);
+ assert(base);
+ proj_obj_unref(src);
+ src = base;
+ srcType = proj_obj_get_type(src);
+ }
+ if (srcType != PJ_OBJ_TYPE_PROJECTED_CRS) {
+ return std::string();
+ }
+
+ auto base = proj_obj_get_source_crs(nullptr, src);
+ assert(base);
+ auto baseType = proj_obj_get_type(base);
+ if (baseType != PJ_OBJ_TYPE_GEOGRAPHIC_2D_CRS &&
+ baseType != PJ_OBJ_TYPE_GEOGRAPHIC_3D_CRS) {
+ proj_obj_unref(base);
+ return std::string();
+ }
+
+ auto cs = proj_obj_crs_get_coordinate_system(nullptr, base);
+ assert(cs);
+
+ const char *axisName = "";
+ proj_obj_cs_get_axis_info(nullptr, cs, 0,
+ &axisName, // name,
+ nullptr, // abbrev
+ nullptr, // direction
+ &toRadians,
+ nullptr // unit name
+ );
+ isLatFirst = NS_PROJ::internal::ci_find(std::string(axisName),
+ "latitude") != std::string::npos;
+
+ proj_obj_unref(cs);
+
+ auto retCStr = proj_obj_as_proj_string(nullptr, base, PJ_PROJ_5, nullptr);
+ std::string ret(retCStr ? retCStr : "");
+ proj_obj_unref(base);
+ return ret;
+}
+
+/************************************************************************/
+/* main() */
+/************************************************************************/
+
+int main(int argc, char **argv) {
+ char *arg;
+ char **eargv = argv;
+ std::string fromStr;
+ std::string toStr;
+ FILE *fid;
+ int eargc = 0, mon = 0;
+ int have_to_flag = 0, inverse = 0;
+ int use_env_locale = 0;
+
+ /* This is just to check that pj_init() is locale-safe */
+ /* Used by nad/testvarious */
+ if (getenv("PROJ_USE_ENV_LOCALE") != nullptr)
+ use_env_locale = 1;
+
+ /* Enable compatibility mode for init=epsg:XXXX by default */
+ if (getenv("PROJ_USE_PROJ4_INIT_RULES") == nullptr) {
+ proj_context_use_proj4_init_rules(nullptr, true);
+ }
+
+ if ((emess_dat.Prog_name = strrchr(*argv, DIR_CHAR)) != nullptr)
+ ++emess_dat.Prog_name;
+ else
+ emess_dat.Prog_name = *argv;
+ inverse = !strncmp(emess_dat.Prog_name, "inv", 3);
+ if (argc <= 1) {
+ (void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name);
+ exit(0);
+ }
+
+ // First pass to check if we have "cs2cs [-bla]* <SRC> <DEST>" syntax
+ int countNonOptionArg = 0;
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (argv[i][1] == '\0') {
+ countNonOptionArg++;
+ }
+ } else {
+ if (strcmp(argv[i], "+to") == 0) {
+ countNonOptionArg = -1;
+ break;
+ }
+ countNonOptionArg++;
+ }
+ }
+ const bool isSrcDestSyntax = (countNonOptionArg == 2);
+
+ /* process run line arguments */
+ while (--argc > 0) { /* collect run line arguments */
+ if (**++argv == '-') {
+ for (arg = *argv;;) {
+ switch (*++arg) {
+ case '\0': /* position of "stdin" */
+ if (arg[-1] == '-')
+ eargv[eargc++] = const_cast<char *>("-");
+ break;
+ case 'v': /* monitor dump of initialization */
+ mon = 1;
+ continue;
+ case 'I': /* alt. method to spec inverse */
+ inverse = 1;
+ continue;
+ case 'E': /* echo ascii input to ascii output */
+ echoin = 1;
+ continue;
+ case 't': /* set col. one char */
+ if (arg[1])
+ tag = *++arg;
+ else
+ emess(1, "missing -t col. 1 tag");
+ continue;
+ case 'l': /* list projections, ellipses or units */
+ if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') {
+ /* list projections */
+ const struct PJ_LIST *lp;
+ int do_long = arg[1] == 'P', c;
+ const char *str;
+
+ for (lp = proj_list_operations(); lp->id; ++lp) {
+ (void)printf("%s : ", lp->id);
+ if (do_long) /* possibly multiline description */
+ (void)puts(*lp->descr);
+ else { /* first line, only */
+ str = *lp->descr;
+ while ((c = *str++) && c != '\n')
+ putchar(c);
+ putchar('\n');
+ }
+ }
+ } else if (arg[1] == '=') { /* list projection 'descr' */
+ const struct PJ_LIST *lp;
+
+ arg += 2;
+ for (lp = proj_list_operations(); lp->id; ++lp)
+ if (!strcmp(lp->id, arg)) {
+ (void)printf("%9s : %s\n", lp->id, *lp->descr);
+ break;
+ }
+ } else if (arg[1] == 'e') { /* list ellipses */
+ const struct PJ_ELLPS *le;
+
+ for (le = proj_list_ellps(); le->id; ++le)
+ (void)printf("%9s %-16s %-16s %s\n", le->id,
+ le->major, le->ell, le->name);
+ } else if (arg[1] == 'u') { /* list units */
+ const struct PJ_UNITS *lu;
+
+ for (lu = proj_list_units(); lu->id; ++lu)
+ (void)printf("%12s %-20s %s\n", lu->id,
+ lu->to_meter, lu->name);
+ } else if (arg[1] == 'd') { /* list datums */
+ const struct PJ_DATUMS *ld;
+
+ printf("__datum_id__ __ellipse___ "
+ "__definition/"
+ "comments______________________________\n");
+ for (ld = pj_get_datums_ref(); ld->id; ++ld) {
+ printf("%12s %-12s %-30s\n", ld->id, ld->ellipse_id,
+ ld->defn);
+ if (ld->comments != nullptr &&
+ strlen(ld->comments) > 0)
+ printf("%25s %s\n", " ", ld->comments);
+ }
+ } else if (arg[1] == 'm') { /* list prime meridians */
+ const struct PJ_PRIME_MERIDIANS *lpm;
+
+ for (lpm = proj_list_prime_meridians(); lpm->id; ++lpm)
+ (void)printf("%12s %-30s\n", lpm->id, lpm->defn);
+ } else
+ emess(1, "invalid list option: l%c", arg[1]);
+ exit(0);
+ /* cppcheck-suppress duplicateBreak */
+ continue; /* artificial */
+ case 'e': /* error line alternative */
+ if (--argc <= 0)
+ noargument:
+ emess(1, "missing argument for -%c", *arg);
+ oterr = *++argv;
+ continue;
+ case 'W': /* specify seconds precision */
+ case 'w': /* -W for constant field width */
+ {
+ char c = arg[1];
+ if (c != 0 && isdigit(c)) {
+ set_rtodms(c - '0', *arg == 'W');
+ ++arg;
+ } else
+ emess(1, "-W argument missing or non-digit");
+ continue;
+ }
+ case 'f': /* alternate output format degrees or xy */
+ if (--argc <= 0)
+ goto noargument;
+ oform = *++argv;
+ continue;
+ case 'r': /* reverse input */
+ reversein = 1;
+ continue;
+ case 's': /* reverse output */
+ reverseout = 1;
+ continue;
+ case 'D': /* set debug level */
+ if (--argc <= 0)
+ goto noargument;
+ pj_ctx_set_debug(pj_get_default_ctx(), atoi(*++argv));
+ continue;
+ case 'd':
+ if (--argc <= 0)
+ goto noargument;
+ sprintf(oform_buffer, "%%.%df", atoi(*++argv));
+ oform = oform_buffer;
+ break;
+ default:
+ emess(1, "invalid option: -%c", *arg);
+ break;
+ }
+ break;
+ }
+ } else if (isSrcDestSyntax) {
+ if (fromStr.empty())
+ fromStr = *argv;
+ else
+ toStr = *argv;
+ } else if (strcmp(*argv, "+to") == 0) {
+ have_to_flag = 1;
+
+ } else if (**argv == '+') { /* + argument */
+ if (have_to_flag) {
+ if (!toStr.empty())
+ toStr += ' ';
+ toStr += *argv;
+ } else {
+ if (!fromStr.empty())
+ fromStr += ' ';
+ fromStr += *argv;
+ }
+ } else if (!have_to_flag) {
+ fromStr = *argv;
+ } else if (toStr.empty()) {
+ toStr = *argv;
+ } else /* assumed to be input file name(s) */
+ eargv[eargc++] = *argv;
+ }
+ if (eargc == 0) /* if no specific files force sysin */
+ eargv[eargc++] = const_cast<char *>("-");
+
+ /*
+ * If the user has requested inverse, then just reverse the
+ * coordinate systems.
+ */
+ if (inverse) {
+ std::swap(fromStr, toStr);
+ }
+
+ if (use_env_locale) {
+ /* Set locale from environment */
+ setlocale(LC_ALL, "");
+ }
+
+ if (fromStr.empty() && toStr.empty()) {
+ emess(3, "missing source and target coordinate systems");
+ }
+
+ const char *const optionsProj4Mode[] = {"USE_PROJ4_INIT_RULES=YES",
+ nullptr};
+ const char *const *optionsImportCRS =
+ proj_context_get_use_proj4_init_rules(nullptr, TRUE) ? optionsProj4Mode
+ : nullptr;
+
+ PJ_OBJ *src = nullptr;
+ if (!fromStr.empty()) {
+ bool ignored;
+ src = instanciate_crs(fromStr, optionsImportCRS, srcIsGeog,
+ srcToRadians, ignored);
+ if (!src) {
+ emess(3, "cannot instanciate source coordinate system");
+ }
+ }
+
+ PJ_OBJ *dst = nullptr;
+ if (!toStr.empty()) {
+ dst = instanciate_crs(toStr, optionsImportCRS, destIsGeog,
+ destToRadians, destIsLatLong);
+ if (!dst) {
+ emess(3, "cannot instanciate target coordinate system");
+ }
+ }
+
+ if (toStr.empty()) {
+ assert(src);
+ toStr = get_geog_crs_proj_string_from_proj_crs(src, destToRadians,
+ destIsLatLong);
+ if (toStr.empty()) {
+ emess(3,
+ "missing target CRS and source CRS is not a projected CRS");
+ }
+ destIsGeog = true;
+ } else if (fromStr.empty()) {
+ assert(dst);
+ bool ignored;
+ fromStr =
+ get_geog_crs_proj_string_from_proj_crs(dst, srcToRadians, ignored);
+ if (fromStr.empty()) {
+ emess(3,
+ "missing source CRS and target CRS is not a projected CRS");
+ }
+ srcIsGeog = true;
+ }
+
+ proj_obj_unref(src);
+ proj_obj_unref(dst);
+
+ transformation = proj_create_crs_to_crs(nullptr, fromStr.c_str(),
+ toStr.c_str(), nullptr);
+ if (!transformation) {
+ emess(3, "cannot initialize transformation\ncause: %s",
+ pj_strerrno(pj_errno));
+ }
+
+ if (use_env_locale) {
+ /* Restore C locale to avoid issues in parsing/outputting numbers*/
+ setlocale(LC_ALL, "C");
+ }
+
+ if (mon) {
+ printf("%c ---- From Coordinate System ----\n", tag);
+ printf("%s\n", fromStr.c_str());
+ printf("%c ---- To Coordinate System ----\n", tag);
+ printf("%s\n", toStr.c_str());
+ }
+
+ /* set input formatting control */
+ if (!srcIsGeog)
+ informat = strtod;
+ else {
+ informat = dmstor;
+ }
+
+ if (!destIsGeog && !oform)
+ oform = "%.2f";
+
+ /* process input file list */
+ for (; eargc--; ++eargv) {
+ if (**eargv == '-') {
+ fid = stdin;
+ emess_dat.File_name = const_cast<char *>("<stdin>");
+
+ } else {
+ if ((fid = fopen(*eargv, "rt")) == nullptr) {
+ emess(-2, *eargv, "input file");
+ continue;
+ }
+ emess_dat.File_name = *eargv;
+ }
+ emess_dat.File_line = 0;
+ process(fid);
+ fclose(fid);
+ emess_dat.File_name = nullptr;
+ }
+
+ proj_destroy(transformation);
+
+ pj_deallocate_grids();
+
+ exit(0); /* normal completion */
+}
diff --git a/src/emess.h b/src/emess.h
index 82526776..cb6b38f4 100644
--- a/src/emess.h
+++ b/src/emess.h
@@ -2,6 +2,10 @@
#ifndef EMESS_H
#define EMESS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct EMESS {
char *File_name, /* input file name */
*Prog_name; /* name of program */
@@ -26,4 +30,8 @@ extern struct EMESS PROJ_DLL emess_dat;
void PROJ_DLL emess(int, const char *, ...);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* end EMESS_H */
diff --git a/src/factory.cpp b/src/factory.cpp
index 3c360d13..91d0c478 100644
--- a/src/factory.cpp
+++ b/src/factory.cpp
@@ -157,6 +157,8 @@ struct DatabaseContext::Private {
};
private:
+ friend class DatabaseContext;
+
std::string databasePath_{};
bool close_handle_ = true;
sqlite3 *sqlite_handle_{};
@@ -164,6 +166,7 @@ struct DatabaseContext::Private {
PJ_CONTEXT *pjCtxt_ = nullptr;
int recLevel_ = 0;
bool detach_ = false;
+ std::string lastMetadataValue_{};
void closeDB();
@@ -704,6 +707,22 @@ const std::string &DatabaseContext::getPath() const { return d->getPath(); }
// ---------------------------------------------------------------------------
+/** \brief Return a metadata item.
+ *
+ * Value remains valid while this is alive and to the next call to getMetadata
+ */
+const char *DatabaseContext::getMetadata(const char *key) const {
+ auto res =
+ d->run("SELECT value FROM metadata WHERE key = ?", {std::string(key)});
+ if (res.empty()) {
+ return nullptr;
+ }
+ d->lastMetadataValue_ = res[0][0];
+ return d->lastMetadataValue_.c_str();
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
DatabaseContextNNPtr DatabaseContext::create(void *sqlite_handle) {
@@ -833,6 +852,29 @@ DatabaseContext::getAliasFromOfficialName(const std::string &officialName,
return res[0][0];
}
+// ---------------------------------------------------------------------------
+
+/** \brief Return the 'text_definition' column of a table for an object
+ *
+ * @param tableName Table name/category.
+ * @param authName Authority name of the object.
+ * @param code Code of the object
+ * @return Text definition (or empty)
+ * @throw FactoryException
+ */
+std::string DatabaseContext::getTextDefinition(const std::string &tableName,
+ const std::string &authName,
+ const std::string &code) const {
+ std::string sql("SELECT text_definition FROM \"");
+ sql += replaceAll(tableName, "\"", "\"\"");
+ sql += "\" WHERE auth_name = ? AND code = ?";
+ auto res = d->run(sql, {authName, code});
+ if (res.empty()) {
+ return std::string();
+ }
+ return res[0][0];
+}
+
//! @endcond
// ---------------------------------------------------------------------------
@@ -3788,6 +3830,11 @@ AuthorityFactory::createObjectsFromName(
break;
}
}
+ if (res.empty() && !deprecated) {
+ return createObjectsFromName(searchedName + " (deprecated)",
+ allowedObjectTypes, approximateMatch,
+ limitResultCount);
+ }
auto sortLambda = [](const common::IdentifiedObjectNNPtr &a,
const common::IdentifiedObjectNNPtr &b) {
diff --git a/src/gie.c b/src/gie.c
index 73b27df8..4bb79f1f 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -148,8 +148,9 @@ static ffio *ffio_destroy (ffio *G);
static ffio *ffio_create (const char **tags, size_t n_tags, size_t max_record_size);
static const char *gie_tags[] = {
- "<gie>", "operation", "accept", "expect", "roundtrip", "banner", "verbose",
- "direction", "tolerance", "ignore", "require_grid", "builtins", "echo", "skip", "</gie>"
+ "<gie>", "operation", "use_proj4_init_rules",
+ "accept", "expect", "roundtrip", "banner", "verbose",
+ "direction", "tolerance", "ignore", "require_grid", "echo", "skip", "</gie>"
};
static const size_t n_gie_tags = sizeof gie_tags / sizeof gie_tags[0];
@@ -186,6 +187,7 @@ typedef struct {
size_t operation_lineno;
size_t dimensions_given, dimensions_given_at_last_accept;
double tolerance;
+ int use_proj4_init_rules;
int ignore;
int skip_test;
const char *curr_file;
@@ -196,8 +198,6 @@ ffio *F = 0;
static gie_ctx T;
int tests=0, succs=0, succ_fails=0, fail_fails=0, succ_rtps=0, fail_rtps=0;
-int succ_builtins=0, fail_builtins=0;
-
static const char delim[] = {"-------------------------------------------------------------------------------\n"};
@@ -245,6 +245,7 @@ int main (int argc, char **argv) {
T.verbosity = 1;
T.tolerance = 5e-4;
T.ignore = 5555; /* Error code that will not be issued by proj_create() */
+ T.use_proj4_init_rules = FALSE;
o = opt_parse (argc, argv, "hlvq", "o", longflags, longkeys);
if (0==o)
@@ -312,7 +313,6 @@ int main (int argc, char **argv) {
if (T.verbosity > 1) {
fprintf (T.fout, "Failing roundtrips: %4d, Succeeding roundtrips: %4d\n", fail_rtps, succ_rtps);
fprintf (T.fout, "Failing failures: %4d, Succeeding failures: %4d\n", fail_fails, succ_fails);
- fprintf (T.fout, "Failing builtins: %4d, Succeeding builtins: %4d\n", fail_builtins, succ_builtins);
fprintf (T.fout, "Internal counters: %4.4d(%4.4d)\n", tests, succs);
fprintf (T.fout, "%s", delim);
}
@@ -369,17 +369,6 @@ static int another_failing_roundtrip (void) {
return another_failure ();
}
-static int another_succeeding_builtin (void) {
- succ_builtins++;
- return another_success ();
-}
-
-static int another_failing_builtin (void) {
- fail_builtins++;
- return another_failure ();
-}
-
-
static int process_file (const char *fname) {
FILE *f;
@@ -512,6 +501,12 @@ static int tolerance (const char *args) {
return 0;
}
+
+static int use_proj4_init_rules (const char *args) {
+ T.use_proj4_init_rules = strcmp(args, "true") == 0;
+ return 0;
+}
+
static int ignore (const char *args) {
T.ignore = errno_from_err_const (column (args, 1));
return 0;
@@ -597,6 +592,7 @@ either a conversion or a transformation)
if (T.P)
proj_destroy (T.P);
proj_errno_reset (0);
+ proj_context_use_proj4_init_rules(0, T.use_proj4_init_rules);
T.P = proj_create (0, F->args);
@@ -606,57 +602,6 @@ either a conversion or a transformation)
return 0;
}
-
-
-
-static int unitconvert_selftest (void);
-static int cart_selftest (void);
-static int horner_selftest (void);
-
-/*****************************************************************************/
-static int builtins (const char *args) {
-/*****************************************************************************
-There are still a few tests that cannot be described using gie
-primitives. Instead, they are implemented as builtins, and invoked
-using the "builtins" command verb.
-******************************************************************************/
- int i;
- if (T.verbosity > 1) {
- finish_previous_operation (args);
- banner ("builtins: unitconvert, horner, cart");
- }
- T.op_ok = 0;
- T.op_ko = 0;
- T.op_skip = 0;
- i = unitconvert_selftest ();
- if (i!=0) {
- fprintf (T.fout, "unitconvert_selftest fails with %d\n", i);
- another_failing_builtin();
- }
- else
- another_succeeding_builtin ();
-
-
- i = cart_selftest ();
- if (i!=0) {
- fprintf (T.fout, "cart_selftest fails with %d\n", i);
- another_failing_builtin();
- }
- else
- another_succeeding_builtin ();
-
- i = horner_selftest ();
- if (i!=0) {
- fprintf (T.fout, "horner_selftest fails with %d\n", i);
- another_failing_builtin();
- }
- else
- another_succeeding_builtin ();
-
- return 0;
-}
-
-
static PJ_COORD torad_coord (PJ *P, PJ_DIRECTION dir, PJ_COORD a) {
size_t i, n;
char *axis = "enut";
@@ -1064,9 +1009,10 @@ static int dispatch (const char *cmnd, const char *args) {
if (0==strcmp (cmnd, "tolerance")) return tolerance (args);
if (0==strcmp (cmnd, "ignore")) return ignore (args);
if (0==strcmp (cmnd, "require_grid")) return require_grid (args);
- if (0==strcmp (cmnd, "builtins")) return builtins (args);
if (0==strcmp (cmnd, "echo")) return echo (args);
if (0==strcmp (cmnd, "skip")) return skip (args);
+ if (0==strcmp (cmnd, "use_proj4_init_rules"))
+ return use_proj4_init_rules (args);
return 0;
}
@@ -1508,567 +1454,3 @@ whitespace etc. The block is stored in G->args. Returns 1 on success, 0 otherwis
pj_shrink (G->args);
return 1;
}
-
-
-
-
-
-static const char tc32_utm32[] = {
- " +proj=horner"
- " +ellps=intl"
- " +range=500000"
- " +fwd_origin=877605.269066,6125810.306769"
- " +inv_origin=877605.760036,6125811.281773"
- " +deg=4"
- " +fwd_v=6.1258112678e+06,9.9999971567e-01,1.5372750011e-10,5.9300860915e-15,2.2609497633e-19,4.3188227445e-05,2.8225130416e-10,7.8740007114e-16,-1.7453997279e-19,1.6877465415e-10,-1.1234649773e-14,-1.7042333358e-18,-7.9303467953e-15,-5.2906832535e-19,3.9984284847e-19"
- " +fwd_u=8.7760574982e+05,9.9999752475e-01,2.8817299305e-10,5.5641310680e-15,-1.5544700949e-18,-4.1357045890e-05,4.2106213519e-11,2.8525551629e-14,-1.9107771273e-18,3.3615590093e-10,2.4380247154e-14,-2.0241230315e-18,1.2429019719e-15,5.3886155968e-19,-1.0167505000e-18"
- " +inv_v=6.1258103208e+06,1.0000002826e+00,-1.5372762184e-10,-5.9304261011e-15,-2.2612705361e-19,-4.3188331419e-05,-2.8225549995e-10,-7.8529116371e-16,1.7476576773e-19,-1.6875687989e-10,1.1236475299e-14,1.7042518057e-18,7.9300735257e-15,5.2881862699e-19,-3.9990736798e-19"
- " +inv_u=8.7760527928e+05,1.0000024735e+00,-2.8817540032e-10,-5.5627059451e-15,1.5543637570e-18,4.1357152105e-05,-4.2114813612e-11,-2.8523713454e-14,1.9109017837e-18,-3.3616407783e-10,-2.4382678126e-14,2.0245020199e-18,-1.2441377565e-15,-5.3885232238e-19,1.0167203661e-18"
-};
-
-
-static const char sb_utm32[] = {
- " +proj=horner"
- " +ellps=intl"
- " +range=500000"
- " +tolerance=0.0005"
- " +fwd_origin=4.94690026817276e+05,6.13342113183056e+06"
- " +inv_origin=6.19480258923588e+05,6.13258568148837e+06"
- " +deg=3"
- " +fwd_c=6.13258562111350e+06,6.19480105709997e+05,9.99378966275206e-01,-2.82153291753490e-02,-2.27089979140026e-10,-1.77019590701470e-09,1.08522286274070e-14,2.11430298751604e-15"
- " +inv_c=6.13342118787027e+06,4.94690181709311e+05,9.99824464710368e-01,2.82279070814774e-02,7.66123542220864e-11,1.78425334628927e-09,-1.05584823306400e-14,-3.32554258683744e-15"
-};
-
-static int horner_selftest (void) {
- PJ *P;
- PJ_COORD a, b, c;
- double dist;
-
- /* Real polynonia relating the technical coordinate system TC32 to "System 45 Bornholm" */
- P = proj_create (PJ_DEFAULT_CTX, tc32_utm32);
- if (0==P)
- return 10;
-
- a = b = proj_coord (0,0,0,0);
- a.uv.v = 6125305.4245;
- a.uv.u = 878354.8539;
- c = a;
-
- /* Check roundtrip precision for 1 iteration each way, starting in forward direction */
- dist = proj_roundtrip (P, PJ_FWD, 1, &c);
- if (dist > 0.01)
- return 1;
- proj_destroy(P);
-
- /* The complex polynomial transformation between the "System Storebaelt" and utm32/ed50 */
- P = proj_create (PJ_DEFAULT_CTX, sb_utm32);
- if (0==P)
- return 11;
-
- /* Test value: utm32_ed50(620000, 6130000) = sb_ed50(495136.8544, 6130821.2945) */
- a = b = c = proj_coord (0,0,0,0);
- a.uv.v = 6130821.2945;
- a.uv.u = 495136.8544;
- c.uv.v = 6130000.0000;
- c.uv.u = 620000.0000;
-
- /* Forward projection */
- b = proj_trans (P, PJ_FWD, a);
- dist = proj_xy_dist (b, c);
- if (dist > 0.001)
- return 2;
-
- /* Inverse projection */
- b = proj_trans (P, PJ_INV, c);
- dist = proj_xy_dist (b, a);
- if (dist > 0.001)
- return 3;
-
- /* Check roundtrip precision for 1 iteration each way */
- dist = proj_roundtrip (P, PJ_FWD, 1, &a);
- if (dist > 0.01)
- return 4;
-
- proj_destroy(P);
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-/* Testing quite a bit of the pj_obs_api as a side effect (inspired by pj_obs_api_test.c) */
-static int cart_selftest (void) {
- PJ_CONTEXT *ctx;
- PJ *P;
- PJ_COORD a, b, obs[2];
- PJ_COORD coord[2];
-
- PJ_INFO info;
- PJ_PROJ_INFO pj_info;
- PJ_GRID_INFO grid_info;
- PJ_INIT_INFO init_info;
-
- PJ_FACTORS factors;
-
- const PJ_OPERATIONS *oper_list;
- const PJ_ELLPS *ellps_list;
- const PJ_UNITS *unit_list;
- const PJ_PRIME_MERIDIANS *pm_list;
-
- int err;
- size_t n, sz;
- double dist, h, t;
- char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"};
- char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"};
- char buf[40];
-
- /* An utm projection on the GRS80 ellipsoid */
- P = proj_create (PJ_DEFAULT_CTX, arg);
- if (0==P)
- return 1;
-
-
- /* Clean up */
- proj_destroy (P);
-
- /* Same projection, now using argc/argv style initialization */
- P = proj_create_argv (PJ_DEFAULT_CTX, 3, args);
- if (0==P)
- return 2;
-
- /* zero initialize everything, then set (longitude, latitude) to (12, 55) */
- a = proj_coord (0,0,0,0);
- /* a.lp: The coordinate part of a, interpreted as a classic LP pair */
- a.lp.lam = PJ_TORAD(12);
- a.lp.phi = PJ_TORAD(55);
-
- /* Forward projection */
- b = proj_trans (P, PJ_FWD, a);
-
- /* Inverse projection */
- a = proj_trans (P, PJ_INV, b);
-
- /* Null projection */
- a = proj_trans (P, PJ_IDENT, a);
-
- /* Forward again, to get two linear items for comparison */
- a = proj_trans (P, PJ_FWD, a);
-
- dist = proj_xy_dist (a, b);
- if (dist > 2e-9)
- return 3;
-
- /* Clear any previous error */
- proj_errno_reset (P);
-
- /* Invalid projection */
- a = proj_trans (P, 42, a);
- if (a.lpz.lam!=HUGE_VAL)
- return 4;
- err = proj_errno (P);
- if (0==err)
- return 5;
-
- /* Clear error again */
- proj_errno_reset (P);
-
- /* Clean up */
- proj_destroy (P);
-
- /* Now do some 3D transformations */
- P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80");
- if (0==P)
- return 6;
-
- /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 100) */
- a = b = proj_coord (0,0,0,0);
- a.lpz.lam = PJ_TORAD(12);
- a.lpz.phi = PJ_TORAD(55);
- a.lpz.z = 100;
-
- /* Forward projection: 3D-Cartesian-to-Ellipsoidal */
- b = proj_trans (P, PJ_FWD, a);
-
- /* Check roundtrip precision for 10000 iterations each way */
- dist = proj_roundtrip (P, PJ_FWD, 10000, &a);
- dist += proj_roundtrip (P, PJ_INV, 10000, &b);
- if (dist > 4e-9)
- return 7;
-
-
- /* Test at the North Pole */
- a = b = proj_coord (0,0,0,0);
- a.lpz.lam = PJ_TORAD(0);
- a.lpz.phi = PJ_TORAD(90);
- a.lpz.z = 100;
-
- /* Forward projection: Ellipsoidal-to-3D-Cartesian */
- dist = proj_roundtrip (P, PJ_FWD, 1, &a);
- if (dist > 1e-9)
- return 8;
-
- /* Test at the South Pole */
- a = b = proj_coord (0,0,0,0);
- a.lpz.lam = PJ_TORAD(0);
- a.lpz.phi = PJ_TORAD(-90);
- a.lpz.z = 100;
- b = a;
-
- /* Forward projection: Ellipsoidal-to-3D-Cartesian */
- dist = proj_roundtrip (P, PJ_FWD, 1, &a);
- if (dist > 1e-9)
- return 9;
-
-
- /* Inverse projection: 3D-Cartesian-to-Ellipsoidal */
- b = proj_trans (P, PJ_INV, b);
-
- /* Move p to another context */
- ctx = proj_context_create ();
- if (ctx==pj_get_default_ctx())
- return 10;
- proj_context_set (P, ctx);
- if (ctx != P->ctx)
- return 11;
- b = proj_trans (P, PJ_FWD, b);
-
- /* Move it back to the default context */
- proj_context_set (P, 0);
- if (pj_get_default_ctx() != P->ctx)
- return 12;
- proj_context_destroy (ctx);
-
- /* We go on with the work - now back on the default context */
- b = proj_trans (P, PJ_INV, b);
- proj_destroy (P);
-
-
- /* Testing proj_trans_generic () */
-
- /* An utm projection on the GRS80 ellipsoid */
- P = proj_create (PJ_DEFAULT_CTX, "+proj=utm +zone=32 +ellps=GRS80");
- if (0==P)
- return 13;
-
- obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0);
- obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0);
- sz = sizeof (PJ_COORD);
-
- /* Forward projection */
- a = proj_trans (P, PJ_FWD, obs[0]);
- b = proj_trans (P, PJ_FWD, obs[1]);
-
- n = proj_trans_generic (
- P, PJ_FWD,
- &(obs[0].lpz.lam), sz, 2,
- &(obs[0].lpz.phi), sz, 2,
- &(obs[0].lpz.z), sz, 2,
- 0, sz, 0
- );
- if (2!=n)
- return 14;
- if (a.lpz.lam != obs[0].lpz.lam) return 15;
- if (a.lpz.phi != obs[0].lpz.phi) return 16;
- if (a.lpz.z != obs[0].lpz.z) return 17;
- if (b.lpz.lam != obs[1].lpz.lam) return 18;
- if (b.lpz.phi != obs[1].lpz.phi) return 19;
- if (b.lpz.z != obs[1].lpz.z) return 20;
-
- /* now test the case of constant z */
- obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0);
- obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0);
- h = 27;
- t = 33;
- n = proj_trans_generic (
- P, PJ_FWD,
- &(obs[0].lpz.lam), sz, 2,
- &(obs[0].lpz.phi), sz, 2,
- &h, 0, 1,
- &t, 0, 1
- );
- if (2!=n)
- return 21;
- if (a.lpz.lam != obs[0].lpz.lam) return 22;
- if (a.lpz.phi != obs[0].lpz.phi) return 23;
- if (45 != obs[0].lpz.z) return 24;
- if (b.lpz.lam != obs[1].lpz.lam) return 25;
- if (b.lpz.phi != obs[1].lpz.phi) return 26;
- if (50 != obs[1].lpz.z) return 27; /* NOTE: unchanged */
- if (50==h) return 28;
-
- /* test proj_trans_array () */
-
- coord[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0);
- coord[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0);
- if (proj_trans_array (P, PJ_FWD, 2, coord))
- return 40;
-
- if (a.lpz.lam != coord[0].lpz.lam) return 41;
- if (a.lpz.phi != coord[0].lpz.phi) return 42;
- if (a.lpz.z != coord[0].lpz.z) return 43;
- if (b.lpz.lam != coord[1].lpz.lam) return 44;
- if (b.lpz.phi != coord[1].lpz.phi) return 45;
- if (b.lpz.z != coord[1].lpz.z) return 46;
-
- /* Clean up after proj_trans_* tests */
- proj_destroy (P);
-
- /* test proj_create_crs_to_crs() */
- P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL);
- if (P==0)
- return 50;
-
- a.xy.x = 700000.0;
- a.xy.y = 6000000.0;
- b.xy.x = 307788.8761171057;
- b.xy.y = 5999669.3036037628;
-
- a = proj_trans(P, PJ_FWD, a);
- if (dist > 1e-7)
- return 51;
- proj_destroy(P);
-
- /* let's make sure that only entries in init-files results in a usable PJ */
- P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84", NULL);
- if (P != 0) {
- proj_destroy(P);
- return 52;
- }
- proj_destroy(P);
-
- /* ********************************************************************** */
- /* Test info functions */
- /* ********************************************************************** */
-
- /* proj_info() */
- /* this one is difficult to test, since the output changes with the setup */
- info = proj_info();
-
- if (info.version[0] != '\0' ) {
- char tmpstr[64];
- sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch);
- if (strcmp(info.version, tmpstr)) return 55;
- }
- if (info.release[0] == '\0') return 56;
- if (getenv ("HOME") || getenv ("PROJ_LIB"))
- if (info.searchpath[0] == '\0') return 57;
-
- /* proj_pj_info() */
- P = proj_create(PJ_DEFAULT_CTX, "+proj=august"); /* august has no inverse */
- if (proj_pj_info(P).has_inverse) { proj_destroy(P); return 60; }
- proj_destroy(P);
-
- P = proj_create(PJ_DEFAULT_CTX, arg);
- pj_info = proj_pj_info(P);
- if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; }
- pj_shrink (arg);
- if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; }
- if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; }
-
- proj_destroy(P);
-
- /* proj_grid_info() */
- grid_info = proj_grid_info("null");
- if ( strlen(grid_info.filename) == 0 ) return 64;
- if ( strcmp(grid_info.gridname, "null") ) return 65;
- grid_info = proj_grid_info("nonexistinggrid");
- if ( strlen(grid_info.filename) > 0 ) return 66;
-
- /* proj_init_info() */
- init_info = proj_init_info("unknowninit");
- if ( strlen(init_info.filename) != 0 ) return 67;
-
- init_info = proj_init_info("epsg");
- /* Need to allow for "Unknown" until all commonly distributed EPSG-files comes with a metadata section */
- if ( strcmp(init_info.origin, "EPSG") && strcmp(init_info.origin, "Unknown") ) return 69;
- if ( strcmp(init_info.name, "epsg") ) return 68;
-
-
- /* test proj_rtodms() and proj_dmstor() */
- if (strcmp("180dN", proj_rtodms(buf, M_PI, 'N', 'S')))
- return 70;
-
- if (proj_dmstor(&buf[0], NULL) != M_PI)
- return 71;
-
- if (strcmp("114d35'29.612\"S", proj_rtodms(buf, -2.0, 'N', 'S')))
- return 72;
-
- /* we can't expect perfect numerical accuracy so testing with a tolerance */
- if (fabs(-2.0 - proj_dmstor(&buf[0], NULL)) > 1e-7)
- return 73;
-
-
- /* test proj_derivatives_retrieve() and proj_factors_retrieve() */
- P = proj_create(PJ_DEFAULT_CTX, "+proj=merc");
- a = proj_coord (0,0,0,0);
- a.lp.lam = PJ_TORAD(12);
- a.lp.phi = PJ_TORAD(55);
-
- factors = proj_factors(P, a);
- if (proj_errno(P))
- return 85; /* factors not created correctly */
-
- /* check a few key characteristics of the Mercator projection */
- if (factors.angular_distortion != 0.0) return 86; /* angular distortion should be 0 */
- if (factors.meridian_parallel_angle != M_PI_2) return 87; /* Meridian/parallel angle should be 90 deg */
- if (factors.meridian_convergence != 0.0) return 88; /* meridian convergence should be 0 */
-
- proj_destroy(P);
-
- /* Check that proj_list_* functions work by looping through them */
- n = 0;
- for (oper_list = proj_list_operations(); oper_list->id; ++oper_list) n++;
- if (n == 0) return 90;
-
- n = 0;
- for (ellps_list = proj_list_ellps(); ellps_list->id; ++ellps_list) n++;
- if (n == 0) return 91;
-
- n = 0;
- for (unit_list = proj_list_units(); unit_list->id; ++unit_list) n++;
- if (n == 0) return 92;
-
- n = 0;
- for (pm_list = proj_list_prime_meridians(); pm_list->id; ++pm_list) n++;
- if (n == 0) return 93;
-
-
- /* check io-predicates */
-
- /* angular in on fwd, linear out */
- P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80");
- if (0==P) return 0;
- if (!proj_angular_input (P, PJ_FWD)) return 100;
- if ( proj_angular_input (P, PJ_INV)) return 101;
- if ( proj_angular_output (P, PJ_FWD)) return 102;
- if (!proj_angular_output (P, PJ_INV)) return 103;
- P->inverted = 1;
- if ( proj_angular_input (P, PJ_FWD)) return 104;
- if (!proj_angular_input (P, PJ_INV)) return 105;
- if (!proj_angular_output (P, PJ_FWD)) return 106;
- if ( proj_angular_output (P, PJ_INV)) return 107;
- proj_destroy(P);
-
- /* angular in and out */
- P = proj_create(PJ_DEFAULT_CTX,
- "+proj=molodensky +a=6378160 +rf=298.25 "
- "+da=-23 +df=-8.120449e-8 +dx=-134 +dy=-48 +dz=149 "
- "+abridged "
- );
- if (0==P) return 0;
- if (!proj_angular_input (P, PJ_FWD)) return 108;
- if (!proj_angular_input (P, PJ_INV)) return 109;
- if (!proj_angular_output (P, PJ_FWD)) return 110;
- if (!proj_angular_output (P, PJ_INV)) return 111;
- P->inverted = 1;
- if (!proj_angular_input (P, PJ_FWD)) return 112;
- if (!proj_angular_input (P, PJ_INV)) return 113;
- if (!proj_angular_output (P, PJ_FWD)) return 114;
- if (!proj_angular_output (P, PJ_INV)) return 115;
- proj_destroy(P);
-
- /* linear in and out */
- P = proj_create(PJ_DEFAULT_CTX,
- " +proj=helmert"
- " +x=0.0127 +y=0.0065 +z=-0.0209 +s=0.00195"
- " +rx=-0.00039 +ry=0.00080 +rz=-0.00114"
- " +dx=-0.0029 +dy=-0.0002 +dz=-0.0006 +ds=0.00001"
- " +drx=-0.00011 +dry=-0.00019 +drz=0.00007"
- " +t_epoch=1988.0 +transpose +no_defs"
- );
- if (0==P) return 0;
- if (proj_angular_input (P, PJ_FWD)) return 116;
- if (proj_angular_input (P, PJ_INV)) return 117;
- if (proj_angular_output (P, PJ_FWD)) return 118;
- if (proj_angular_output (P, PJ_INV)) return 119;
- P->inverted = 1;
- if (proj_angular_input (P, PJ_FWD)) return 120;
- if (proj_angular_input (P, PJ_INV)) return 121;
- if (proj_angular_output (P, PJ_FWD)) return 122;
- if (proj_angular_output (P, PJ_INV)) return 123;
-
- /* We specified "no_defs" but didn't give any ellipsoid info */
- /* pj_init_ctx should default to WGS84 */
- if (P->a != 6378137.0) return 124;
- if (P->f != 1.0/298.257223563) return 125;
- proj_destroy(P);
-
- /* Test that pj_fwd* and pj_inv* returns NaNs when receiving NaN input */
- P = proj_create(PJ_DEFAULT_CTX, "+proj=merc");
- if (0==P) return 0;
- a = proj_coord(NAN, NAN, NAN, NAN);
- a = proj_trans(P, PJ_FWD, a);
- if ( !( isnan(a.v[0]) && isnan(a.v[1]) && isnan(a.v[2]) && isnan(a.v[3]) ) )
- return 126;
- a = proj_coord(NAN, NAN, NAN, NAN);
- a = proj_trans(P, PJ_INV, a);
- if ( !( isnan(a.v[0]) && isnan(a.v[1]) && isnan(a.v[2]) && isnan(a.v[3]) ) )
- return 127;
- proj_destroy(P);
-
- return 0;
-}
-
-
-
-
-static int test_time(const char* args, double tol, double t_in, double t_exp) {
- PJ_COORD in, out;
- PJ *P = proj_create(PJ_DEFAULT_CTX, args);
- int ret = 0;
-
- if (P == 0)
- return 5;
-
- in = proj_coord(0.0, 0.0, 0.0, t_in);
-
- out = proj_trans(P, PJ_FWD, in);
- if (fabs(out.xyzt.t - t_exp) > tol) {
- proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_exp);
- ret = 1;
- }
- out = proj_trans(P, PJ_INV, out);
- if (fabs(out.xyzt.t - t_in) > tol) {
- proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_in);
- ret = 2;
- }
- pj_free(P);
-
- proj_log_level(NULL, 0);
- return ret;
-}
-
-static int unitconvert_selftest (void) {
- int ret = 0;
- char args1[] = "+proj=unitconvert +t_in=decimalyear +t_out=decimalyear";
- double in1 = 2004.25;
-
- char args2[] = "+proj=unitconvert +t_in=gps_week +t_out=gps_week";
- double in2 = 1782.0;
-
- char args3[] = "+proj=unitconvert +t_in=mjd +t_out=mjd";
- double in3 = 57390.0;
-
- char args4[] = "+proj=unitconvert +t_in=gps_week +t_out=decimalyear";
- double in4 = 1877.71428, exp4 = 2016.0;
-
- char args5[] = "+proj=unitconvert +t_in=yyyymmdd +t_out=yyyymmdd";
- double in5 = 20170131;
-
- ret = test_time(args1, 1e-6, in1, in1); if (ret) return ret + 10;
- ret = test_time(args2, 1e-6, in2, in2); if (ret) return ret + 20;
- ret = test_time(args3, 1e-6, in3, in3); if (ret) return ret + 30;
- ret = test_time(args4, 1e-6, in4, exp4); if (ret) return ret + 40;
- ret = test_time(args5, 1e-6, in5, in5); if (ret) return ret + 50;
-
- return 0;
-}
diff --git a/src/io.cpp b/src/io.cpp
index 87caddd0..11e4748e 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -373,7 +373,7 @@ void WKTFormatter::startNode(const std::string &keyword, bool hasId) {
if (!d->stackHasChild_.empty()) {
d->startNewChild();
} else if (!d->result_.empty()) {
- d->result_ += ",";
+ d->result_ += ',';
if (d->params_.multiLine_ && !keyword.empty()) {
d->addNewLine();
}
@@ -390,7 +390,7 @@ void WKTFormatter::startNode(const std::string &keyword, bool hasId) {
if (!keyword.empty()) {
d->result_ += keyword;
- d->result_ += "[";
+ d->result_ += '[';
}
d->indentLevel_++;
d->stackHasChild_.push_back(false);
@@ -428,7 +428,7 @@ void WKTFormatter::endNode() {
d->stackEmptyKeyword_.pop_back();
d->stackHasChild_.pop_back();
if (!emptyKeyword)
- d->result_ += "]";
+ d->result_ += ']';
}
// ---------------------------------------------------------------------------
@@ -443,7 +443,7 @@ WKTFormatter &WKTFormatter::simulCurNodeHasId() {
void WKTFormatter::Private::startNewChild() {
assert(!stackHasChild_.empty());
if (stackHasChild_.back()) {
- result_ += ",";
+ result_ += ',';
}
stackHasChild_.back() = true;
}
@@ -456,9 +456,9 @@ void WKTFormatter::addQuotedString(const char *str) {
void WKTFormatter::addQuotedString(const std::string &str) {
d->startNewChild();
- d->result_ += "\"";
+ d->result_ += '"';
d->result_ += replaceAll(str, "\"", "\"\"");
- d->result_ += "\"";
+ d->result_ += '"';
}
// ---------------------------------------------------------------------------
@@ -719,6 +719,20 @@ std::string WKTFormatter::morphNameToESRI(const std::string &name) {
return ret;
}
+// ---------------------------------------------------------------------------
+
+void WKTFormatter::ingestWKTNode(const WKTNodeNNPtr &node) {
+ startNode(node->value(), true);
+ for (const auto &child : node->children()) {
+ if (!child->children().empty()) {
+ ingestWKTNode(child);
+ } else {
+ add(child->value());
+ }
+ }
+ endNode();
+}
+
#ifdef unused
// ---------------------------------------------------------------------------
@@ -991,7 +1005,7 @@ WKTNodeNNPtr WKTNode::createFrom(const std::string &wkt, size_t indexStart,
if (!inString) {
inString = true;
closingStringMarker = endPrintedQuote;
- value += "\"";
+ value += '"';
i += 2;
continue;
}
@@ -1000,7 +1014,7 @@ WKTNodeNNPtr WKTNode::createFrom(const std::string &wkt, size_t indexStart,
wkt.substr(i, 3) == endPrintedQuote) {
inString = false;
closingStringMarker.clear();
- value += "\"";
+ value += '"';
i += 2;
continue;
}
@@ -1038,6 +1052,10 @@ WKTNodeNNPtr WKTNode::createFrom(const std::string &wkt, size_t indexStart,
assert(indexEndChild > i);
i = indexEndChild;
i = skipSpace(wkt, i);
+ if (i < wkt.size() && wkt[i] == ',') {
+ ++i;
+ i = skipSpace(wkt, i);
+ }
}
if (i == wkt.size() || (wkt[i] != ']' && wkt[i] != ')')) {
throw ParsingException("missing ]");
@@ -1065,7 +1083,7 @@ static std::string escapeIfQuotedString(const std::string &str) {
if (str.size() > 2 && str[0] == '"' && str.back() == '"') {
std::string res("\"");
res += replaceAll(str.substr(1, str.size() - 2), "\"", "\"\"");
- res += "\"";
+ res += '"';
return res;
} else {
return str;
@@ -1084,7 +1102,7 @@ std::string WKTNode::toString() const {
bool first = true;
for (auto &child : d->children_) {
if (!first) {
- str += ",";
+ str += ',';
}
first = false;
str += child->toString();
@@ -1166,6 +1184,7 @@ struct WKTParser::Private {
MeridianNNPtr buildMeridian(const WKTNodeNNPtr &node);
CoordinateSystemAxisNNPtr buildAxis(const WKTNodeNNPtr &node,
const UnitOfMeasure &unitIn,
+ const UnitOfMeasure::Type &unitType,
bool isGeocentric,
int expectedOrderNum);
@@ -1198,8 +1217,8 @@ struct WKTParser::Private {
static bool hasWebMercPROJ4String(const WKTNodeNNPtr &projCRSNode,
const WKTNodeNNPtr &projectionNode);
- static bool projectionHasParameter(const WKTNodeNNPtr &projCRSNode,
- const char *paramName);
+ static std::string projectionGetParameter(const WKTNodeNNPtr &projCRSNode,
+ const char *paramName);
ConversionNNPtr buildProjection(const WKTNodeNNPtr &projCRSNode,
const WKTNodeNNPtr &projectionNode,
@@ -1924,6 +1943,37 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame(
.set(Identifier::AUTHORITY_KEY, authNameFromAlias)));
properties.set(IdentifiedObject::IDENTIFIERS_KEY, identifiers);
}
+ } else if (name.find('_') != std::string::npos) {
+ // Likely coming from WKT1
+ if (dbContext_) {
+ auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
+ std::string());
+ auto res = authFactory->createObjectsFromName(
+ name, {AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME},
+ true, 1);
+ if (!res.empty()) {
+ const auto &refDatum = res.front();
+ if (metadata::Identifier::isEquivalentName(
+ name.c_str(), refDatum->nameStr().c_str())) {
+ properties.set(IdentifiedObject::NAME_KEY,
+ refDatum->nameStr());
+ if (properties.find(Identifier::CODESPACE_KEY) ==
+ properties.end() &&
+ refDatum->identifiers().size() == 1) {
+ const auto &id = refDatum->identifiers()[0];
+ auto identifiers = ArrayOfBaseObject::create();
+ identifiers->add(Identifier::create(
+ id->code(), PropertyMap()
+ .set(Identifier::CODESPACE_KEY,
+ *id->codeSpace())
+ .set(Identifier::AUTHORITY_KEY,
+ *id->codeSpace())));
+ properties.set(IdentifiedObject::IDENTIFIERS_KEY,
+ identifiers);
+ }
+ }
+ }
+ }
}
auto ellipsoid = buildEllipsoid(ellipsoidNode);
@@ -2039,10 +2089,17 @@ MeridianNNPtr WKTParser::Private::buildMeridian(const WKTNodeNNPtr &node) {
// ---------------------------------------------------------------------------
+PROJ_NO_RETURN static void ThrowParsingExceptionMissingUNIT() {
+ throw ParsingException("buildCS: missing UNIT");
+}
+
+// ---------------------------------------------------------------------------
+
CoordinateSystemAxisNNPtr
WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
- const UnitOfMeasure &unitIn, bool isGeocentric,
- int expectedOrderNum) {
+ const UnitOfMeasure &unitIn,
+ const UnitOfMeasure::Type &unitType,
+ bool isGeocentric, int expectedOrderNum) {
const auto *nodeP = node->GP();
const auto &children = nodeP->children();
if (children.size() < 2) {
@@ -2128,7 +2185,8 @@ WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
abbreviation = AxisAbbreviation::Y;
direction = &AxisDirection::GEOCENTRIC_Y;
} else if (isGeocentric && axisName == AxisName::Geocentric_Z &&
- dirString == AxisDirectionWKT1::NORTH.toString()) {
+ (dirString == AxisDirectionWKT1::NORTH.toString() ||
+ dirString == AxisDirectionWKT1::OTHER.toString())) {
abbreviation = AxisAbbreviation::Z;
direction = &AxisDirection::GEOCENTRIC_Z;
} else if (dirString == AxisDirectionWKT1::OTHER.toString()) {
@@ -2146,6 +2204,11 @@ WKTParser::Private::buildAxis(const WKTNodeNNPtr &node,
// If no unit in the AXIS node, use the one potentially coming from
// the CS.
unit = unitIn;
+ if (unit == UnitOfMeasure::NONE &&
+ unitType != UnitOfMeasure::Type::NONE &&
+ unitType != UnitOfMeasure::Type::TIME) {
+ ThrowParsingExceptionMissingUNIT();
+ }
}
auto &meridianNode = nodeP->lookForChild(WKTConstants::MERIDIAN);
@@ -2165,10 +2228,6 @@ PROJ_NO_RETURN static void ThrowParsingException(const std::string &msg) {
throw ParsingException(msg);
}
-PROJ_NO_RETURN static void ThrowParsingExceptionMissingUNIT() {
- throw ParsingException("buildCS: missing UNIT");
-}
-
static ParsingException
buildParsingExceptionInvalidAxisCount(const std::string &csType) {
return ParsingException(
@@ -2331,8 +2390,7 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */
"and number of AXIS are inconsistent");
}
- UnitOfMeasure unit = buildUnitInSubNode(
- parentNode,
+ const auto unitType =
ci_equal(csType, "ellipsoidal")
? UnitOfMeasure::Type::ANGULAR
: ci_equal(csType, "ordinal")
@@ -2347,13 +2405,14 @@ WKTParser::Private::buildCS(const WKTNodeNNPtr &node, /* maybe null */
ci_equal(csType, "TemporalCount") ||
ci_equal(csType, "TemporalMeasure"))
? UnitOfMeasure::Type::TIME
- : UnitOfMeasure::Type::UNKNOWN);
+ : UnitOfMeasure::Type::UNKNOWN;
+ UnitOfMeasure unit = buildUnitInSubNode(parentNode, unitType);
std::vector<CoordinateSystemAxisNNPtr> axisList;
for (int i = 0; i < axisCount; i++) {
axisList.emplace_back(
buildAxis(parentNode->GP()->lookForChild(WKTConstants::AXIS, i),
- unit, isGeocentric, i + 1));
+ unit, unitType, isGeocentric, i + 1));
};
const PropertyMap &csMap = emptyPropertyMap;
@@ -2476,6 +2535,11 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) {
auto props = buildProperties(node);
addExtensionProj4ToProp(nodeP, props);
+ // No explicit AXIS node ? (WKT1)
+ if (isNull(nodeP->lookForChild(WKTConstants::AXIS))) {
+ props.set("IMPLICIT_CS", true);
+ }
+
auto datum =
!isNull(datumNode)
? buildGeodeticReferenceFrame(datumNode, primeMeridian, dynamicNode)
@@ -2819,7 +2883,7 @@ bool WKTParser::Private::hasWebMercPROJ4String(
projCRSNode->countChildrenOfName("center_latitude") == 0) {
// Hack to detect the hacky way of encodign webmerc in GDAL WKT1
- // with a EXTENSION["PROJ", "+proj=merc +a=6378137 +b=6378137
+ // with a EXTENSION["PROJ4", "+proj=merc +a=6378137 +b=6378137
// +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m
// +nadgrids=@null +wktext +no_defs"] node
if (extensionNode && extensionNode->GP()->childrenSize() == 2 &&
@@ -3034,19 +3098,20 @@ WKTParser::Private::buildProjection(const WKTNodeNNPtr &projCRSNode,
// ---------------------------------------------------------------------------
-bool WKTParser::Private::projectionHasParameter(const WKTNodeNNPtr &projCRSNode,
- const char *paramName) {
+std::string
+WKTParser::Private::projectionGetParameter(const WKTNodeNNPtr &projCRSNode,
+ const char *paramName) {
for (const auto &childNode : projCRSNode->GP()->children()) {
if (ci_equal(childNode->GP()->value(), WKTConstants::PARAMETER)) {
const auto &childNodeChildren = childNode->GP()->children();
if (childNodeChildren.size() == 2 &&
metadata::Identifier::isEquivalentName(
stripQuotes(childNodeChildren[0]).c_str(), paramName)) {
- return true;
+ return childNodeChildren[1]->GP()->value();
}
}
}
- return false;
+ return std::string();
}
// ---------------------------------------------------------------------------
@@ -3068,10 +3133,12 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
bool gdal_3026_hack = false;
if (metadata::Identifier::isEquivalentName(wkt1ProjectionName.c_str(),
"Mercator_1SP") &&
- !projectionHasParameter(projCRSNode, "center_latitude")) {
+ projectionGetParameter(projCRSNode, "center_latitude").empty()) {
// Hack for https://trac.osgeo.org/gdal/ticket/3026
- if (projectionHasParameter(projCRSNode, "latitude_of_origin")) {
+ std::string lat0(
+ projectionGetParameter(projCRSNode, "latitude_of_origin"));
+ if (!lat0.empty() && lat0 != "0" && lat0 != "0.0") {
wkt1ProjectionName = "Mercator_2SP";
gdal_3026_hack = true;
} else {
@@ -3173,11 +3240,11 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
projCRSNode->countChildrenOfName(WKTConstants::AXIS) == 2 &&
&buildAxis(
projCRSNode->GP()->lookForChild(WKTConstants::AXIS, 0),
- defaultLinearUnit, false,
+ defaultLinearUnit, UnitOfMeasure::Type::LINEAR, false,
1)->direction() == &AxisDirection::SOUTH &&
&buildAxis(
projCRSNode->GP()->lookForChild(WKTConstants::AXIS, 1),
- defaultLinearUnit, false,
+ defaultLinearUnit, UnitOfMeasure::Type::LINEAR, false,
2)->direction() == &AxisDirection::WEST) {
mapping = getMapping(EPSG_CODE_METHOD_KROVAK);
}
@@ -3255,6 +3322,17 @@ ConversionNNPtr WKTParser::Private::buildProjectionStandard(
// ---------------------------------------------------------------------------
+static ProjectedCRSNNPtr createPseudoMercator(const PropertyMap &props) {
+ auto conversion = Conversion::createPopularVisualisationPseudoMercator(
+ PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), Angle(0),
+ Angle(0), Length(0), Length(0));
+ return ProjectedCRS::create(
+ props, GeographicCRS::EPSG_4326, conversion,
+ CartesianCS::createEastingNorthing(UnitOfMeasure::METRE));
+}
+
+// ---------------------------------------------------------------------------
+
ProjectedCRSNNPtr
WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
@@ -3264,16 +3342,6 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
if (isNull(conversionNode) && isNull(projectionNode)) {
ThrowMissing(WKTConstants::CONVERSION);
}
- if (isNull(conversionNode) && hasWebMercPROJ4String(node, projectionNode)) {
- auto conversion = Conversion::createPopularVisualisationPseudoMercator(
- PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), Angle(0),
- Angle(0), Length(0), Length(0));
- return ProjectedCRS::create(
- PropertyMap().set(IdentifiedObject::NAME_KEY,
- "WGS 84 / Pseudo-Mercator"),
- GeographicCRS::EPSG_4326, conversion,
- CartesianCS::createEastingNorthing(UnitOfMeasure::METRE));
- }
auto &baseGeodCRSNode =
nodeP->lookForChild(WKTConstants::BASEGEODCRS,
@@ -3284,6 +3352,50 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
}
auto baseGeodCRS = buildGeodeticCRS(baseGeodCRSNode);
+ auto props = buildProperties(node);
+
+ const std::string projCRSName = stripQuotes(nodeP->children()[0]);
+ if (esriStyle_ && dbContext_) {
+ // It is likely that the ESRI definition of EPSG:32661 (UPS North) &
+ // EPSG:32761 (UPS South) uses the easting-northing order, instead
+ // of the EPSG northing-easting order
+ // so don't substitue names to avoid confusion.
+ if (projCRSName == "UPS_North") {
+ props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS North (E,N)");
+ } else if (projCRSName == "UPS_South") {
+ props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS South (E,N)");
+ } else {
+ std::string outTableName;
+ std::string authNameFromAlias;
+ std::string codeFromAlias;
+ auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
+ std::string());
+ auto officialName = authFactory->getOfficialNameFromAlias(
+ projCRSName, "projected_crs", "ESRI", outTableName,
+ authNameFromAlias, codeFromAlias);
+ if (!officialName.empty()) {
+ props.set(IdentifiedObject::NAME_KEY, officialName);
+ }
+ }
+ }
+
+ if (isNull(conversionNode) && hasWebMercPROJ4String(node, projectionNode)) {
+ toWGS84Parameters_.clear();
+ return createPseudoMercator(props);
+ }
+
+ // WGS_84_Pseudo_Mercator: Particular case for corrupted ESRI WKT generated
+ // by older GDAL versions
+ // https://trac.osgeo.org/gdal/changeset/30732
+ // WGS_1984_Web_Mercator: deprecated ESRI:102113
+ if (metadata::Identifier::isEquivalentName(projCRSName.c_str(),
+ "WGS_84_Pseudo_Mercator") ||
+ metadata::Identifier::isEquivalentName(projCRSName.c_str(),
+ "WGS_1984_Web_Mercator")) {
+ toWGS84Parameters_.clear();
+ return createPseudoMercator(props);
+ }
+
auto linearUnit = buildUnitInSubNode(node, UnitOfMeasure::Type::LINEAR);
auto angularUnit = baseGeodCRS->coordinateSystem()->axisList()[0]->unit();
@@ -3301,6 +3413,11 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
auto cs = buildCS(csNode, node, UnitOfMeasure::NONE);
auto cartesianCS = nn_dynamic_pointer_cast<CartesianCS>(cs);
+ // No explicit AXIS node ? (WKT1)
+ if (isNull(nodeP->lookForChild(WKTConstants::AXIS))) {
+ props.set("IMPLICIT_CS", true);
+ }
+
if (isNull(csNode) && node->countChildrenOfName(WKTConstants::AXIS) == 0) {
const auto methodCode = conversion->method()->getEPSGCode();
// Krovak south oriented ?
@@ -3367,33 +3484,6 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) {
ThrowNotExpectedCSType("Cartesian");
}
- auto props = buildProperties(node);
- if (esriStyle_ && dbContext_) {
- auto projCRSName = stripQuotes(nodeP->children()[0]);
-
- // It is likely that the ESRI definition of EPSG:32661 (UPS North) &
- // EPSG:32761 (UPS South) uses the easting-northing order, instead
- // of the EPSG northing-easting order
- // so don't substitue names to avoid confusion.
- if (projCRSName == "UPS_North") {
- props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS North (E,N)");
- } else if (projCRSName == "UPS_South") {
- props.set(IdentifiedObject::NAME_KEY, "WGS 84 / UPS South (E,N)");
- } else {
- std::string outTableName;
- std::string authNameFromAlias;
- std::string codeFromAlias;
- auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_),
- std::string());
- auto officialName = authFactory->getOfficialNameFromAlias(
- projCRSName, "projected_crs", "ESRI", outTableName,
- authNameFromAlias, codeFromAlias);
- if (!officialName.empty()) {
- props.set(IdentifiedObject::NAME_KEY, officialName);
- }
- }
- }
-
addExtensionProj4ToProp(nodeP, props);
return ProjectedCRS::create(props, baseGeodCRS, conversion,
@@ -4066,10 +4156,22 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) {
* determine the appropriate best match.</li>
* </ul>
*
+ * @param text One of the above mentionned text format
+ * @param dbContext Database context, or nullptr (in which case database
+ * lookups will not work)
+ * @param usePROJ4InitRules When set to true,
+ * init=epsg:XXXX syntax will be allowed and will be interpreted according to
+ * PROJ.4 and PROJ.5 rules, that is geodeticCRS will have longitude, latitude
+ * order and will expect/output coordinates in radians. ProjectedCRS will have
+ * easting, northing axis order (except the ones with Transverse Mercator South
+ * Orientated projection). In that mode, the epsg:XXXX syntax will be also
+ * interprated the same way.
* @throw ParsingException
*/
BaseObjectNNPtr createFromUserInput(const std::string &text,
- const DatabaseContextPtr &dbContext) {
+ const DatabaseContextPtr &dbContext,
+ bool usePROJ4InitRules) {
+
for (const auto &wktConstants : WKTConstants::constants()) {
if (ci_starts_with(text, wktConstants)) {
return WKTParser().attachDatabaseContext(dbContext).createFromWKT(
@@ -4085,6 +4187,7 @@ BaseObjectNNPtr createFromUserInput(const std::string &text,
strncmp(textWithoutPlusPrefix, "title=", strlen("title=")) == 0) {
return PROJStringParser()
.attachDatabaseContext(dbContext)
+ .setUsePROJ4InitRules(usePROJ4InitRules)
.createFromPROJString(text);
}
@@ -4093,9 +4196,23 @@ BaseObjectNNPtr createFromUserInput(const std::string &text,
if (!dbContext) {
throw ParsingException("no database context specified");
}
- auto factory =
- AuthorityFactory::create(NN_NO_CHECK(dbContext), tokens[0]);
- return factory->createCoordinateReferenceSystem(tokens[1]);
+ DatabaseContextNNPtr dbContextNNPtr(NN_NO_CHECK(dbContext));
+ const auto &authName = tokens[0];
+ const auto &code = tokens[1];
+ auto factory = AuthorityFactory::create(dbContextNNPtr, authName);
+ try {
+ return factory->createCoordinateReferenceSystem(code);
+ } catch (...) {
+ const auto authorities = dbContextNNPtr->getAuthorities();
+ for (const auto &authCandidate : authorities) {
+ if (ci_equal(authCandidate, authName)) {
+ return AuthorityFactory::create(dbContextNNPtr,
+ authCandidate)
+ ->createCoordinateReferenceSystem(code);
+ }
+ }
+ throw;
+ }
}
// urn:ogc:def:crs:EPSG::4326
@@ -4395,6 +4512,7 @@ struct PROJStringFormatter::Private {
bool useETMercForTMerc_ = false;
bool useETMercForTMercSet_ = false;
bool addNoDefs_ = true;
+ bool coordOperationOptimizations_ = false;
std::string result_{};
@@ -4477,6 +4595,12 @@ const std::string &PROJStringFormatter::toString() const {
step.paramValues[6].equals("s", "0") &&
step.paramValues[7].keyEquals("convention")))) {
iter = d->steps_.erase(iter);
+ } else if (d->coordOperationOptimizations_ &&
+ step.name == "unitconvert" && paramCount == 2 &&
+ step.paramValues[0].keyEquals("xy_in") &&
+ step.paramValues[1].keyEquals("xy_out") &&
+ step.paramValues[0].value == step.paramValues[1].value) {
+ iter = d->steps_.erase(iter);
} else {
++iter;
}
@@ -4694,6 +4818,24 @@ const std::string &PROJStringFormatter::toString() const {
break;
}
+ // axisswap order=2,1, unitconvert, axisswap order=2,1 -> can
+ // suppress axisswap
+ if (i + 1 < d->steps_.size() && prevStep.name == "axisswap" &&
+ curStep.name == "unitconvert" && prevStepParamCount == 1 &&
+ prevStep.paramValues[0].equals("order", "2,1")) {
+ auto iterNext = iterCur;
+ ++iterNext;
+ auto &nextStep = *iterNext;
+ if (nextStep.name == "axisswap" &&
+ nextStep.paramValues.size() == 1 &&
+ nextStep.paramValues[0].equals("order", "2,1")) {
+ d->steps_.erase(iterPrev);
+ d->steps_.erase(iterNext);
+ changeDone = true;
+ break;
+ }
+ }
+
// for practical purposes WGS84 and GRS80 ellipsoids are
// equivalents (cartesian transform between both lead to differences
// of the order of 1e-14 deg..).
@@ -4880,6 +5022,12 @@ bool PROJStringFormatter::getUseETMercForTMerc(bool &settingSetOut) const {
// ---------------------------------------------------------------------------
+void PROJStringFormatter::setCoordinateOperationOptimizations(bool enable) {
+ d->coordOperationOptimizations_ = enable;
+}
+
+// ---------------------------------------------------------------------------
+
void PROJStringFormatter::Private::appendToResult(const char *str) {
if (!result_.empty()) {
result_ += " ";
@@ -4939,11 +5087,13 @@ PROJStringSyntaxParser(const std::string &projString, std::vector<Step> &steps,
}
prevWasStep = false;
} else if (starts_with(word, "proj=")) {
+ auto stepName = word.substr(strlen("proj="));
if (prevWasInit) {
- throw ParsingException("+init= found at unexpected place");
+ steps.back() = Step();
+ prevWasInit = false;
+ } else {
+ steps.push_back(Step());
}
- auto stepName = word.substr(strlen("proj="));
- steps.push_back(Step());
steps.back().name = stepName;
steps.back().inverted = inverted;
prevWasStep = false;
@@ -4996,7 +5146,7 @@ void PROJStringFormatter::ingestPROJString(
std::string vto_meter;
PROJStringSyntaxParser(str, steps, d->globalParamValues_, title, vunits,
vto_meter);
- d->steps_.insert(d->steps_.begin(), steps.begin(), steps.end());
+ d->steps_.insert(d->steps_.end(), steps.begin(), steps.end());
}
// ---------------------------------------------------------------------------
@@ -5137,7 +5287,7 @@ void PROJStringFormatter::addParam(const char *paramName,
std::string paramValue;
for (size_t i = 0; i < vals.size(); ++i) {
if (i > 0) {
- paramValue += ",";
+ paramValue += ',';
}
paramValue += formatToString(vals[i]);
}
@@ -5261,6 +5411,7 @@ const DatabaseContextPtr &PROJStringFormatter::databaseContext() const {
struct PROJStringParser::Private {
DatabaseContextPtr dbContext_{};
+ bool usePROJ4InitRules_ = false;
std::vector<std::string> warningList_{};
std::string projString_{};
@@ -5368,6 +5519,22 @@ PROJStringParser::attachDatabaseContext(const DatabaseContextPtr &dbContext) {
// ---------------------------------------------------------------------------
+/** \brief Set how init=epsg:XXXX syntax should be interpreted.
+ *
+ * @param enable When set to true,
+ * init=epsg:XXXX syntax will be allowed and will be interpreted according to
+ * PROJ.4 and PROJ.5 rules, that is geodeticCRS will have longitude, latitude
+ * order and will expect/output coordinates in radians. ProjectedCRS will have
+ * easting, northing axis order (except the ones with Transverse Mercator South
+ * Orientated projection).
+ */
+PROJStringParser &PROJStringParser::setUsePROJ4InitRules(bool enable) {
+ d->usePROJ4InitRules_ = enable;
+ return *this;
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the list of warnings found during parsing.
*/
std::vector<std::string> PROJStringParser::warningList() const {
@@ -5571,11 +5738,12 @@ PROJStringParser::Private::buildPrimeMeridian(const Step &step) {
PrimeMeridianNNPtr pm = PrimeMeridian::GREENWICH;
const auto &pmStr = getParamValue(step, "pm");
if (!pmStr.empty()) {
- try {
- double pmValue = c_locale_stod(pmStr);
+ char *end;
+ double pmValue = dmstor(pmStr.c_str(), &end) * RAD_TO_DEG;
+ if (pmValue != HUGE_VAL && *end == '\0') {
pm = PrimeMeridian::create(createMapWithUnknownName(),
Angle(pmValue));
- } catch (const std::invalid_argument &) {
+ } else {
bool found = false;
if (pmStr == "paris") {
found = true;
@@ -5588,9 +5756,8 @@ PROJStringParser::Private::buildPrimeMeridian(const Step &step) {
found = true;
std::string name = static_cast<char>(::toupper(pmStr[0])) +
pmStr.substr(1);
- double pmValue =
- dmstor(proj_prime_meridians[i].defn, nullptr) *
- RAD_TO_DEG;
+ pmValue = dmstor(proj_prime_meridians[i].defn, nullptr) *
+ RAD_TO_DEG;
pm = PrimeMeridian::create(
PropertyMap().set(IdentifiedObject::NAME_KEY, name),
Angle(pmValue));
@@ -5619,12 +5786,20 @@ PROJStringParser::Private::buildDatum(const Step &step,
const auto &ellpsStr = getParamValue(step, "ellps");
const auto &datumStr = getParamValue(step, "datum");
+ const auto &RStr = getParamValue(step, "R");
const auto &aStr = getParamValue(step, "a");
const auto &bStr = getParamValue(step, "b");
const auto &rfStr = getParamValue(step, "rf");
const auto &fStr = getParamValue(step, "f");
- const auto &RStr = getParamValue(step, "R");
+ const auto &esStr = getParamValue(step, "es");
+ const auto &eStr = getParamValue(step, "e");
+ double a = -1.0;
+ double b = -1.0;
+ double rf = -1.0;
const util::optional<std::string> optionalEmptyString{};
+ const bool numericParamPresent =
+ !RStr.empty() || !aStr.empty() || !bStr.empty() || !rfStr.empty() ||
+ !fStr.empty() || !esStr.empty() || !eStr.empty();
PrimeMeridianNNPtr pm(buildPrimeMeridian(step));
PropertyMap grfMap;
@@ -5647,104 +5822,151 @@ PROJStringParser::Private::buildDatum(const Step &step,
}
};
+ // R take precedence
+ if (!RStr.empty()) {
+ double R;
+ try {
+ R = c_locale_stod(RStr);
+ } catch (const std::invalid_argument &) {
+ throw ParsingException("Invalid R value");
+ }
+ auto ellipsoid = Ellipsoid::createSphere(createMapWithUnknownName(),
+ Length(R), guessBodyName(R));
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty() ? "unknown" : title.c_str()),
+ ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
+ }
+
if (!datumStr.empty()) {
- if (datumStr == "WGS84") {
- return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6326);
- } else if (datumStr == "NAD83") {
- return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6269);
- } else if (datumStr == "NAD27") {
- return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6267);
- } else {
+ auto l_datum = [&datumStr, &overridePmIfNeeded, &grfMap,
+ &optionalEmptyString, &pm]() {
+ if (datumStr == "WGS84") {
+ return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6326);
+ } else if (datumStr == "NAD83") {
+ return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6269);
+ } else if (datumStr == "NAD27") {
+ return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6267);
+ } else {
- for (const auto &datumDesc : datumDescs) {
- if (datumStr == datumDesc.projName) {
- (void)datumDesc.gcsName; // to please cppcheck
- (void)datumDesc.gcsCode; // to please cppcheck
- auto ellipsoid = Ellipsoid::createFlattenedSphere(
- grfMap
- .set(IdentifiedObject::NAME_KEY,
- datumDesc.ellipsoidName)
- .set(Identifier::CODESPACE_KEY, Identifier::EPSG)
- .set(Identifier::CODE_KEY, datumDesc.ellipsoidCode),
- Length(datumDesc.a), Scale(datumDesc.rf));
- return GeodeticReferenceFrame::create(
- grfMap
- .set(IdentifiedObject::NAME_KEY,
- datumDesc.datumName)
- .set(Identifier::CODESPACE_KEY, Identifier::EPSG)
- .set(Identifier::CODE_KEY, datumDesc.datumCode),
- ellipsoid, optionalEmptyString, pm);
+ for (const auto &datumDesc : datumDescs) {
+ if (datumStr == datumDesc.projName) {
+ (void)datumDesc.gcsName; // to please cppcheck
+ (void)datumDesc.gcsCode; // to please cppcheck
+ auto ellipsoid = Ellipsoid::createFlattenedSphere(
+ grfMap
+ .set(IdentifiedObject::NAME_KEY,
+ datumDesc.ellipsoidName)
+ .set(Identifier::CODESPACE_KEY,
+ Identifier::EPSG)
+ .set(Identifier::CODE_KEY,
+ datumDesc.ellipsoidCode),
+ Length(datumDesc.a), Scale(datumDesc.rf));
+ return GeodeticReferenceFrame::create(
+ grfMap
+ .set(IdentifiedObject::NAME_KEY,
+ datumDesc.datumName)
+ .set(Identifier::CODESPACE_KEY,
+ Identifier::EPSG)
+ .set(Identifier::CODE_KEY, datumDesc.datumCode),
+ ellipsoid, optionalEmptyString, pm);
+ }
}
}
+ throw ParsingException("unknown datum " + datumStr);
+ }();
+ if (!numericParamPresent) {
+ return l_datum;
}
- throw ParsingException("unknown datum " + datumStr);
+ a = l_datum->ellipsoid()->semiMajorAxis().getSIValue();
+ rf = l_datum->ellipsoid()->computedInverseFlattening();
}
else if (!ellpsStr.empty()) {
- if (ellpsStr == "WGS84") {
- return GeodeticReferenceFrame::create(
- grfMap.set(IdentifiedObject::NAME_KEY,
- title.empty() ? "Unknown based on WGS84 ellipsoid"
- : title.c_str()),
- Ellipsoid::WGS84, optionalEmptyString, pm);
- } else if (ellpsStr == "GRS80") {
- return GeodeticReferenceFrame::create(
- grfMap.set(IdentifiedObject::NAME_KEY,
- title.empty() ? "Unknown based on GRS80 ellipsoid"
- : title.c_str()),
- Ellipsoid::GRS1980, optionalEmptyString, pm);
- } else {
- auto proj_ellps = proj_list_ellps();
- for (int i = 0; proj_ellps[i].id != nullptr; i++) {
- if (ellpsStr == proj_ellps[i].id) {
- assert(strncmp(proj_ellps[i].major, "a=", 2) == 0);
- const double a_iter =
- c_locale_stod(proj_ellps[i].major + 2);
- EllipsoidPtr ellipsoid;
- PropertyMap ellpsMap;
- if (strncmp(proj_ellps[i].ell, "b=", 2) == 0) {
- const double b_iter =
- c_locale_stod(proj_ellps[i].ell + 2);
- ellipsoid = Ellipsoid::createTwoAxis(
- ellpsMap.set(IdentifiedObject::NAME_KEY,
- proj_ellps[i].name),
- Length(a_iter), Length(b_iter))
- .as_nullable();
- } else {
- assert(strncmp(proj_ellps[i].ell, "rf=", 3) == 0);
- const double rf_iter =
- c_locale_stod(proj_ellps[i].ell + 3);
- ellipsoid = Ellipsoid::createFlattenedSphere(
- ellpsMap.set(IdentifiedObject::NAME_KEY,
- proj_ellps[i].name),
- Length(a_iter), Scale(rf_iter))
- .as_nullable();
+ auto l_datum = [&ellpsStr, &title, &grfMap, &optionalEmptyString,
+ &pm]() {
+ if (ellpsStr == "WGS84") {
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty()
+ ? "Unknown based on WGS84 ellipsoid"
+ : title.c_str()),
+ Ellipsoid::WGS84, optionalEmptyString, pm);
+ } else if (ellpsStr == "GRS80") {
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty()
+ ? "Unknown based on GRS80 ellipsoid"
+ : title.c_str()),
+ Ellipsoid::GRS1980, optionalEmptyString, pm);
+ } else {
+ auto proj_ellps = proj_list_ellps();
+ for (int i = 0; proj_ellps[i].id != nullptr; i++) {
+ if (ellpsStr == proj_ellps[i].id) {
+ assert(strncmp(proj_ellps[i].major, "a=", 2) == 0);
+ const double a_iter =
+ c_locale_stod(proj_ellps[i].major + 2);
+ EllipsoidPtr ellipsoid;
+ PropertyMap ellpsMap;
+ if (strncmp(proj_ellps[i].ell, "b=", 2) == 0) {
+ const double b_iter =
+ c_locale_stod(proj_ellps[i].ell + 2);
+ ellipsoid =
+ Ellipsoid::createTwoAxis(
+ ellpsMap.set(IdentifiedObject::NAME_KEY,
+ proj_ellps[i].name),
+ Length(a_iter), Length(b_iter))
+ .as_nullable();
+ } else {
+ assert(strncmp(proj_ellps[i].ell, "rf=", 3) == 0);
+ const double rf_iter =
+ c_locale_stod(proj_ellps[i].ell + 3);
+ ellipsoid =
+ Ellipsoid::createFlattenedSphere(
+ ellpsMap.set(IdentifiedObject::NAME_KEY,
+ proj_ellps[i].name),
+ Length(a_iter), Scale(rf_iter))
+ .as_nullable();
+ }
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty()
+ ? std::string("Unknown based on ") +
+ proj_ellps[i].name +
+ " ellipsoid"
+ : title),
+ NN_NO_CHECK(ellipsoid), optionalEmptyString, pm);
}
- return GeodeticReferenceFrame::create(
- grfMap.set(IdentifiedObject::NAME_KEY,
- title.empty()
- ? std::string("Unknown based on ") +
- proj_ellps[i].name + " ellipsoid"
- : title),
- NN_NO_CHECK(ellipsoid), optionalEmptyString, pm);
}
+ throw ParsingException("unknown ellipsoid " + ellpsStr);
}
- throw ParsingException("unknown ellipsoid " + ellpsStr);
+ }();
+ if (!numericParamPresent) {
+ return l_datum;
+ }
+ a = l_datum->ellipsoid()->semiMajorAxis().getSIValue();
+ if (l_datum->ellipsoid()->semiMinorAxis().has_value()) {
+ b = l_datum->ellipsoid()->semiMinorAxis()->getSIValue();
+ } else {
+ rf = l_datum->ellipsoid()->computedInverseFlattening();
}
}
- else if (!aStr.empty() && !bStr.empty()) {
- double a;
+ if (!aStr.empty()) {
try {
a = c_locale_stod(aStr);
} catch (const std::invalid_argument &) {
throw ParsingException("Invalid a value");
}
- double b;
- try {
- b = c_locale_stod(bStr);
- } catch (const std::invalid_argument &) {
- throw ParsingException("Invalid b value");
+ }
+
+ if (a > 0 && (b > 0 || !bStr.empty())) {
+ if (!bStr.empty()) {
+ try {
+ b = c_locale_stod(bStr);
+ } catch (const std::invalid_argument &) {
+ throw ParsingException("Invalid b value");
+ }
}
auto ellipsoid =
Ellipsoid::createTwoAxis(createMapWithUnknownName(), Length(a),
@@ -5756,18 +5978,13 @@ PROJStringParser::Private::buildDatum(const Step &step,
ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
}
- else if (!aStr.empty() && !rfStr.empty()) {
- double a;
- try {
- a = c_locale_stod(aStr);
- } catch (const std::invalid_argument &) {
- throw ParsingException("Invalid a value");
- }
- double rf;
- try {
- rf = c_locale_stod(rfStr);
- } catch (const std::invalid_argument &) {
- throw ParsingException("Invalid rf value");
+ else if (a > 0 && (rf >= 0 || !rfStr.empty())) {
+ if (!rfStr.empty()) {
+ try {
+ rf = c_locale_stod(rfStr);
+ } catch (const std::invalid_argument &) {
+ throw ParsingException("Invalid rf value");
+ }
}
auto ellipsoid = Ellipsoid::createFlattenedSphere(
createMapWithUnknownName(), Length(a), Scale(rf),
@@ -5779,13 +5996,7 @@ PROJStringParser::Private::buildDatum(const Step &step,
ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
}
- else if (!aStr.empty() && !fStr.empty()) {
- double a;
- try {
- a = c_locale_stod(aStr);
- } catch (const std::invalid_argument &) {
- throw ParsingException("Invalid a value");
- }
+ else if (a > 0 && !fStr.empty()) {
double f;
try {
f = c_locale_stod(fStr);
@@ -5802,23 +6013,52 @@ PROJStringParser::Private::buildDatum(const Step &step,
ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
}
- else if (!RStr.empty()) {
- double R;
+ else if (a > 0 && !eStr.empty()) {
+ double e;
try {
- R = c_locale_stod(RStr);
+ e = c_locale_stod(eStr);
} catch (const std::invalid_argument &) {
- throw ParsingException("Invalid R value");
+ throw ParsingException("Invalid e value");
}
- auto ellipsoid = Ellipsoid::createSphere(createMapWithUnknownName(),
- Length(R), guessBodyName(R));
+ double alpha = asin(e); /* angular eccentricity */
+ double f = 1 - cos(alpha); /* = 1 - sqrt (1 - es); */
+ auto ellipsoid = Ellipsoid::createFlattenedSphere(
+ createMapWithUnknownName(), Length(a),
+ Scale(f != 0.0 ? 1.0 / f : 0.0), guessBodyName(a))
+ ->identify();
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty() ? "unknown" : title.c_str()),
+ ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
+ }
+
+ else if (a > 0 && !esStr.empty()) {
+ double es;
+ try {
+ es = c_locale_stod(esStr);
+ } catch (const std::invalid_argument &) {
+ throw ParsingException("Invalid es value");
+ }
+ double f = 1 - sqrt(1 - es);
+ auto ellipsoid = Ellipsoid::createFlattenedSphere(
+ createMapWithUnknownName(), Length(a),
+ Scale(f != 0.0 ? 1.0 / f : 0.0), guessBodyName(a))
+ ->identify();
return GeodeticReferenceFrame::create(
grfMap.set(IdentifiedObject::NAME_KEY,
title.empty() ? "unknown" : title.c_str()),
ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
}
- if (!aStr.empty() && bStr.empty() && rfStr.empty()) {
- throw ParsingException("a found, but b, f or rf missing");
+ // If only a is specified, create a sphere
+ if (a > 0 && bStr.empty() && rfStr.empty() && eStr.empty() &&
+ esStr.empty()) {
+ auto ellipsoid = Ellipsoid::createSphere(createMapWithUnknownName(),
+ Length(a), guessBodyName(a));
+ return GeodeticReferenceFrame::create(
+ grfMap.set(IdentifiedObject::NAME_KEY,
+ title.empty() ? "unknown" : title.c_str()),
+ ellipsoid, optionalEmptyString, fixupPrimeMeridan(ellipsoid, pm));
}
if (!bStr.empty() && aStr.empty()) {
@@ -5833,6 +6073,14 @@ PROJStringParser::Private::buildDatum(const Step &step,
throw ParsingException("f found, but a missing");
}
+ if (!eStr.empty() && aStr.empty()) {
+ throw ParsingException("e found, but a missing");
+ }
+
+ if (!esStr.empty() && aStr.empty()) {
+ throw ParsingException("es found, but a missing");
+ }
+
return overridePmIfNeeded(GeodeticReferenceFrame::EPSG_6326);
}
@@ -6002,6 +6250,22 @@ PROJStringParser::Private::buildEllipsoidalCS(int iStep, int iUnitConvert,
// ---------------------------------------------------------------------------
+static double getNumericValue(const std::string &paramValue,
+ bool *pHasError = nullptr) {
+ try {
+ double value = c_locale_stod(paramValue);
+ if (pHasError)
+ *pHasError = false;
+ return value;
+ } catch (const std::invalid_argument &) {
+ if (pHasError)
+ *pHasError = true;
+ return 0.0;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
GeographicCRSNNPtr
PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert,
int iAxisSwap, bool ignoreVUnits,
@@ -6015,7 +6279,10 @@ PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert,
auto props = PropertyMap().set(IdentifiedObject::NAME_KEY,
title.empty() ? "unknown" : title);
- if (l_isGeographicStep && hasParamValue(step, "wktext")) {
+ if (l_isGeographicStep &&
+ (hasParamValue(step, "wktext") ||
+ hasParamValue(step, "lon_wrap") | hasParamValue(step, "geoc") ||
+ getNumericValue(getParamValue(step, "lon_0")) != 0.0)) {
props.set("EXTENSION_PROJ4", projString_);
}
@@ -6152,22 +6419,6 @@ static double getAngularValue(const std::string &paramValue,
// ---------------------------------------------------------------------------
-static double getNumericValue(const std::string &paramValue,
- bool *pHasError = nullptr) {
- try {
- double value = c_locale_stod(paramValue);
- if (pHasError)
- *pHasError = false;
- return value;
- } catch (const std::invalid_argument &) {
- if (pHasError)
- *pHasError = true;
- return 0.0;
- }
-}
-
-// ---------------------------------------------------------------------------
-
CRSNNPtr PROJStringParser::Private::buildProjectedCRS(
int iStep, GeographicCRSNNPtr geogCRS, int iUnitConvert, int iAxisSwap) {
auto &step = steps_[iStep];
@@ -6223,7 +6474,10 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS(
mapping =
getMapping(PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_Y);
} else if (step.name == "omerc") {
- if (hasParamValue(step, "no_uoff") || hasParamValue(step, "no_off")) {
+ if (hasParamValue(step, "no_rot")) {
+ mapping = nullptr;
+ } else if (hasParamValue(step, "no_uoff") ||
+ hasParamValue(step, "no_off")) {
mapping =
getMapping(EPSG_CODE_METHOD_HOTINE_OBLIQUE_MERCATOR_VARIANT_A);
} else if (hasParamValue(step, "lat_1") &&
@@ -6777,6 +7031,21 @@ PROJStringParser::Private::buildMolodenskyTransformation(
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+static const metadata::ExtentPtr nullExtent{};
+
+static const metadata::ExtentPtr &getExtent(const crs::CRS *crs) {
+ const auto &domains = crs->domains();
+ if (!domains.empty()) {
+ return domains[0]->domainOfValidity();
+ }
+ return nullExtent;
+}
+
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
/** \brief Instanciate a sub-class of BaseObject from a PROJ string.
* @throw ParsingException
*/
@@ -6785,6 +7054,9 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
std::string vunits;
std::string vto_meter;
+ d->steps_.clear();
+ d->title_.clear();
+ d->globalParamValues_.clear();
d->projString_ = projString;
PROJStringSyntaxParser(projString, d->steps_, d->globalParamValues_,
d->title_, vunits, vto_meter);
@@ -6821,6 +7093,117 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
: -1));
}
+ // +init=xxxx:yyyy syntax
+ if (d->steps_.size() == 1 && d->steps_[0].isInit &&
+ d->steps_[0].paramValues.size() == 0) {
+
+ // Those used to come from a text init file
+ // We only support them in compatibility mode
+ const std::string &stepName = d->steps_[0].name;
+ if (ci_starts_with(stepName, "epsg:") ||
+ ci_starts_with(stepName, "IGNF:")) {
+ bool usePROJ4InitRules = d->usePROJ4InitRules_;
+ if (!usePROJ4InitRules) {
+ PJ_CONTEXT *ctx = proj_context_create();
+ if (ctx) {
+ usePROJ4InitRules = proj_context_get_use_proj4_init_rules(
+ ctx, FALSE) == TRUE;
+ proj_context_destroy(ctx);
+ }
+ }
+ if (!usePROJ4InitRules) {
+ throw ParsingException("init=epsg:/init=IGNF: syntax not "
+ "supported in non-PROJ4 emulation mode");
+ }
+
+ PJ_CONTEXT *ctx = proj_context_create();
+ char unused[256];
+ std::string initname(stepName);
+ initname.resize(initname.find(':'));
+ int file_found =
+ pj_find_file(ctx, initname.c_str(), unused, sizeof(unused));
+ proj_context_destroy(ctx);
+ if (!file_found) {
+ auto obj = createFromUserInput(stepName, d->dbContext_, true);
+ auto crs = dynamic_cast<CRS *>(obj.get());
+ if (crs) {
+ PropertyMap properties;
+ properties.set(IdentifiedObject::NAME_KEY, crs->nameStr());
+ const auto &extent = getExtent(crs);
+ if (extent) {
+ properties.set(
+ common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ NN_NO_CHECK(extent));
+ }
+ auto geogCRS = dynamic_cast<GeographicCRS *>(crs);
+ if (geogCRS) {
+ // Override with longitude latitude in radian
+ return GeographicCRS::create(
+ properties, geogCRS->datum(),
+ geogCRS->datumEnsemble(),
+ EllipsoidalCS::createLongitudeLatitude(
+ UnitOfMeasure::RADIAN));
+ }
+ auto projCRS = dynamic_cast<ProjectedCRS *>(crs);
+ if (projCRS) {
+ // Override with easting northing order
+ const auto &conv = projCRS->derivingConversionRef();
+ if (conv->method()->getEPSGCode() !=
+ EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED) {
+ return ProjectedCRS::create(
+ properties, projCRS->baseCRS(), conv,
+ CartesianCS::createEastingNorthing(
+ projCRS->coordinateSystem()
+ ->axisList()[0]
+ ->unit()));
+ }
+ }
+ }
+ return obj;
+ }
+ }
+
+ paralist *init = pj_mkparam(("init=" + d->steps_[0].name).c_str());
+ if (!init) {
+ throw ParsingException("out of memory");
+ }
+ PJ_CONTEXT *ctx = proj_context_create();
+ if (!ctx) {
+ pj_dealloc(init);
+ throw ParsingException("out of memory");
+ }
+ paralist *list = pj_expand_init(ctx, init);
+ proj_context_destroy(ctx);
+ if (!list) {
+ pj_dealloc(init);
+ throw ParsingException("cannot expand " + projString);
+ }
+ std::string expanded;
+ bool first = true;
+ bool has_init_term = false;
+ for (auto t = list; t;) {
+ if (!expanded.empty()) {
+ expanded += ' ';
+ }
+ if (first) {
+ // first parameter is the init= itself
+ first = false;
+ } else if (starts_with(t->param, "init=")) {
+ has_init_term = true;
+ } else {
+ expanded += t->param;
+ }
+
+ auto n = t->next;
+ pj_dealloc(t);
+ t = n;
+ }
+
+ if (!has_init_term) {
+ return createFromPROJString(expanded);
+ }
+ }
+
int iFirstGeogStep = -1;
int iSecondGeogStep = -1;
int iProjStep = -1;
@@ -7003,6 +7386,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
throw ParsingException("out of memory");
}
proj_log_func(pj_context, &logger, Logger::log);
+ proj_context_use_proj4_init_rules(pj_context, d->usePROJ4InitRules_);
auto pj = proj_create(pj_context, projString.c_str());
bool valid = pj != nullptr;
proj_destroy(pj);
diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake
index 6fe84944..9e6f51fd 100644
--- a/src/lib_proj.cmake
+++ b/src/lib_proj.cmake
@@ -32,7 +32,7 @@ elseif(USE_THREAD AND NOT Threads_FOUND)
message(FATAL_ERROR "No thread library found and thread/mutex support is required by USE_THREAD option")
endif()
-option(ENABLE_LTO "Build library with LTO optimization (if available)." ON)
+option(ENABLE_LTO "Build library with LTO optimization (if available)." OFF)
if(ENABLE_LTO)
if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
include (CheckCXXSourceCompiles)
@@ -265,6 +265,7 @@ set(SRC_LIBPROJ_CPP
set(HEADERS_LIBPROJ
proj_api.h
proj.h
+ proj_experimental.h
proj_constants.h
geodesic.h
)
diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c
index 31e0124e..45ce5c8e 100644
--- a/src/pj_apply_gridshift.c
+++ b/src/pj_apply_gridshift.c
@@ -349,7 +349,7 @@ LP proj_hgrid_apply(PJ *P, LP lp, PJ_DIRECTION direction) {
out = nad_cvt(lp, inverse, ct);
if (out.lam == HUGE_VAL || out.phi == HUGE_VAL)
- pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
+ pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA);
return out;
diff --git a/src/pj_ctx.c b/src/pj_ctx.c
index 6626d5ee..1c99e921 100644
--- a/src/pj_ctx.c
+++ b/src/pj_ctx.c
@@ -85,6 +85,8 @@ projCtx pj_get_default_ctx()
default_context.app_data = NULL;
default_context.fileapi = pj_get_default_fileapi();
default_context.cpp_context = NULL;
+ default_context.use_proj4_init_rules = -1;
+ default_context.epsg_file_exists = -1;
if( getenv("PROJ_DEBUG") != NULL )
{
@@ -114,6 +116,7 @@ projCtx pj_ctx_alloc()
memcpy( ctx, pj_get_default_ctx(), sizeof(projCtx_t) );
ctx->last_errno = 0;
ctx->cpp_context = NULL;
+ ctx->use_proj4_init_rules = -1;
return ctx;
}
diff --git a/src/pj_fwd.c b/src/pj_fwd.c
index 1a970374..38443f07 100644
--- a/src/pj_fwd.c
+++ b/src/pj_fwd.c
@@ -103,7 +103,6 @@ static PJ_COORD fwd_prepare (PJ *P, PJ_COORD coo) {
}
-
static PJ_COORD fwd_finalize (PJ *P, PJ_COORD coo) {
switch (OUTPUT_UNITS) {
@@ -138,6 +137,14 @@ static PJ_COORD fwd_finalize (PJ *P, PJ_COORD coo) {
case PJ_IO_UNITS_ANGULAR:
coo.lpz.z = P->vfr_meter * (coo.lpz.z + P->z0);
+
+ if( P->is_long_wrap_set ) {
+ if( coo.lpz.lam != HUGE_VAL ) {
+ coo.lpz.lam = P->long_wrap_center +
+ adjlon(coo.lpz.lam - P->long_wrap_center);
+ }
+ }
+
break;
}
diff --git a/src/pj_init.c b/src/pj_init.c
index fcc03537..bc81235e 100644
--- a/src/pj_init.c
+++ b/src/pj_init.c
@@ -43,7 +43,6 @@
#include "projects.h"
-
/**************************************************************************************/
static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
/***************************************************************************************
@@ -81,14 +80,15 @@ static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
/**************************************************************************************/
-static char *get_init_string (PJ_CONTEXT *ctx, char *name) {
+static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
/***************************************************************************************
Read a section of an init file. Return its contents as a plain character string.
It is the duty of the caller to free the memory allocated for the string.
***************************************************************************************/
#define MAX_LINE_LENGTH 1000
size_t current_buffer_size = 5 * (MAX_LINE_LENGTH + 1);
- char *fname, *section, *key;
+ char *fname, *section;
+ const char *key;
char *buffer = 0;
char *line = 0;
PAFile fid;
@@ -228,11 +228,12 @@ static char *get_init_string (PJ_CONTEXT *ctx, char *name) {
/************************************************************************/
-static paralist *get_init(PJ_CONTEXT *ctx, char *key) {
+static paralist *get_init(PJ_CONTEXT *ctx, const char *key, int allow_init_epsg) {
/*************************************************************************
Expand key from buffer or (if not in buffer) from init file
*************************************************************************/
- char *xkey, *definition;
+ const char *xkey;
+ char *definition = 0;
paralist *init_items = 0;
/* support "init=file:section", "+init=file:section", and "file:section" format */
@@ -248,10 +249,68 @@ Expand key from buffer or (if not in buffer) from init file
if (init_items)
return init_items;
- /* If not, we must read it from file */
- pj_log (ctx, PJ_LOG_TRACE,
- "get_init: searching on in init files for [%s]", xkey);
- definition = get_init_string (ctx, xkey);
+ if( (strncmp(xkey, "epsg:", 5) == 0 || strncmp(xkey, "IGNF:", 5) == 0) ) {
+ char unused[256];
+ char initname[5];
+ int exists;
+
+ memcpy(initname, xkey, 4);
+ initname[4] = 0;
+
+ if( strncmp(xkey, "epsg:", 5) == 0 ) {
+ exists = ctx->epsg_file_exists;
+ if( exists < 0 ) {
+ exists = pj_find_file(ctx, initname, unused, sizeof(unused));
+ ctx->epsg_file_exists = exists;
+ }
+ } else {
+ exists = pj_find_file(ctx, initname, unused, sizeof(unused));
+ }
+
+ if( !exists ) {
+ const char* const optionsProj4Mode[] = { "USE_PROJ4_INIT_RULES=YES", NULL };
+ char szInitStr[7 + 64];
+ PJ_OBJ* src;
+ const char* proj_string;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ if( !allow_init_epsg ) {
+ pj_log (ctx, PJ_LOG_TRACE, "%s expansion disallowed", xkey);
+ return 0;
+ }
+ if( strlen(xkey) > 64 ) {
+ return 0;
+ }
+ strcpy(szInitStr, "+init=");
+ strcat(szInitStr, xkey);
+
+ src = proj_obj_create_from_user_input(ctx, szInitStr, optionsProj4Mode);
+ if( !src ) {
+ return 0;
+ }
+
+ proj_string = proj_obj_as_proj_string(ctx, src, PJ_PROJ_4, NULL);
+ if( !proj_string ) {
+ proj_obj_unref(src);
+ return 0;
+ }
+ definition = (char*)calloc(1, strlen(proj_string)+1);
+ if( definition ) {
+ strcpy(definition, proj_string);
+ }
+
+ proj_obj_unref(src);
+ }
+ }
+
+ if( !definition ) {
+ /* If not, we must read it from file */
+ pj_log (ctx, PJ_LOG_TRACE,
+ "get_init: searching on in init files for [%s]", xkey);
+ definition = get_init_string (ctx, xkey);
+ }
+
if (0==definition)
return 0;
init_items = string_to_paralist (ctx, definition);
@@ -271,7 +330,7 @@ Expand key from buffer or (if not in buffer) from init file
-static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, char *key) {
+static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, const char *key, int allow_init_epsg) {
paralist *defaults, *last = 0;
char keystring[ID_TAG_MAX + 20];
paralist *next, *proj;
@@ -303,7 +362,7 @@ static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start,
strcpy (keystring, "proj_def.dat:");
strcat (keystring, key);
- defaults = get_init (ctx, keystring);
+ defaults = get_init (ctx, keystring, allow_init_epsg);
/* Defaults are optional - so we don't care if we cannot open the file */
pj_ctx_set_errno (ctx, err);
@@ -340,7 +399,7 @@ static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start,
}
/*****************************************************************************/
-paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) {
+static paralist *pj_expand_init_internal(PJ_CONTEXT *ctx, paralist *init, int allow_init_epsg) {
/******************************************************************************
Append expansion of <key> to the paralist <init>. The expansion is appended,
rather than inserted at <init>'s place, since <init> may contain
@@ -367,7 +426,7 @@ Note that 'init=foo:bar' stays in the list. It is ignored after expansion.
if (0==init)
return 0;
- expn = get_init(ctx, init->param);
+ expn = get_init(ctx, init->param, allow_init_epsg);
/* Nothing in expansion? */
if (0==expn)
@@ -381,6 +440,9 @@ Note that 'init=foo:bar' stays in the list. It is ignored after expansion.
return init;
}
+paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) {
+ return pj_expand_init_internal(ctx, init, TRUE);
+}
/************************************************************************/
@@ -496,6 +558,14 @@ static PJ_CONSTRUCTOR locate_constructor (const char *name) {
PJ *
pj_init_ctx(projCtx ctx, int argc, char **argv) {
+ /* Legacy interface: allow init=epsg:XXXX syntax by default */
+ int allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, TRUE);
+ return pj_init_ctx_with_allow_init_epsg(ctx, argc, argv, allow_init_epsg);
+}
+
+
+PJ *
+pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_init_epsg) {
const char *s;
char *name;
PJ_CONSTRUCTOR proj;
@@ -558,7 +628,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) {
/* problem when '+init's are expanded as late as possible. */
init = pj_param_exists (start, "init");
if (init && n_pipelines == 0) {
- init = pj_expand_init (ctx, init);
+ init = pj_expand_init_internal (ctx, init, allow_init_epsg);
if (!init)
return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS);
}
@@ -580,8 +650,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) {
/* Append general and projection specific defaults to the definition list */
- append_defaults_to_paralist (ctx, start, "general");
- append_defaults_to_paralist (ctx, start, name);
+ append_defaults_to_paralist (ctx, start, "general", allow_init_epsg);
+ append_defaults_to_paralist (ctx, start, name, allow_init_epsg);
/* Allocate projection structure */
diff --git a/src/pj_transform.c b/src/pj_transform.c
index f6210822..6982676e 100644
--- a/src/pj_transform.c
+++ b/src/pj_transform.c
@@ -195,7 +195,7 @@ static int geographic_to_projected (PJ *P, long n, int dist, double *x, double *
if (P->is_geocent)
return 0;
- if(P->fwd3d != NULL)
+ if(P->fwd3d != NULL && !(z == NULL && P->is_latlong))
{
/* Three dimensions must be defined */
if ( z == NULL)
@@ -292,6 +292,8 @@ static int projected_to_geographic (PJ *P, long n, int dist, double *x, double *
/* Nothing to do? */
if (P->is_latlong && !P->geoc && P->vto_meter == 1.0)
return 0;
+ if (P->is_geocent)
+ return 0;
/* Check first if projection is invertible. */
if( (P->inv3d == NULL) && (P->inv == NULL))
@@ -303,7 +305,7 @@ static int projected_to_geographic (PJ *P, long n, int dist, double *x, double *
}
/* If invertible - First try inv3d if defined */
- if (P->inv3d != NULL)
+ if (P->inv3d != NULL && !(z == NULL && P->is_latlong))
{
/* Three dimensions must be defined */
if ( z == NULL)
diff --git a/src/proj.h b/src/proj.h
index 39d16b30..c41a2770 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -335,18 +335,23 @@ typedef struct projCtx_t PJ_CONTEXT;
PJ_CONTEXT PROJ_DLL *proj_context_create (void);
PJ_CONTEXT PROJ_DLL *proj_context_destroy (PJ_CONTEXT *ctx);
+void PROJ_DLL proj_context_use_proj4_init_rules(PJ_CONTEXT *ctx, int enable);
+int PROJ_DLL proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_legacy_code_path);
/* Manage the transformation definition object PJ */
PJ PROJ_DLL *proj_create (PJ_CONTEXT *ctx, const char *definition);
PJ PROJ_DLL *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv);
-PJ PROJ_DLL *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area);
+PJ PROJ_DLL *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area);
PJ PROJ_DLL *proj_destroy (PJ *P);
-/* Setter-functions for the opaque PJ_AREA struct */
-/* Uncomment these when implementing support for area-based transformations.
-void proj_area_bbox(PJ_AREA *area, LP ll, LP ur);
-void proj_area_description(PJ_AREA *area, const char *descr);
-*/
+
+PJ_AREA PROJ_DLL *proj_area_create(void);
+void PROJ_DLL proj_area_set_bbox(PJ_AREA *area,
+ double west_lon_degree,
+ double south_lat_degree,
+ double east_lon_degree,
+ double north_lat_degree);
+void PROJ_DLL proj_area_destroy(PJ_AREA* area);
/* Apply transformation to observation - in forward or inverse direction */
enum PJ_DIRECTION {
@@ -438,6 +443,11 @@ char PROJ_DLL * proj_rtodms(char *s, double r, int pos, int neg);
/* Binding in C of C++ API */
/* ------------------------------------------------------------------------- */
+/**
+ * \defgroup basic_cpp_binding Binding in C of basic methods from the C++ API
+ * @{
+ */
+
/*! @cond Doxygen_Suppress */
typedef struct PJ_OBJ PJ_OBJ;
/*! @endcond */
@@ -453,6 +463,10 @@ int PROJ_DLL proj_context_set_database_path(PJ_CONTEXT *ctx,
const char PROJ_DLL *proj_context_get_database_path(PJ_CONTEXT *ctx);
+const char PROJ_DLL *proj_context_get_database_metadata(PJ_CONTEXT* ctx,
+ const char* key);
+
+
/** \brief Guessed WKT "dialect". */
typedef enum
{
@@ -504,9 +518,13 @@ PJ_OBJ PROJ_DLL *proj_obj_create_from_database(PJ_CONTEXT *ctx,
void PROJ_DLL proj_obj_unref(PJ_OBJ *obj);
+PJ_OBJ PROJ_DLL *proj_obj_clone(PJ_CONTEXT *ctx, const PJ_OBJ *obj);
+
/** \brief Object type. */
typedef enum
{
+ PJ_OBJ_TYPE_UNKNOWN,
+
PJ_OBJ_TYPE_ELLIPSOID,
PJ_OBJ_TYPE_GEODETIC_REFERENCE_FRAME,
@@ -531,6 +549,7 @@ typedef enum
PJ_OBJ_TYPE_PROJECTED_CRS,
PJ_OBJ_TYPE_COMPOUND_CRS,
PJ_OBJ_TYPE_TEMPORAL_CRS,
+ PJ_OBJ_TYPE_ENGINEERING_CRS,
PJ_OBJ_TYPE_BOUND_CRS,
PJ_OBJ_TYPE_OTHER_CRS,
@@ -538,8 +557,6 @@ typedef enum
PJ_OBJ_TYPE_TRANSFORMATION,
PJ_OBJ_TYPE_CONCATENATED_OPERATION,
PJ_OBJ_TYPE_OTHER_COORDINATE_OPERATION,
-
- PJ_OBJ_TYPE_UNKNOWN
} PJ_OBJ_TYPE;
PJ_OBJ_LIST PROJ_DLL *proj_obj_create_from_name(PJ_CONTEXT *ctx,
@@ -551,614 +568,9 @@ PJ_OBJ_LIST PROJ_DLL *proj_obj_create_from_name(PJ_CONTEXT *ctx,
size_t limitResultCount,
const char* const *options);
-PJ_OBJ PROJ_DLL *proj_obj_create_geographic_crs(
- PJ_CONTEXT *ctx,
- const char *geogName,
- const char *datumName,
- const char *ellipsoidName,
- double semiMajorMetre, double invFlattening,
- const char *primeMeridianName,
- double primeMeridianOffset,
- const char *angularUnits,
- double angularUnitsConv,
- int latLongOrder);
-
-/* BEGIN: Generated by scripts/create_c_api_projections.py*/
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_UTM(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- int zone,
- int north
-);
+PJ_OBJ_TYPE PROJ_DLL proj_obj_get_type(const PJ_OBJ *obj);
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_TransverseMercator(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_GaussSchreiberTransverseMercator(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_TransverseMercatorSouthOriented(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_TwoPointEquidistant(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstPoint,
- double longitudeFirstPoint,
- double latitudeSecondPoint,
- double longitudeSeconPoint,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_TunisiaMappingGrid(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_AlbersEqualArea(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFalseOrigin,
- double longitudeFalseOrigin,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double eastingFalseOrigin,
- double northingFalseOrigin,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertConicConformal_1SP(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertConicConformal_2SP(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFalseOrigin,
- double longitudeFalseOrigin,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double eastingFalseOrigin,
- double northingFalseOrigin,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertConicConformal_2SP_Michigan(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFalseOrigin,
- double longitudeFalseOrigin,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double eastingFalseOrigin,
- double northingFalseOrigin,
- double ellipsoidScalingFactor,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertConicConformal_2SP_Belgium(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFalseOrigin,
- double longitudeFalseOrigin,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double eastingFalseOrigin,
- double northingFalseOrigin,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_AzimuthalEquidistant(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeNatOrigin,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_GuamProjection(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeNatOrigin,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Bonne(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeNatOrigin,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertCylindricalEqualAreaSpherical(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstParallel,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertCylindricalEqualArea(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstParallel,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_CassiniSoldner(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EquidistantConic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertI(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertII(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertIII(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertIV(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertV(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EckertVI(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EquidistantCylindrical(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstParallel,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EquidistantCylindricalSpherical(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstParallel,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Gall(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_GoodeHomolosine(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_InterruptedGoodeHomolosine(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_GeostationarySatelliteSweepX(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double height,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_GeostationarySatelliteSweepY(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double height,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Gnomonic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_HotineObliqueMercatorVariantA(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeProjectionCentre,
- double longitudeProjectionCentre,
- double azimuthInitialLine,
- double angleFromRectifiedToSkrewGrid,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_HotineObliqueMercatorVariantB(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeProjectionCentre,
- double longitudeProjectionCentre,
- double azimuthInitialLine,
- double angleFromRectifiedToSkrewGrid,
- double scale,
- double eastingProjectionCentre,
- double northingProjectionCentre,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_HotineObliqueMercatorTwoPointNaturalOrigin(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeProjectionCentre,
- double latitudePoint1,
- double longitudePoint1,
- double latitudePoint2,
- double longitudePoint2,
- double scale,
- double eastingProjectionCentre,
- double northingProjectionCentre,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_InternationalMapWorldPolyconic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double latitudeFirstParallel,
- double latitudeSecondParallel,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_KrovakNorthOriented(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeProjectionCentre,
- double longitudeOfOrigin,
- double colatitudeConeAxis,
- double latitudePseudoStandardParallel,
- double scaleFactorPseudoStandardParallel,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Krovak(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeProjectionCentre,
- double longitudeOfOrigin,
- double colatitudeConeAxis,
- double latitudePseudoStandardParallel,
- double scaleFactorPseudoStandardParallel,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_LambertAzimuthalEqualArea(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeNatOrigin,
- double longitudeNatOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_MillerCylindrical(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_MercatorVariantA(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_MercatorVariantB(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeFirstParallel,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_PopularVisualisationPseudoMercator(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Mollweide(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_NewZealandMappingGrid(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_ObliqueStereographic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Orthographic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_AmericanPolyconic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_PolarStereographicVariantA(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_PolarStereographicVariantB(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeStandardParallel,
- double longitudeOfOrigin,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Robinson(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Sinusoidal(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_Stereographic(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double scale,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_VanDerGrinten(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerI(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerII(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerIII(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double latitudeTrueScale,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerIV(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerV(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerVI(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_WagnerVII(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_QuadrilateralizedSphericalCube(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLat,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_SphericalCrossTrackHeight(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double pegPointLat,
- double pegPointLong,
- double pegPointHeading,
- double pegPointHeight,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs_EqualEarth(
- PJ_OBJ* geodetic_crs, const char* crs_name,
- double centerLong,
- double falseEasting,
- double falseNorthing,
- const char* angUnitName, double angUnitConvFactor,
- const char* linearUnitName, double linearUnitConvFactor);
-
-/* END: Generated by scripts/create_c_api_projections.py*/
-
-PJ_OBJ_TYPE PROJ_DLL proj_obj_get_type(PJ_OBJ *obj);
-
-int PROJ_DLL proj_obj_is_deprecated(PJ_OBJ *obj);
+int PROJ_DLL proj_obj_is_deprecated(const PJ_OBJ *obj);
/** Comparison criterion. */
typedef enum
@@ -1182,23 +594,24 @@ typedef enum
PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS,
} PJ_COMPARISON_CRITERION;
-int PROJ_DLL proj_obj_is_equivalent_to(PJ_OBJ *obj, PJ_OBJ* other,
+int PROJ_DLL proj_obj_is_equivalent_to(const PJ_OBJ *obj, const PJ_OBJ* other,
PJ_COMPARISON_CRITERION criterion);
-int PROJ_DLL proj_obj_is_crs(PJ_OBJ *obj);
+int PROJ_DLL proj_obj_is_crs(const PJ_OBJ *obj);
-const char PROJ_DLL* proj_obj_get_name(PJ_OBJ *obj);
+const char PROJ_DLL* proj_obj_get_name(const PJ_OBJ *obj);
-const char PROJ_DLL* proj_obj_get_id_auth_name(PJ_OBJ *obj, int index);
+const char PROJ_DLL* proj_obj_get_id_auth_name(const PJ_OBJ *obj, int index);
-const char PROJ_DLL* proj_obj_get_id_code(PJ_OBJ *obj, int index);
+const char PROJ_DLL* proj_obj_get_id_code(const PJ_OBJ *obj, int index);
-int PROJ_DLL proj_obj_get_area_of_use(PJ_OBJ *obj,
- double* p_west_lon,
- double* p_south_lat,
- double* p_east_lon,
- double* p_north_lat,
- const char **p_area_name);
+int PROJ_DLL proj_obj_get_area_of_use(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj,
+ double* out_west_lon_degree,
+ double* out_south_lat_degree,
+ double* out_east_lon_degree,
+ double* out_north_lat_degree,
+ const char **out_area_name);
/** \brief WKT version. */
typedef enum
@@ -1217,7 +630,8 @@ typedef enum
PJ_WKT1_ESRI
} PJ_WKT_TYPE;
-const char PROJ_DLL* proj_obj_as_wkt(PJ_OBJ *obj, PJ_WKT_TYPE type,
+const char PROJ_DLL* proj_obj_as_wkt(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj, PJ_WKT_TYPE type,
const char* const *options);
/** \brief PROJ string version. */
@@ -1229,18 +643,22 @@ typedef enum
PJ_PROJ_4
} PJ_PROJ_STRING_TYPE;
-const char PROJ_DLL* proj_obj_as_proj_string(PJ_OBJ *obj,
+const char PROJ_DLL* proj_obj_as_proj_string(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj,
PJ_PROJ_STRING_TYPE type,
const char* const *options);
-PJ_OBJ PROJ_DLL *proj_obj_get_source_crs(PJ_OBJ *obj);
+PJ_OBJ PROJ_DLL *proj_obj_get_source_crs(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj);
-PJ_OBJ PROJ_DLL *proj_obj_get_target_crs(PJ_OBJ *obj);
+PJ_OBJ PROJ_DLL *proj_obj_get_target_crs(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj);
-PJ_OBJ_LIST PROJ_DLL *proj_obj_identify(PJ_OBJ* obj,
+PJ_OBJ_LIST PROJ_DLL *proj_obj_identify(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj,
const char *auth_name,
const char* const *options,
- int **confidence);
+ int **out_confidence);
void PROJ_DLL proj_free_int_list(int* list);
@@ -1270,18 +688,20 @@ PJ_OPERATION_FACTORY_CONTEXT PROJ_DLL *proj_create_operation_factory_context(
const char *authority);
void PROJ_DLL proj_operation_factory_context_unref(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt);
+ PJ_OPERATION_FACTORY_CONTEXT *ctx);
void PROJ_DLL proj_operation_factory_context_set_desired_accuracy(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
double accuracy);
void PROJ_DLL proj_operation_factory_context_set_area_of_interest(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
- double west_lon,
- double south_lat,
- double east_lon,
- double north_lat);
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ double west_lon_degree,
+ double south_lat_degree,
+ double east_lon_degree,
+ double north_lat_degree);
/** Specify how source and target CRS extent should be used to restrict
* candidate operations (only taken into account if no explicit area of
@@ -1303,7 +723,8 @@ typedef enum
} PROJ_CRS_EXTENT_USE;
void PROJ_DLL proj_operation_factory_context_set_crs_extent_use(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
PROJ_CRS_EXTENT_USE use);
/** Spatial criterion to restrict candiate operations. */
@@ -1318,7 +739,8 @@ typedef enum {
} PROJ_SPATIAL_CRITERION;
void PROJ_DLL proj_operation_factory_context_set_spatial_criterion(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
PROJ_SPATIAL_CRITERION criterion);
@@ -1337,95 +759,148 @@ typedef enum {
} PROJ_GRID_AVAILABILITY_USE;
void PROJ_DLL proj_operation_factory_context_set_grid_availability_use(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
PROJ_GRID_AVAILABILITY_USE use);
void PROJ_DLL proj_operation_factory_context_set_use_proj_alternative_grid_names(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
int usePROJNames);
void PROJ_DLL proj_operation_factory_context_set_allow_use_intermediate_crs(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt, int allow);
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ int allow);
void PROJ_DLL proj_operation_factory_context_set_allowed_intermediate_crs(
- PJ_OPERATION_FACTORY_CONTEXT *ctxt,
+ PJ_CONTEXT *ctx,
+ PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
const char* const *list_of_auth_name_codes);
/* ------------------------------------------------------------------------- */
PJ_OBJ_LIST PROJ_DLL *proj_obj_create_operations(
- PJ_OBJ *source_crs,
- PJ_OBJ *target_crs,
- PJ_OPERATION_FACTORY_CONTEXT *operationContext);
+ PJ_CONTEXT *ctx,
+ const PJ_OBJ *source_crs,
+ const PJ_OBJ *target_crs,
+ const PJ_OPERATION_FACTORY_CONTEXT *operationContext);
-int PROJ_DLL proj_obj_list_get_count(PJ_OBJ_LIST *result);
+int PROJ_DLL proj_obj_list_get_count(const PJ_OBJ_LIST *result);
-PJ_OBJ PROJ_DLL *proj_obj_list_get(PJ_OBJ_LIST *result,
- int index);
+PJ_OBJ PROJ_DLL *proj_obj_list_get(PJ_CONTEXT *ctx,
+ const PJ_OBJ_LIST *result,
+ int index);
void PROJ_DLL proj_obj_list_unref(PJ_OBJ_LIST *result);
/* ------------------------------------------------------------------------- */
-PJ_OBJ PROJ_DLL *proj_obj_crs_get_geodetic_crs(PJ_OBJ *crs);
-
-PJ_OBJ PROJ_DLL *proj_obj_crs_get_horizontal_datum(PJ_OBJ *crs);
-
-PJ_OBJ PROJ_DLL *proj_obj_crs_get_sub_crs(PJ_OBJ *crs, int index);
-
-PJ_OBJ PROJ_DLL *proj_obj_crs_create_bound_crs_to_WGS84(PJ_OBJ *crs);
-
-PJ_OBJ PROJ_DLL *proj_obj_get_ellipsoid(PJ_OBJ *obj);
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_geodetic_crs(PJ_CONTEXT *ctx, const PJ_OBJ *crs);
-int PROJ_DLL proj_obj_ellipsoid_get_parameters(PJ_OBJ *ellipsoid,
- double *pSemiMajorMetre,
- double *pSemiMinorMetre,
- int *pIsSemiMinorComputed,
- double *pInverseFlattening);
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_horizontal_datum(PJ_CONTEXT *ctx, const PJ_OBJ *crs);
-PJ_OBJ PROJ_DLL *proj_obj_get_prime_meridian(PJ_OBJ *obj);
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_sub_crs(PJ_CONTEXT *ctx, const PJ_OBJ *crs, int index);
-int PROJ_DLL proj_obj_prime_meridian_get_parameters(PJ_OBJ *prime_meridian,
- double *pLongitude,
- double *pLongitudeUnitConvFactor,
- const char **pLongitudeUnitName);
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_datum(PJ_CONTEXT *ctx, const PJ_OBJ *crs);
-PJ_OBJ PROJ_DLL *proj_obj_crs_get_coordoperation(PJ_OBJ *crs,
- const char **pMethodName,
- const char **pMethodAuthorityName,
- const char **pMethodCode);
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_coordinate_system(PJ_CONTEXT *ctx, const PJ_OBJ *crs);
-int PROJ_DLL proj_coordoperation_is_instanciable(PJ_OBJ *coordoperation);
-
-int PROJ_DLL proj_coordoperation_get_param_count(PJ_OBJ *coordoperation);
-
-int PROJ_DLL proj_coordoperation_get_param_index(PJ_OBJ *coordoperation,
+/** Type of coordinate system. */
+typedef enum
+{
+ PJ_CS_TYPE_UNKNOWN,
+
+ PJ_CS_TYPE_CARTESIAN,
+ PJ_CS_TYPE_ELLIPSOIDAL,
+ PJ_CS_TYPE_VERTICAL,
+ PJ_CS_TYPE_SPHERICAL,
+ PJ_CS_TYPE_ORDINAL,
+ PJ_CS_TYPE_PARAMETRIC,
+ PJ_CS_TYPE_DATETIMETEMPORAL,
+ PJ_CS_TYPE_TEMPORALCOUNT,
+ PJ_CS_TYPE_TEMPORALMEASURE
+} PJ_COORDINATE_SYSTEM_TYPE;
+
+PJ_COORDINATE_SYSTEM_TYPE PROJ_DLL proj_obj_cs_get_type(PJ_CONTEXT *ctx,
+ const PJ_OBJ* cs);
+
+int PROJ_DLL proj_obj_cs_get_axis_count(PJ_CONTEXT *ctx,
+ const PJ_OBJ *cs);
+
+int PROJ_DLL proj_obj_cs_get_axis_info(PJ_CONTEXT *ctx,
+ const PJ_OBJ *cs, int index,
+ const char **out_name,
+ const char **out_abbrev,
+ const char **out_direction,
+ double *out_unit_conv_factor,
+ const char **out_unit_name);
+
+PJ_OBJ PROJ_DLL *proj_obj_get_ellipsoid(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj);
+
+int PROJ_DLL proj_obj_ellipsoid_get_parameters(PJ_CONTEXT *ctx,
+ const PJ_OBJ *ellipsoid,
+ double *out_semi_major_metre,
+ double *out_semi_minor_metre,
+ int *out_is_semi_minor_computed,
+ double *out_inv_flattening);
+
+PJ_OBJ PROJ_DLL *proj_obj_get_prime_meridian(PJ_CONTEXT *ctx,
+ const PJ_OBJ *obj);
+
+int PROJ_DLL proj_obj_prime_meridian_get_parameters(PJ_CONTEXT *ctx,
+ const PJ_OBJ *prime_meridian,
+ double *out_longitude,
+ double *out_unit_conv_factor,
+ const char **out_unit_name);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_get_coordoperation(PJ_CONTEXT *ctx,
+ const PJ_OBJ *crs,
+ const char **out_method_name,
+ const char **out_method_auth_name,
+ const char **out_method_code);
+
+int PROJ_DLL proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation);
+
+int PROJ_DLL proj_coordoperation_get_param_count(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation);
+
+int PROJ_DLL proj_coordoperation_get_param_index(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation,
const char *name);
-int PROJ_DLL proj_coordoperation_get_param(PJ_OBJ *coordoperation,
+int PROJ_DLL proj_coordoperation_get_param(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation,
int index,
- const char **pName,
- const char **pNameAuthorityName,
- const char **pNameCode,
- double *pValue,
- const char **pValueString,
- double *pValueUnitConvFactor,
- const char **pValueUnitName);
-
-int PROJ_DLL proj_coordoperation_get_grid_used_count(PJ_OBJ *coordoperation);
-
-int PROJ_DLL proj_coordoperation_get_grid_used(PJ_OBJ *coordoperation,
+ const char **out_name,
+ const char **out_auth_name,
+ const char **out_code,
+ double *out_value,
+ const char **out_value_string,
+ double *out_unit_conv_factor,
+ const char **out_unit_name);
+
+int PROJ_DLL proj_coordoperation_get_grid_used_count(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation);
+
+int PROJ_DLL proj_coordoperation_get_grid_used(PJ_CONTEXT *ctx,
+ const PJ_OBJ *coordoperation,
int index,
- const char **pShortName,
- const char **pFullName,
- const char **pPackageName,
- const char **pURL,
- int *pDirectDownload,
- int *pOpenLicense,
- int *pAvailable);
-
-double PROJ_DLL proj_coordoperation_get_accuracy(PJ_OBJ* obj);
+ const char **out_short_name,
+ const char **out_full_name,
+ const char **out_package_name,
+ const char **out_url,
+ int *out_direct_download,
+ int *out_open_license,
+ int *out_available);
+
+double PROJ_DLL proj_coordoperation_get_accuracy(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj);
+
+/**@}*/
#ifdef __cplusplus
}
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index 56694aae..6ba56764 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -32,6 +32,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifndef _MSC_VER
+#include <strings.h>
+#endif
#include "proj.h"
#include "proj_internal.h"
@@ -564,6 +567,7 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
char *args, **argv;
size_t argc, n;
int ret;
+ int allow_init_epsg;
if (0==ctx)
ctx = pj_get_default_ctx ();
@@ -587,7 +591,9 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
argv = pj_trim_argv (argc, args);
/* ...and let pj_init_ctx do the hard work */
- P = pj_init_ctx (ctx, (int) argc, argv);
+ /* New interface: forbid init=epsg:XXXX syntax by default */
+ allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, FALSE);
+ P = pj_init_ctx_with_allow_init_epsg (ctx, (int) argc, argv, allow_init_epsg);
pj_dealloc (argv);
pj_dealloc (args);
@@ -634,51 +640,183 @@ indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
return P;
}
+/** Create an area of use */
+PJ_AREA * proj_area_create(void) {
+ return pj_calloc(1, sizeof(PJ_AREA));
+}
+
+/** Assign a bounding box to an area of use. */
+void proj_area_set_bbox(PJ_AREA *area,
+ double west_lon_degree,
+ double south_lat_degree,
+ double east_lon_degree,
+ double north_lat_degree) {
+ area->bbox_set = TRUE;
+ area->west_lon_degree = west_lon_degree;
+ area->south_lat_degree = south_lat_degree;
+ area->east_lon_degree = east_lon_degree;
+ area->north_lat_degree = north_lat_degree;
+}
+
+/** Free an area of use */
+void proj_area_destroy(PJ_AREA* area) {
+ pj_dealloc(area);
+}
+
+/************************************************************************/
+/* proj_context_use_proj4_init_rules() */
+/************************************************************************/
+
+void proj_context_use_proj4_init_rules(PJ_CONTEXT *ctx, int enable) {
+ if( ctx == NULL ) {
+ ctx = pj_get_default_ctx();
+ }
+ ctx->use_proj4_init_rules = enable;
+}
+
+/************************************************************************/
+/* EQUAL() */
+/************************************************************************/
+
+static int EQUAL(const char* a, const char* b) {
+#ifdef _MSC_VER
+ return _stricmp(a, b) == 0;
+#else
+ return strcasecmp(a, b) == 0;
+#endif
+}
+
+/************************************************************************/
+/* proj_context_get_use_proj4_init_rules() */
+/************************************************************************/
+
+int proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_legacy_code_path) {
+ const char* val = getenv("PROJ_USE_PROJ4_INIT_RULES");
+
+ if( ctx == NULL ) {
+ ctx = pj_get_default_ctx();
+ }
+
+ if( val ) {
+ if( EQUAL(val, "yes") || EQUAL(val, "on") || EQUAL(val, "true") ) {
+ return TRUE;
+ }
+ if( EQUAL(val, "no") || EQUAL(val, "off") || EQUAL(val, "false") ) {
+ return FALSE;
+ }
+ pj_log(ctx, PJ_LOG_ERROR, "Invalid value for PROJ_USE_PROJ4_INIT_RULES");
+ }
+
+ if( ctx->use_proj4_init_rules >= 0 ) {
+ return ctx->use_proj4_init_rules;
+ }
+ return from_legacy_code_path;
+}
/*****************************************************************************/
-PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area) {
+PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area) {
/******************************************************************************
Create a transformation pipeline between two known coordinate reference
systems.
- srid_from and srid_to should be the value part of a +init=... parameter
- set, i.e. "epsg:25833" or "IGNF:AMST63". Any projection definition that
- can be found in a init-file in PROJ_LIB is a valid input to this function.
-
- For now the function mimics the cs2cs app: An input and an output CRS is
- given and coordinates are transformed via a hub datum (WGS84). This
- transformation strategy is referred to as "early-binding" by the EPSG. The
- function can be extended to support "late-binding" transformations in the
- future without affecting users of the function.
-
- An "area of use" can be specified in area. In the current version of this
- function is has no function, but is added in anticipation of a
- "late-binding" implementation in the future. The idea being, that if a user
- supplies an area of use, the more accurate transformation between two given
- systems can be chosen.
+ source_crs and target_crs can be :
+ - a "AUTHORITY:CODE", like EPSG:25832. When using that syntax for a source
+ CRS, the created pipeline will expect that the values passed to proj_trans()
+ respect the axis order and axis unit of the official definition (
+ so for example, for EPSG:4326, with latitude first and longitude next,
+ in degrees). Similarly, when using that syntax for a target CRS, output
+ values will be emitted according to the official definition of this CRS.
+ - a PROJ string, like "+proj=longlat +datum=WGS84".
+ When using that syntax, the axis order and unit for geographic CRS will
+ be longitude, latitude, and the unit degrees.
+ - more generally any string accepted by proj_obj_create_from_user_input()
+
+ An "area of use" can be specified in area. When it is supplied, the more
+ accurate transformation between two given systems can be chosen.
Example call:
- PJ *P = proj_create_crs_to_crs(0, "epsg:25832", "epsg:25833", NULL);
+ PJ *P = proj_create_crs_to_crs(0, "EPSG:25832", "EPSG:25833", NULL);
******************************************************************************/
PJ *P;
- char buffer[512];
- size_t len;
+ PJ_OBJ* src;
+ PJ_OBJ* dst;
+ PJ_OPERATION_FACTORY_CONTEXT* operation_ctx;
+ PJ_OBJ_LIST* op_list;
+ PJ_OBJ* op;
+ const char* proj_string;
+ const char* const optionsProj4Mode[] = { "USE_PROJ4_INIT_RULES=YES", NULL };
+ const char* const* optionsImportCRS =
+ proj_context_get_use_proj4_init_rules(ctx, FALSE) ? optionsProj4Mode : NULL;
+
+ src = proj_obj_create_from_user_input(ctx, source_crs, optionsImportCRS);
+ if( !src ) {
+ return NULL;
+ }
+
+ dst = proj_obj_create_from_user_input(ctx, target_crs, optionsImportCRS);
+ if( !dst ) {
+ proj_obj_unref(src);
+ return NULL;
+ }
+
+ operation_ctx = proj_create_operation_factory_context(ctx, NULL);
+ if( !operation_ctx ) {
+ proj_obj_unref(src);
+ proj_obj_unref(dst);
+ return NULL;
+ }
+
+ if( area && area->bbox_set ) {
+ proj_operation_factory_context_set_area_of_interest(
+ ctx,
+ operation_ctx,
+ area->west_lon_degree,
+ area->south_lat_degree,
+ area->east_lon_degree,
+ area->north_lat_degree);
+ }
+
+ proj_operation_factory_context_set_grid_availability_use(
+ ctx, operation_ctx, PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID);
+
+ op_list = proj_obj_create_operations(ctx, src, dst, operation_ctx);
+
+ proj_operation_factory_context_unref(operation_ctx);
+ proj_obj_unref(src);
+ proj_obj_unref(dst);
+
+ if( !op_list ) {
+ return NULL;
+ }
+
+ if( proj_obj_list_get_count(op_list) == 0 ) {
+ proj_obj_list_unref(op_list);
+ return NULL;
+ }
+
+ op = proj_obj_list_get(ctx, op_list, 0);
+ proj_obj_list_unref(op_list);
+ if( !op ) {
+ return NULL;
+ }
- /* area not in use yet, suppressing warning */
- (void)area;
+ proj_string = proj_obj_as_proj_string(ctx, op, PJ_PROJ_5, NULL);
+ if( !proj_string) {
+ proj_obj_unref(op);
+ return NULL;
+ }
- strcpy(buffer, "+proj=pipeline +step +init=");
- len = strlen(buffer);
- strncat(buffer + len, srid_from, sizeof(buffer)-1-len);
- len += strlen(buffer + len);
- strncat(buffer + len, " +inv +step +init=", sizeof(buffer)-1-len);
- len += strlen(buffer + len);
- strncat(buffer + len, srid_to, sizeof(buffer)-1-len);
+ if( proj_string[0] == '\0' ) {
+ /* Null transform ? */
+ P = proj_create(ctx, "proj=affine");
+ } else {
+ P = proj_create(ctx, proj_string);
+ }
- P = proj_create(ctx, buffer);
+ proj_obj_unref(op);
return P;
}
@@ -1028,6 +1166,42 @@ PJ_INIT_INFO proj_init_info(const char *initname){
file_found = pj_find_file(ctx, initname, ininfo.filename, sizeof(ininfo.filename));
if (!file_found || strlen(initname) > 64) {
+ if( strcmp(initname, "epsg") == 0 || strcmp(initname, "EPSG") == 0 ) {
+ const char* val;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
+ strcpy(ininfo.origin, "EPSG");
+ val = proj_context_get_database_metadata(ctx, "EPSG.VERSION");
+ if( val ) {
+ strncpy(ininfo.version, val, sizeof(ininfo.version) - 1);
+ }
+ val = proj_context_get_database_metadata(ctx, "EPSG.DATE");
+ if( val ) {
+ strncpy(ininfo.lastupdate, val, sizeof(ininfo.lastupdate) - 1);
+ }
+ return ininfo;
+ }
+
+ if( strcmp(initname, "IGNF") == 0 ) {
+ const char* val;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
+ strcpy(ininfo.origin, "IGNF");
+ val = proj_context_get_database_metadata(ctx, "IGNF.VERSION");
+ if( val ) {
+ strncpy(ininfo.version, val, sizeof(ininfo.version) - 1);
+ }
+ val = proj_context_get_database_metadata(ctx, "IGNF.DATE");
+ if( val ) {
+ strncpy(ininfo.lastupdate, val, sizeof(ininfo.lastupdate) - 1);
+ }
+ return ininfo;
+ }
+
return ininfo;
}
diff --git a/src/proj_experimental.h b/src/proj_experimental.h
new file mode 100644
index 00000000..1dc16f99
--- /dev/null
+++ b/src/proj_experimental.h
@@ -0,0 +1,831 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: Experimental C API
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, 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.
+ ****************************************************************************/
+
+#include "proj.h"
+
+#ifndef PROJ_EXPERIMENTAL_H
+#define PROJ_EXPERIMENTAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file proj_experimental.h
+ *
+ * Experimental C API.
+ *
+ * \warning
+ * This API has been considered now to be experimental, and may change or
+ * be removed in the future. It addresses for now the needs of the GDAL
+ * project to be able to construct CRS objects in a programmatic way, piece
+ * by piece, instead of whole conversion from PROJ string or WKT string.
+ */
+
+/* ------------------------------------------------------------------------- */
+/* Binding in C of advanced methods from the C++ API */
+/* */
+/* Manual construction of CRS objects. */
+/* ------------------------------------------------------------------------- */
+
+/**
+ * \defgroup advanced_cpp_binding Binding in C of advanced methods from the C++ API
+ * @{
+ */
+
+/** Type of unit of measure. */
+typedef enum
+{
+ /** Angular unit of measure */
+ PJ_UT_ANGULAR,
+ /** Linear unit of measure */
+ PJ_UT_LINEAR,
+ /** Scale unit of measure */
+ PJ_UT_SCALE,
+ /** Time unit of measure */
+ PJ_UT_TIME,
+ /** Parametric unit of measure */
+ PJ_UT_PARAMETRIC
+} PJ_UNIT_TYPE;
+
+/** Axis description. */
+typedef struct
+{
+ /** Axis name. */
+ char* name;
+ /** Axis abbreviation. */
+ char* abbreviation;
+ /** Axis direction. */
+ char* direction;
+ /** Axis unit name. */
+ char* unit_name;
+ /** Conversion factor to SI of the unit. */
+ double unit_conv_factor;
+ /** Type of unit */
+ PJ_UNIT_TYPE unit_type;
+} PJ_AXIS_DESCRIPTION;
+
+PJ_OBJ PROJ_DLL *proj_obj_create_cs(PJ_CONTEXT *ctx,
+ PJ_COORDINATE_SYSTEM_TYPE type,
+ int axis_count,
+ const PJ_AXIS_DESCRIPTION* axis);
+
+/** Type of Cartesian 2D coordinate system. */
+typedef enum
+{
+ /* Easting-Norting */
+ PJ_CART2D_EASTING_NORTHING,
+ /* Northing-Easting */
+ PJ_CART2D_NORTHING_EASTING,
+} PJ_CARTESIAN_CS_2D_TYPE;
+
+PJ_OBJ PROJ_DLL *proj_obj_create_cartesian_2D_cs(PJ_CONTEXT *ctx,
+ PJ_CARTESIAN_CS_2D_TYPE type,
+ const char* unit_name,
+ double unit_conv_factor);
+
+
+/** Type of Cartesian 2D coordinate system. */
+typedef enum
+{
+ /* Longitude-Latitude */
+ PJ_ELLPS2D_LONGITUDE_LATITUDE,
+ /* Latitude-Longitude */
+ PJ_ELLPS2D_LATITUDE_LONGITUDE,
+} PJ_ELLIPSOIDAL_CS_2D_TYPE;
+
+PJ_OBJ PROJ_DLL *proj_obj_create_ellipsoidal_2D_cs(PJ_CONTEXT *ctx,
+ PJ_ELLIPSOIDAL_CS_2D_TYPE type,
+ const char* unit_name,
+ double unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_geographic_crs(
+ PJ_CONTEXT *ctx,
+ const char *crs_name,
+ const char *datum_name,
+ const char *ellps_name,
+ double semi_major_metre, double inv_flattening,
+ const char *prime_meridian_name,
+ double prime_meridian_offset,
+ const char *pm_angular_units,
+ double pm_units_conv,
+ PJ_OBJ* ellipsoidal_cs);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_geographic_crs_from_datum(
+ PJ_CONTEXT *ctx,
+ const char *crs_name,
+ PJ_OBJ* datum,
+ PJ_OBJ* ellipsoidal_cs);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_geocentric_crs(
+ PJ_CONTEXT *ctx,
+ const char *crs_name,
+ const char *datum_name,
+ const char *ellps_name,
+ double semi_major_metre, double inv_flattening,
+ const char *prime_meridian_name,
+ double prime_meridian_offset,
+ const char *angular_units,
+ double angular_units_conv,
+ const char *linear_units,
+ double linear_units_conv);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_geocentric_crs_from_datum(
+ PJ_CONTEXT *ctx,
+ const char *crs_name,
+ const PJ_OBJ* datum,
+ const char *linear_units,
+ double linear_units_conv);
+
+PJ_OBJ PROJ_DLL *proj_obj_alter_name(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj, const char* name);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_alter_geodetic_crs(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj,
+ const PJ_OBJ* new_geod_crs);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_alter_cs_angular_unit(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj,
+ const char *angular_units,
+ double angular_units_conv);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_alter_cs_linear_unit(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj,
+ const char *linear_units,
+ double linear_units_conv);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_alter_parameters_linear_unit(PJ_CONTEXT *ctx,
+ const PJ_OBJ* obj,
+ const char *linear_units,
+ double linear_units_conv,
+ int convert_to_new_unit);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_engineering_crs(PJ_CONTEXT *ctx,
+ const char *crsName);
+
+/** Description of a parameter value for a Conversion. */
+typedef struct
+{
+ /** Parameter name. */
+ const char* name;
+ /** Parameter authority name. */
+ const char* auth_name;
+ /** Parameter code. */
+ const char* code;
+ /** Parameter value. */
+ double value;
+ /** Name of unit in which parameter value is expressed. */
+ const char* unit_name;
+ /** Conversion factor to SI of the unit. */
+ double unit_conv_factor;
+ /** Type of unit */
+ PJ_UNIT_TYPE unit_type;
+} PJ_PARAM_DESCRIPTION;
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion(PJ_CONTEXT *ctx,
+ const char* name,
+ const char* auth_name,
+ const char* code,
+ const char* method_name,
+ const char* method_auth_name,
+ const char* method_code,
+ int param_count,
+ const PJ_PARAM_DESCRIPTION* params);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_projected_crs(PJ_CONTEXT *ctx,
+ const char* crs_name,
+ const PJ_OBJ* geodetic_crs,
+ const PJ_OBJ* conversion,
+ const PJ_OBJ* coordinate_system);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_create_bound_crs(PJ_CONTEXT *ctx,
+ const PJ_OBJ *base_crs,
+ const PJ_OBJ *hub_crs,
+ const PJ_OBJ *transformation);
+
+PJ_OBJ PROJ_DLL *proj_obj_crs_create_bound_crs_to_WGS84(PJ_CONTEXT *ctx,
+ const PJ_OBJ *crs);
+
+/* BEGIN: Generated by scripts/create_c_api_projections.py*/
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_utm(
+ PJ_CONTEXT *ctx,
+ int zone,
+ int north);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_transverse_mercator(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_gauss_schreiber_transverse_mercator(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_transverse_mercator_south_oriented(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_two_point_equidistant(
+ PJ_CONTEXT *ctx,
+ double latitude_first_point,
+ double longitude_first_point,
+ double latitude_second_point,
+ double longitude_secon_point,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_tunisia_mapping_grid(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_albers_equal_area(
+ PJ_CONTEXT *ctx,
+ double latitude_false_origin,
+ double longitude_false_origin,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double easting_false_origin,
+ double northing_false_origin,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_conic_conformal_1sp(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_conic_conformal_2sp(
+ PJ_CONTEXT *ctx,
+ double latitude_false_origin,
+ double longitude_false_origin,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double easting_false_origin,
+ double northing_false_origin,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_conic_conformal_2sp_michigan(
+ PJ_CONTEXT *ctx,
+ double latitude_false_origin,
+ double longitude_false_origin,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double easting_false_origin,
+ double northing_false_origin,
+ double ellipsoid_scaling_factor,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_conic_conformal_2sp_belgium(
+ PJ_CONTEXT *ctx,
+ double latitude_false_origin,
+ double longitude_false_origin,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double easting_false_origin,
+ double northing_false_origin,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_azimuthal_equidistant(
+ PJ_CONTEXT *ctx,
+ double latitude_nat_origin,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_guam_projection(
+ PJ_CONTEXT *ctx,
+ double latitude_nat_origin,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_bonne(
+ PJ_CONTEXT *ctx,
+ double latitude_nat_origin,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_cylindrical_equal_area_spherical(
+ PJ_CONTEXT *ctx,
+ double latitude_first_parallel,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_cylindrical_equal_area(
+ PJ_CONTEXT *ctx,
+ double latitude_first_parallel,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_cassini_soldner(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_equidistant_conic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_i(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_ii(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_iii(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_iv(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_v(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_eckert_vi(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_equidistant_cylindrical(
+ PJ_CONTEXT *ctx,
+ double latitude_first_parallel,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_equidistant_cylindrical_spherical(
+ PJ_CONTEXT *ctx,
+ double latitude_first_parallel,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_gall(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_goode_homolosine(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_interrupted_goode_homolosine(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_geostationary_satellite_sweep_x(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double height,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_geostationary_satellite_sweep_y(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double height,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_gnomonic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_hotine_oblique_mercator_variant_a(
+ PJ_CONTEXT *ctx,
+ double latitude_projection_centre,
+ double longitude_projection_centre,
+ double azimuth_initial_line,
+ double angle_from_rectified_to_skrew_grid,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_hotine_oblique_mercator_variant_b(
+ PJ_CONTEXT *ctx,
+ double latitude_projection_centre,
+ double longitude_projection_centre,
+ double azimuth_initial_line,
+ double angle_from_rectified_to_skrew_grid,
+ double scale,
+ double easting_projection_centre,
+ double northing_projection_centre,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_hotine_oblique_mercator_two_point_natural_origin(
+ PJ_CONTEXT *ctx,
+ double latitude_projection_centre,
+ double latitude_point1,
+ double longitude_point1,
+ double latitude_point2,
+ double longitude_point2,
+ double scale,
+ double easting_projection_centre,
+ double northing_projection_centre,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_international_map_world_polyconic(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double latitude_first_parallel,
+ double latitude_second_parallel,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_krovak_north_oriented(
+ PJ_CONTEXT *ctx,
+ double latitude_projection_centre,
+ double longitude_of_origin,
+ double colatitude_cone_axis,
+ double latitude_pseudo_standard_parallel,
+ double scale_factor_pseudo_standard_parallel,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_krovak(
+ PJ_CONTEXT *ctx,
+ double latitude_projection_centre,
+ double longitude_of_origin,
+ double colatitude_cone_axis,
+ double latitude_pseudo_standard_parallel,
+ double scale_factor_pseudo_standard_parallel,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_lambert_azimuthal_equal_area(
+ PJ_CONTEXT *ctx,
+ double latitude_nat_origin,
+ double longitude_nat_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_miller_cylindrical(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_mercator_variant_a(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_mercator_variant_b(
+ PJ_CONTEXT *ctx,
+ double latitude_first_parallel,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_popular_visualisation_pseudo_mercator(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_mollweide(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_new_zealand_mapping_grid(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_oblique_stereographic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_orthographic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_american_polyconic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_polar_stereographic_variant_a(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_polar_stereographic_variant_b(
+ PJ_CONTEXT *ctx,
+ double latitude_standard_parallel,
+ double longitude_of_origin,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_robinson(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_sinusoidal(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_stereographic(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double scale,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_van_der_grinten(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_i(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_ii(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_iii(
+ PJ_CONTEXT *ctx,
+ double latitude_true_scale,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_iv(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_v(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_vi(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_wagner_vii(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_quadrilateralized_spherical_cube(
+ PJ_CONTEXT *ctx,
+ double center_lat,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_spherical_cross_track_height(
+ PJ_CONTEXT *ctx,
+ double peg_point_lat,
+ double peg_point_long,
+ double peg_point_heading,
+ double peg_point_height,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+PJ_OBJ PROJ_DLL *proj_obj_create_conversion_equal_earth(
+ PJ_CONTEXT *ctx,
+ double center_long,
+ double false_easting,
+ double false_northing,
+ const char* ang_unit_name, double ang_unit_conv_factor,
+ const char* linear_unit_name, double linear_unit_conv_factor);
+
+/* END: Generated by scripts/create_c_api_projections.py*/
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ndef PROJ_EXPERIMENTAL_H */
diff --git a/src/proj_symbol_rename.h b/src/proj_symbol_rename.h
index d0dd09eb..a267b97e 100644
--- a/src/proj_symbol_rename.h
+++ b/src/proj_symbol_rename.h
@@ -101,14 +101,20 @@
#define pj_transform internal_pj_transform
#define proj_angular_input internal_proj_angular_input
#define proj_angular_output internal_proj_angular_output
+#define proj_area_create internal_proj_area_create
+#define proj_area_destroy internal_proj_area_destroy
+#define proj_area_set_bbox internal_proj_area_set_bbox
#define proj_context_create internal_proj_context_create
#define proj_context_delete_cpp_context internal_proj_context_delete_cpp_context
#define proj_context_destroy internal_proj_context_destroy
#define proj_context_errno internal_proj_context_errno
+#define proj_context_get_database_metadata internal_proj_context_get_database_metadata
#define proj_context_get_database_path internal_proj_context_get_database_path
+#define proj_context_get_use_proj4_init_rules internal_proj_context_get_use_proj4_init_rules
#define proj_context_guess_wkt_dialect internal_proj_context_guess_wkt_dialect
#define proj_context_set internal_proj_context_set
#define proj_context_set_database_path internal_proj_context_set_database_path
+#define proj_context_use_proj4_init_rules internal_proj_context_use_proj4_init_rules
#define proj_coord internal_proj_coord
#define proj_coord_error internal_proj_coord_error
#define proj_coordoperation_get_accuracy internal_proj_coordoperation_get_accuracy
@@ -132,7 +138,6 @@
#define proj_factors internal_proj_factors
#define proj_free_int_list internal_proj_free_int_list
#define proj_free_string_list internal_proj_free_string_list
-#define proj_geocentric_latitude internal_proj_geocentric_latitude
#define proj_geod internal_proj_geod
#define proj_get_authorities_from_database internal_proj_get_authorities_from_database
#define proj_get_codes_from_database internal_proj_get_codes_from_database
@@ -151,6 +156,7 @@
#define proj_lpz_dist internal_proj_lpz_dist
#define proj_obj_as_proj_string internal_proj_obj_as_proj_string
#define proj_obj_as_wkt internal_proj_obj_as_wkt
+#define proj_obj_clone internal_proj_obj_clone
#define proj_obj_create_from_database internal_proj_obj_create_from_database
#define proj_obj_create_from_name internal_proj_obj_create_from_name
#define proj_obj_create_from_proj_string internal_proj_obj_create_from_proj_string
@@ -223,10 +229,14 @@
#define proj_obj_create_projected_crs_WagnerVI internal_proj_obj_create_projected_crs_WagnerVI
#define proj_obj_create_projected_crs_WagnerVII internal_proj_obj_create_projected_crs_WagnerVII
#define proj_obj_crs_create_bound_crs_to_WGS84 internal_proj_obj_crs_create_bound_crs_to_WGS84
+#define proj_obj_crs_get_coordinate_system internal_proj_obj_crs_get_coordinate_system
#define proj_obj_crs_get_coordoperation internal_proj_obj_crs_get_coordoperation
#define proj_obj_crs_get_geodetic_crs internal_proj_obj_crs_get_geodetic_crs
#define proj_obj_crs_get_horizontal_datum internal_proj_obj_crs_get_horizontal_datum
#define proj_obj_crs_get_sub_crs internal_proj_obj_crs_get_sub_crs
+#define proj_obj_cs_get_axis_count internal_proj_obj_cs_get_axis_count
+#define proj_obj_cs_get_axis_info internal_proj_obj_cs_get_axis_info
+#define proj_obj_cs_get_type internal_proj_obj_cs_get_type
#define proj_obj_ellipsoid_get_parameters internal_proj_obj_ellipsoid_get_parameters
#define proj_obj_get_area_of_use internal_proj_obj_get_area_of_use
#define proj_obj_get_ellipsoid internal_proj_obj_get_ellipsoid
diff --git a/src/projects.h b/src/projects.h
index e34fc9e0..11467d56 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -224,10 +224,11 @@ struct PJ_REGION_S {
};
struct PJ_AREA {
- int id; /* Area ID in the EPSG database */
- LP ll; /* Lower left corner of bounding box */
- LP ur; /* Upper right corner of bounding box */
- char descr[64]; /* text representation of area */
+ int bbox_set;
+ double west_lon_degree;
+ double south_lat_degree;
+ double east_lon_degree;
+ double north_lat_degree;
};
struct projCtx_t;
@@ -596,6 +597,8 @@ struct projCtx_t {
void *app_data;
struct projFileAPI_t *fileapi;
struct projCppContext* cpp_context; /* internal context for C++ code */
+ int use_proj4_init_rules; /* -1 = unknown, 0 = no, 1 = yes */
+ int epsg_file_exists; /* -1 = unknown, 0 = no, 1 = yes */
};
/* classic public API */
@@ -831,6 +834,8 @@ double PROJ_DLL pj_atof( const char* nptr );
double pj_strtod( const char *nptr, char **endptr );
void pj_freeup_plain (PJ *P);
+projPJ pj_init_ctx_with_allow_init_epsg( projCtx ctx, int argc, char **argv, int allow_init_epsg );
+
#ifdef __cplusplus
}
#endif
diff --git a/src/projinfo.cpp b/src/projinfo.cpp
index dbbcdae2..7acb13af 100644
--- a/src/projinfo.cpp
+++ b/src/projinfo.cpp
@@ -65,6 +65,7 @@ struct OutputOptions {
bool WKT1_GDAL = false;
bool WKT1_ESRI = false;
bool c_ify = false;
+ bool singleLine = false;
};
// ---------------------------------------------------------------------------
@@ -86,6 +87,7 @@ static void usage() {
<< " [--main-db-path path] [--aux-db-path path]*"
<< std::endl
<< " [--identify]" << std::endl
+ << " [--c-ify] [--single-line]" << std::endl
<< " {object_definition} | (-s {srs_def} -t {srs_def})"
<< std::endl;
std::cerr << std::endl;
@@ -204,7 +206,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
if (outputOpt.PROJ5) {
try {
if (!outputOpt.quiet) {
- std::cout << "PROJ string: " << std::endl;
+ std::cout << "PROJ string:" << std::endl;
}
std::cout << projStringExportable->exportToPROJString(
PROJStringFormatter::create(
@@ -225,7 +227,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "PROJ.4 string: " << std::endl;
+ std::cout << "PROJ.4 string:" << std::endl;
}
auto crs = nn_dynamic_pointer_cast<CRS>(obj);
@@ -261,11 +263,14 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT2_2015 string: " << std::endl;
+ std::cout << "WKT2_2015 string:" << std::endl;
}
- auto wkt = wktExportable->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT2_2015)
- .get());
+ auto formatter =
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2015);
+ if (outputOpt.singleLine) {
+ formatter->setMultiLine(false);
+ }
+ auto wkt = wktExportable->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
}
@@ -283,12 +288,14 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT2_2015_SIMPLIFIED string: " << std::endl;
+ std::cout << "WKT2_2015_SIMPLIFIED string:" << std::endl;
}
- auto wkt = wktExportable->exportToWKT(
- WKTFormatter::create(
- WKTFormatter::Convention::WKT2_2015_SIMPLIFIED)
- .get());
+ auto formatter = WKTFormatter::create(
+ WKTFormatter::Convention::WKT2_2015_SIMPLIFIED);
+ if (outputOpt.singleLine) {
+ formatter->setMultiLine(false);
+ }
+ auto wkt = wktExportable->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
}
@@ -306,11 +313,14 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT2_2018 string: " << std::endl;
+ std::cout << "WKT2_2018 string:" << std::endl;
}
- auto wkt = wktExportable->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT2_2018)
- .get());
+ auto formatter =
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2018);
+ if (outputOpt.singleLine) {
+ formatter->setMultiLine(false);
+ }
+ auto wkt = wktExportable->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
}
@@ -328,12 +338,14 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT2_2018_SIMPLIFIED string: " << std::endl;
+ std::cout << "WKT2_2018_SIMPLIFIED string:" << std::endl;
}
- auto wkt = wktExportable->exportToWKT(
- WKTFormatter::create(
- WKTFormatter::Convention::WKT2_2018_SIMPLIFIED)
- .get());
+ auto formatter = WKTFormatter::create(
+ WKTFormatter::Convention::WKT2_2018_SIMPLIFIED);
+ if (outputOpt.singleLine) {
+ formatter->setMultiLine(false);
+ }
+ auto wkt = wktExportable->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
}
@@ -351,7 +363,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT1_GDAL: " << std::endl;
+ std::cout << "WKT1_GDAL:" << std::endl;
}
auto crs = nn_dynamic_pointer_cast<CRS>(obj);
@@ -364,9 +376,12 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
objToExport = wktExportable;
}
- auto wkt = objToExport->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL)
- .get());
+ auto formatter =
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL);
+ if (outputOpt.singleLine) {
+ formatter->setMultiLine(false);
+ }
+ auto wkt = objToExport->exportToWKT(formatter.get());
if (outputOpt.c_ify) {
wkt = c_ify_string(wkt);
}
@@ -385,7 +400,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj,
std::cout << std::endl;
}
if (!outputOpt.quiet) {
- std::cout << "WKT1_ESRI: " << std::endl;
+ std::cout << "WKT1_ESRI:" << std::endl;
}
auto wkt = wktExportable->exportToWKT(
@@ -571,6 +586,7 @@ int main(int argc, char **argv) {
outputOpt.WKT2_2018 = true;
outputOpt.WKT2_2015 = true;
outputOpt.WKT1_GDAL = true;
+ outputOpt.WKT1_ESRI = true;
} else if (ci_equal(format, "default")) {
outputOpt.PROJ5 = true;
outputOpt.PROJ4 = false;
@@ -684,6 +700,8 @@ int main(int argc, char **argv) {
outputOpt.quiet = true;
} else if (arg == "--c-ify") {
outputOpt.c_ify = true;
+ } else if (arg == "--single-line") {
+ outputOpt.singleLine = true;
} else if (arg == "--summary") {
summary = true;
} else if (ci_equal(arg, "--boundcrs-to-wgs84")) {
diff --git a/src/rtodms.c b/src/rtodms.c
index f0e2f675..674cebdf 100644
--- a/src/rtodms.c
+++ b/src/rtodms.c
@@ -66,6 +66,13 @@ rtodms(char *s, double r, int pos, int neg) {
size_t suffix_len = sign ? 3 : 2;
(void)sprintf(ss,format,deg,min,sec,sign);
+ /* Replace potential decimal comma by decimal point for non C locale */
+ for( p = ss; *p != '\0'; ++p ) {
+ if( *p == ',' ) {
+ *p = '.';
+ break;
+ }
+ }
for (q = p = ss + strlen(ss) - suffix_len; *p == '0'; --p) ;
if (*p != '.')
++p;