aboutsummaryrefslogtreecommitdiff
path: root/test/unit
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 /test/unit
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 'test/unit')
-rw-r--r--test/unit/CMakeLists.txt16
-rw-r--r--test/unit/Makefile.am26
-rw-r--r--test/unit/basic_test.cpp44
-rw-r--r--test/unit/gie_self_tests.cpp664
-rw-r--r--test/unit/main.cpp8
-rw-r--r--test/unit/pj_phi2_test.cpp3
-rw-r--r--test/unit/pj_transform_test.cpp583
-rw-r--r--test/unit/proj_errno_string_test.cpp18
-rw-r--r--test/unit/test_c_api.cpp1032
-rw-r--r--test/unit/test_crs.cpp328
-rw-r--r--test/unit/test_factory.cpp17
-rw-r--r--test/unit/test_io.cpp335
-rw-r--r--test/unit/test_operation.cpp221
13 files changed, 2827 insertions, 468 deletions
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 5138dafc..68a6e60f 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -58,13 +58,13 @@ endif()
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${SQLITE3_INCLUDE_DIR})
-add_executable(proj_test_unit
+add_executable(proj_pj_transform_test
main.cpp
- basic_test.cpp)
-target_link_libraries(proj_test_unit
+ pj_transform_test.cpp)
+target_link_libraries(proj_pj_transform_test
gtest
${PROJ_LIBRARIES})
-add_test(NAME proj_test_unit COMMAND proj_test_unit)
+add_test(NAME proj_pj_transform_test COMMAND proj_pj_transform_test)
add_executable(proj_errno_string_test
main.cpp
@@ -103,3 +103,11 @@ target_link_libraries(proj_test_cpp_api
${PROJ_LIBRARIES}
${SQLITE3_LIBRARY})
add_test(NAME proj_test_cpp_api COMMAND proj_test_cpp_api)
+
+add_executable(gie_self_tests
+ main.cpp
+ gie_self_tests.cpp)
+target_link_libraries(gie_self_tests
+ gtest
+ ${PROJ_LIBRARIES})
+add_test(NAME gie_self_tests COMMAND gie_self_tests)
diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am
index 77525f9a..236ad444 100644
--- a/test/unit/Makefile.am
+++ b/test/unit/Makefile.am
@@ -9,19 +9,17 @@ AM_CXXFLAGS = @CXX_WFLAGS@ @NO_ZERO_AS_NULL_POINTER_CONSTANT_FLAG@
PROJ_LIB ?= ../../data
-noinst_PROGRAMS = basic_test
+noinst_PROGRAMS = pj_transform_test
noinst_PROGRAMS += pj_phi2_test
noinst_PROGRAMS += proj_errno_string_test
noinst_PROGRAMS += test_cpp_api
+noinst_PROGRAMS += gie_self_tests
-basic_test_SOURCES = basic_test.cpp main.cpp
-basic_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
+pj_transform_test_SOURCES = pj_transform_test.cpp main.cpp
+pj_transform_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
-test_cpp_api_SOURCES = test_util.cpp test_common.cpp test_crs.cpp test_metadata.cpp test_io.cpp test_operation.cpp test_datum.cpp test_factory.cpp test_c_api.cpp main.cpp
-test_cpp_api_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la @SQLITE3_LDFLAGS@
-
-basic_test-check: basic_test
- ./basic_test
+pj_transform_test-check: pj_transform_test
+ PROJ_LIB=$(PROJ_LIB) ./pj_transform_test
pj_phi2_test_SOURCES = pj_phi2_test.cpp main.cpp
pj_phi2_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
@@ -35,10 +33,16 @@ proj_errno_string_test_LDADD= ../../src/libproj.la ../../test/googletest/libgtes
proj_errno_string_test-check: proj_errno_string_test
./proj_errno_string_test
-check-local: basic_test-check
-check-local: pj_phi2_test-check proj_errno_string_test-check
+test_cpp_api_SOURCES = test_util.cpp test_common.cpp test_crs.cpp test_metadata.cpp test_io.cpp test_operation.cpp test_datum.cpp test_factory.cpp test_c_api.cpp main.cpp
+test_cpp_api_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la @SQLITE3_LDFLAGS@
test_cpp_api-check: test_cpp_api
PROJ_LIB=$(PROJ_LIB) ./test_cpp_api
-check-local: basic_test-check test_cpp_api-check
+gie_self_tests_SOURCES = gie_self_tests.cpp main.cpp
+gie_self_tests_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la @SQLITE3_LDFLAGS@
+
+gie_self_tests-check: gie_self_tests
+ PROJ_LIB=$(PROJ_LIB) ./gie_self_tests
+
+check-local: pj_transform_test-check pj_phi2_test-check proj_errno_string_test-check test_cpp_api-check gie_self_tests-check
diff --git a/test/unit/basic_test.cpp b/test/unit/basic_test.cpp
deleted file mode 100644
index d565f839..00000000
--- a/test/unit/basic_test.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/******************************************************************************
- *
- * Project: PROJ
- * Purpose: Test
- * 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 "gtest_include.h"
-#include <proj.h>
-#include <memory>
-
-namespace {
-
-// ---------------------------------------------------------------------------
-
-TEST( dumy, dummy ) {
- std::unique_ptr<PJ, decltype(&::proj_destroy)> pj(
- ::proj_create(PJ_DEFAULT_CTX, "+proj=merc +ellps=clrk66 +lat_ts=33"),
- &::proj_destroy);
- ASSERT_NE(pj, nullptr);
-}
-
-} // namespace
diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp
new file mode 100644
index 00000000..b7af926b
--- /dev/null
+++ b/test/unit/gie_self_tests.cpp
@@ -0,0 +1,664 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: Test
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2017, Thomas Knudsen
+ * Copyright (c) 2017, SDFE
+ *
+ * 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 "gtest_include.h"
+
+// PROJ include order is sensitive
+// clang-format off
+#include "proj_internal.h"
+#include "proj.h"
+#include "projects.h"
+// clang-format on
+
+#include <cmath>
+#include <string>
+
+namespace {
+
+// ---------------------------------------------------------------------------
+
+TEST(gie, cart_selftest) {
+ PJ_CONTEXT *ctx;
+ PJ *P;
+ PJ_COORD a, b, obs[2];
+ PJ_COORD coord[2];
+
+ int err;
+ size_t n, sz;
+ double dist, h, t;
+ const char *const args[3] = {"proj=utm", "zone=32", "ellps=GRS80"};
+ char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"};
+
+ /* An utm projection on the GRS80 ellipsoid */
+ P = proj_create(PJ_DEFAULT_CTX, arg);
+ ASSERT_TRUE(P != nullptr);
+
+ /* Clean up */
+ proj_destroy(P);
+
+ /* Same projection, now using argc/argv style initialization */
+ P = proj_create_argv(PJ_DEFAULT_CTX, 3, const_cast<char **>(args));
+ ASSERT_TRUE(P != nullptr);
+
+ /* 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 = proj_torad(12);
+ a.lp.phi = proj_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);
+ ASSERT_LE(dist, 2e-9);
+
+ /* Clear any previous error */
+ proj_errno_reset(P);
+
+ /* Invalid projection */
+ a = proj_trans(P, static_cast<PJ_DIRECTION>(42), a);
+ ASSERT_EQ(a.lpz.lam, HUGE_VAL);
+
+ err = proj_errno(P);
+ ASSERT_NE(err, 0);
+
+ /* 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");
+ ASSERT_TRUE(P != nullptr);
+
+ /* zero initialize everything, then set (longitude, latitude, height) to
+ * (12, 55, 100) */
+ a = b = proj_coord(0, 0, 0, 0);
+ a.lpz.lam = proj_torad(12);
+ a.lpz.phi = proj_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);
+ ASSERT_LE(dist, 4e-9);
+
+ /* Test at the North Pole */
+ a = b = proj_coord(0, 0, 0, 0);
+ a.lpz.lam = proj_torad(0);
+ a.lpz.phi = proj_torad(90);
+ a.lpz.z = 100;
+
+ /* Forward projection: Ellipsoidal-to-3D-Cartesian */
+ dist = proj_roundtrip(P, PJ_FWD, 1, &a);
+ ASSERT_LE(dist, 1e-9);
+
+ /* Test at the South Pole */
+ a = b = proj_coord(0, 0, 0, 0);
+ a.lpz.lam = proj_torad(0);
+ a.lpz.phi = proj_torad(-90);
+ a.lpz.z = 100;
+ b = a;
+
+ /* Forward projection: Ellipsoidal-to-3D-Cartesian */
+ dist = proj_roundtrip(P, PJ_FWD, 1, &a);
+ ASSERT_LE(dist, 4e-9);
+
+ /* Inverse projection: 3D-Cartesian-to-Ellipsoidal */
+ b = proj_trans(P, PJ_INV, b);
+
+ /* Move p to another context */
+ ctx = proj_context_create();
+ ASSERT_NE(ctx, pj_get_default_ctx());
+
+ proj_context_set(P, ctx);
+ ASSERT_EQ(ctx, P->ctx);
+
+ b = proj_trans(P, PJ_FWD, b);
+
+ /* Move it back to the default context */
+ proj_context_set(P, 0);
+ ASSERT_EQ(pj_get_default_ctx(), P->ctx);
+
+ 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");
+ ASSERT_TRUE(P != nullptr);
+
+ obs[0] = proj_coord(proj_torad(12), proj_torad(55), 45, 0);
+ obs[1] = proj_coord(proj_torad(12), proj_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);
+ ASSERT_EQ(n, 2);
+
+ ASSERT_EQ(a.lpz.lam, obs[0].lpz.lam);
+ ASSERT_EQ(a.lpz.phi, obs[0].lpz.phi);
+ ASSERT_EQ(a.lpz.z, obs[0].lpz.z);
+ ASSERT_EQ(b.lpz.lam, obs[1].lpz.lam);
+ ASSERT_EQ(b.lpz.phi, obs[1].lpz.phi);
+ ASSERT_EQ(b.lpz.z, obs[1].lpz.z);
+
+ /* now test the case of constant z */
+ obs[0] = proj_coord(proj_torad(12), proj_torad(55), 45, 0);
+ obs[1] = proj_coord(proj_torad(12), proj_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);
+ ASSERT_EQ(n, 2);
+
+ ASSERT_EQ(a.lpz.lam, obs[0].lpz.lam);
+ ASSERT_EQ(a.lpz.phi, obs[0].lpz.phi);
+ ASSERT_EQ(45, obs[0].lpz.z);
+ ASSERT_EQ(b.lpz.lam, obs[1].lpz.lam);
+ ASSERT_EQ(b.lpz.phi, obs[1].lpz.phi);
+ ASSERT_EQ(50, obs[1].lpz.z);
+ ASSERT_NE(50, h);
+
+ /* test proj_trans_array () */
+
+ coord[0] = proj_coord(proj_torad(12), proj_torad(55), 45, 0);
+ coord[1] = proj_coord(proj_torad(12), proj_torad(56), 50, 0);
+ ASSERT_FALSE(proj_trans_array(P, PJ_FWD, 2, coord));
+
+ ASSERT_EQ(a.lpz.lam, coord[0].lpz.lam);
+ ASSERT_EQ(a.lpz.phi, coord[0].lpz.phi);
+ ASSERT_EQ(a.lpz.z, coord[0].lpz.z);
+ ASSERT_EQ(b.lpz.lam, coord[1].lpz.lam);
+ ASSERT_EQ(b.lpz.phi, coord[1].lpz.phi);
+ ASSERT_EQ(b.lpz.z, coord[1].lpz.z);
+
+ /* Clean up after proj_trans_* tests */
+ proj_destroy(P);
+}
+
+// ---------------------------------------------------------------------------
+
+class gieTest : public ::testing::Test {
+
+ static void DummyLogFunction(void *, int, const char *) {}
+
+ protected:
+ void SetUp() override {
+ m_ctxt = proj_context_create();
+ proj_log_func(m_ctxt, nullptr, DummyLogFunction);
+ }
+
+ void TearDown() override { proj_context_destroy(m_ctxt); }
+
+ PJ_CONTEXT *m_ctxt = nullptr;
+};
+
+// ---------------------------------------------------------------------------
+
+TEST_F(gieTest, proj_create_crs_to_crs) {
+ /* test proj_create_crs_to_crs() */
+ auto P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833",
+ NULL);
+ ASSERT_TRUE(P != nullptr);
+ PJ_COORD a, b;
+
+ 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);
+ EXPECT_NEAR(a.xy.x, b.xy.x, 1e-9);
+ EXPECT_NEAR(a.xy.y, b.xy.y, 1e-9);
+ proj_destroy(P);
+
+ /* we can also allow PROJ strings as 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);
+ ASSERT_TRUE(P != nullptr);
+ proj_destroy(P);
+
+ EXPECT_TRUE(proj_create_crs_to_crs(m_ctxt, "invalid", "EPSG:25833", NULL) ==
+ nullptr);
+ EXPECT_TRUE(proj_create_crs_to_crs(m_ctxt, "EPSG:25832", "invalid", NULL) ==
+ nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(gieTest, proj_create_crs_to_crs_EPSG_4326) {
+
+ auto P =
+ proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4326", "EPSG:32631", NULL);
+ ASSERT_TRUE(P != nullptr);
+ PJ_COORD a, b;
+
+ // Lat, long degrees
+ a.xy.x = 0.0;
+ a.xy.y = 3.0;
+
+ b.xy.x = 500000.0;
+ b.xy.y = 0.0;
+
+ a = proj_trans(P, PJ_FWD, a);
+ EXPECT_NEAR(a.xy.x, b.xy.x, 1e-9);
+ EXPECT_NEAR(a.xy.y, b.xy.y, 1e-9);
+ proj_destroy(P);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(gieTest, proj_create_crs_to_crs_proj_longlat) {
+
+ auto P = proj_create_crs_to_crs(
+ PJ_DEFAULT_CTX, "+proj=longlat +datum=WGS84", "EPSG:32631", NULL);
+ ASSERT_TRUE(P != nullptr);
+ PJ_COORD a, b;
+
+ // Long, lat degrees
+ a.xy.x = 3.0;
+ a.xy.y = 0;
+
+ b.xy.x = 500000.0;
+ b.xy.y = 0.0;
+
+ a = proj_trans(P, PJ_FWD, a);
+ EXPECT_NEAR(a.xy.x, b.xy.x, 1e-9);
+ EXPECT_NEAR(a.xy.y, b.xy.y, 1e-9);
+ proj_destroy(P);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(gie, info_functions) {
+ 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;
+
+ char buf[40];
+ PJ *P;
+ char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"};
+ PJ_COORD a;
+
+ /* ********************************************************************** */
+ /* 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);
+ ASSERT_EQ(std::string(info.version), std::string(tmpstr));
+ }
+ ASSERT_NE(std::string(info.release), "");
+ if (getenv("HOME") || getenv("PROJ_LIB")) {
+ ASSERT_NE(std::string(info.searchpath), std::string());
+ }
+
+ /* proj_pj_info() */
+ {
+ P = proj_create(PJ_DEFAULT_CTX,
+ "+proj=august"); /* august has no inverse */
+ auto has_inverse = proj_pj_info(P).has_inverse;
+ proj_destroy(P);
+ ASSERT_FALSE(has_inverse);
+ }
+
+ P = proj_create(PJ_DEFAULT_CTX, arg);
+ pj_info = proj_pj_info(P);
+ ASSERT_TRUE(pj_info.has_inverse);
+ pj_shrink(arg);
+ ASSERT_EQ(std::string(pj_info.definition), arg);
+ ASSERT_EQ(std::string(pj_info.id), "utm");
+
+ proj_destroy(P);
+
+ /* proj_grid_info() */
+ grid_info = proj_grid_info("null");
+ ASSERT_NE(std::string(grid_info.filename), "");
+ ASSERT_EQ(std::string(grid_info.gridname), "null");
+
+ grid_info = proj_grid_info("nonexistinggrid");
+ ASSERT_EQ(std::string(grid_info.filename), "");
+
+ /* proj_init_info() */
+ init_info = proj_init_info("unknowninit");
+ ASSERT_EQ(std::string(init_info.filename), "");
+
+ init_info = proj_init_info("epsg");
+ /* Need to allow for "Unknown" until all commonly distributed EPSG-files
+ * comes with a metadata section */
+ ASSERT_TRUE(std::string(init_info.origin) == "EPSG" ||
+ std::string(init_info.origin) == "Unknown")
+ << std::string(init_info.origin);
+ ASSERT_EQ(std::string(init_info.name), "epsg");
+
+ /* test proj_rtodms() and proj_dmstor() */
+ ASSERT_EQ(std::string("180dN"), proj_rtodms(buf, M_PI, 'N', 'S'));
+
+ ASSERT_EQ(proj_dmstor(&buf[0], NULL), M_PI);
+
+ ASSERT_EQ(std::string("114d35'29.612\"S"),
+ proj_rtodms(buf, -2.0, 'N', 'S'));
+
+ /* we can't expect perfect numerical accuracy so testing with a tolerance */
+ ASSERT_NEAR(-2.0, proj_dmstor(&buf[0], NULL), 1e-7);
+
+ /* 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 = proj_torad(12);
+ a.lp.phi = proj_torad(55);
+
+ factors = proj_factors(P, a);
+ ASSERT_FALSE(proj_errno(P)); /* factors not created correctly */
+
+ /* check a few key characteristics of the Mercator projection */
+ ASSERT_EQ(factors.angular_distortion,
+ 0.0); /* angular distortion should be 0 */
+ ASSERT_EQ(factors.meridian_parallel_angle,
+ M_PI_2); /* Meridian/parallel angle should be 90 deg */
+ ASSERT_EQ(factors.meridian_convergence,
+ 0.0); /* meridian convergence should be 0 */
+
+ proj_destroy(P);
+
+ /* Check that proj_list_* functions work by looping through them */
+ size_t n = 0;
+ for (oper_list = proj_list_operations(); oper_list->id; ++oper_list)
+ n++;
+ ASSERT_NE(n, 0U);
+
+ n = 0;
+ for (ellps_list = proj_list_ellps(); ellps_list->id; ++ellps_list)
+ n++;
+ ASSERT_NE(n, 0U);
+
+ n = 0;
+ for (unit_list = proj_list_units(); unit_list->id; ++unit_list)
+ n++;
+ ASSERT_NE(n, 0U);
+
+ n = 0;
+ for (pm_list = proj_list_prime_meridians(); pm_list->id; ++pm_list)
+ n++;
+ ASSERT_NE(n, 0U);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(gie, io_predicates) {
+ /* check io-predicates */
+
+ /* angular in on fwd, linear out */
+ auto P = proj_create(PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80");
+ ASSERT_TRUE(P != nullptr);
+ ASSERT_TRUE(proj_angular_input(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_input(P, PJ_INV));
+ ASSERT_FALSE(proj_angular_output(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_output(P, PJ_INV));
+ P->inverted = 1;
+ ASSERT_FALSE(proj_angular_input(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_input(P, PJ_INV));
+ ASSERT_TRUE(proj_angular_output(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_output(P, PJ_INV));
+ 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 ");
+ ASSERT_TRUE(P != nullptr);
+ ASSERT_TRUE(proj_angular_input(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_input(P, PJ_INV));
+ ASSERT_TRUE(proj_angular_output(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_output(P, PJ_INV));
+ P->inverted = 1;
+ ASSERT_TRUE(proj_angular_input(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_input(P, PJ_INV));
+ ASSERT_TRUE(proj_angular_output(P, PJ_FWD));
+ ASSERT_TRUE(proj_angular_output(P, PJ_INV));
+ 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 +convention=coordinate_frame +no_defs");
+ ASSERT_TRUE(P != nullptr);
+ ASSERT_FALSE(proj_angular_input(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_input(P, PJ_INV));
+ ASSERT_FALSE(proj_angular_output(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_output(P, PJ_INV));
+ P->inverted = 1;
+ ASSERT_FALSE(proj_angular_input(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_input(P, PJ_INV));
+ ASSERT_FALSE(proj_angular_output(P, PJ_FWD));
+ ASSERT_FALSE(proj_angular_output(P, PJ_INV));
+
+ /* We specified "no_defs" but didn't give any ellipsoid info */
+ /* pj_init_ctx should default to WGS84 */
+ ASSERT_EQ(P->a, 6378137.0);
+ ASSERT_EQ(P->f, 1.0 / 298.257223563);
+ proj_destroy(P);
+
+ /* Test that pj_fwd* and pj_inv* returns NaNs when receiving NaN input */
+ P = proj_create(PJ_DEFAULT_CTX, "+proj=merc");
+ ASSERT_TRUE(P != nullptr);
+ auto a = proj_coord(NAN, NAN, NAN, NAN);
+ a = proj_trans(P, PJ_FWD, a);
+ ASSERT_TRUE((std::isnan(a.v[0]) && std::isnan(a.v[1]) &&
+ std::isnan(a.v[2]) && std::isnan(a.v[3])));
+
+ a = proj_coord(NAN, NAN, NAN, NAN);
+ a = proj_trans(P, PJ_INV, a);
+ ASSERT_TRUE((std::isnan(a.v[0]) && std::isnan(a.v[1]) &&
+ std::isnan(a.v[2]) && std::isnan(a.v[3])));
+ proj_destroy(P);
+}
+
+// ---------------------------------------------------------------------------
+
+static void 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);
+
+ ASSERT_TRUE(P != 0);
+
+ in = proj_coord(0.0, 0.0, 0.0, t_in);
+
+ out = proj_trans(P, PJ_FWD, in);
+ EXPECT_NEAR(out.xyzt.t, t_exp, tol);
+
+ out = proj_trans(P, PJ_INV, out);
+ EXPECT_NEAR(out.xyzt.t, t_in, tol);
+
+ pj_free(P);
+
+ proj_log_level(NULL, PJ_LOG_NONE);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(gie, unitconvert_selftest) {
+
+ 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;
+
+ test_time(args1, 1e-6, in1, in1);
+ test_time(args2, 1e-6, in2, in2);
+ test_time(args3, 1e-6, in3, in3);
+ test_time(args4, 1e-6, in4, exp4);
+ test_time(args5, 1e-6, in5, in5);
+}
+
+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"};
+
+// ---------------------------------------------------------------------------
+
+TEST(gie, horner_selftest) {
+
+ 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);
+ ASSERT_TRUE(P != nullptr);
+
+ 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);
+ EXPECT_LE(dist, 0.01);
+ proj_destroy(P);
+
+ /* The complex polynomial transformation between the "System Storebaelt" and
+ * utm32/ed50 */
+ P = proj_create(PJ_DEFAULT_CTX, sb_utm32);
+ ASSERT_TRUE(P != nullptr);
+
+ /* 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);
+ EXPECT_LE(dist, 0.001);
+
+ /* Inverse projection */
+ b = proj_trans(P, PJ_INV, c);
+ dist = proj_xy_dist(b, a);
+ EXPECT_LE(dist, 0.001);
+
+ /* Check roundtrip precision for 1 iteration each way */
+ dist = proj_roundtrip(P, PJ_FWD, 1, &a);
+ EXPECT_LE(dist, 0.01);
+
+ proj_destroy(P);
+}
+
+} // namespace
diff --git a/test/unit/main.cpp b/test/unit/main.cpp
index f24a7aa6..d53e4236 100644
--- a/test/unit/main.cpp
+++ b/test/unit/main.cpp
@@ -31,9 +31,9 @@
#include "gtest_include.h"
GTEST_API_ int main(int argc, char **argv) {
- // Use a potentially non-C locale to make sure we are robust
- setlocale(LC_ALL, "");
+ // Use a potentially non-C locale to make sure we are robust
+ setlocale(LC_ALL, "");
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
}
diff --git a/test/unit/pj_phi2_test.cpp b/test/unit/pj_phi2_test.cpp
index 186bcbc5..67441b69 100644
--- a/test/unit/pj_phi2_test.cpp
+++ b/test/unit/pj_phi2_test.cpp
@@ -60,7 +60,6 @@ TEST(PjPhi2Test, Basic) {
EXPECT_TRUE(std::isnan(pj_phi2(ctx, -M_PI, -M_PI)));
}
-
TEST(PjPhi2Test, AvoidUndefinedBehavior) {
auto ctx = pj_get_default_ctx();
@@ -82,4 +81,4 @@ TEST(PjPhi2Test, AvoidUndefinedBehavior) {
EXPECT_TRUE(std::isnan(pj_phi2(ctx, -inf, -inf)));
}
-} // namespace
+} // namespace
diff --git a/test/unit/pj_transform_test.cpp b/test/unit/pj_transform_test.cpp
new file mode 100644
index 00000000..95329bdb
--- /dev/null
+++ b/test/unit/pj_transform_test.cpp
@@ -0,0 +1,583 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: Test pj_transform() legacy interface
+ * 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.
+ ****************************************************************************/
+
+#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
+
+#include "gtest_include.h"
+#include <memory>
+
+// PROJ include order is sensitive
+// clang-format off
+#include <projects.h>
+#include <proj_api.h>
+// clang-format on
+
+namespace {
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_longlat) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_EQ(x, 2 * DEG_TO_RAD);
+ EXPECT_EQ(y, 49 * DEG_TO_RAD);
+
+ x = 182 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_EQ(x, 182 * DEG_TO_RAD);
+ EXPECT_EQ(y, 49 * DEG_TO_RAD);
+
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_proj) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
+ double x = 3 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 500000, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_proj_tometer) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84 +to_meter=1000");
+ double x = 3 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 500, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, proj_to_longlat) {
+ auto src = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 500000;
+ double y = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 3 * DEG_TO_RAD, 1e-12);
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, proj_to_proj) {
+ auto src = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
+ auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
+ double x = 500000;
+ double y = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 500000, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_geocent) {
+ auto src = pj_init_plus("+proj=longlat +R=2");
+ auto dst = pj_init_plus("+proj=geocent +R=2");
+ double x = 0;
+ double y = 0;
+ double z = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ EXPECT_NEAR(z, 0, 1e-8);
+
+ x = 90 * DEG_TO_RAD;
+ y = 0;
+ z = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 0, 1e-8);
+ EXPECT_NEAR(y, 2, 1e-8);
+ EXPECT_NEAR(z, 0, 1e-8);
+
+ x = 0;
+ y = 90 * DEG_TO_RAD;
+ z = 0.1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 0, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ EXPECT_NEAR(z, 2 + 0.1, 1e-8);
+
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_geocent_to_meter) {
+ auto src = pj_init_plus("+proj=longlat +R=2");
+ auto dst = pj_init_plus("+proj=geocent +R=2 +to_meter=1000");
+ double x = 0;
+ double y = 0;
+ double z = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2e-3, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ EXPECT_NEAR(z, 0, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, geocent_to_longlat) {
+ auto src = pj_init_plus("+proj=geocent +R=2");
+ auto dst = pj_init_plus("+proj=longlat +R=2");
+ double x = 0;
+ double y = 2;
+ double z = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 0, 1e-12);
+
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, geocent_to_meter_to_longlat) {
+ auto src = pj_init_plus("+proj=geocent +to_meter=1000 +R=2");
+ auto dst = pj_init_plus("+proj=longlat +R=2");
+ double x = 0;
+ double y = 2e-3;
+ double z = 0;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 0, 1e-12);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, pm) {
+ auto src = pj_init_plus("+proj=longlat +pm=3 +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +pm=1 +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, (2 + 3 - 1) * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_EQ(y, 49 * DEG_TO_RAD) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_geoc_to_longlat) {
+ auto src = pj_init_plus("+proj=longlat +geoc +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 48.809360314691766 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_to_longlat_geoc) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +geoc +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 48.809360314691766 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, ellps_to_ellps_noop) {
+ auto src = pj_init_plus("+proj=longlat +ellps=clrk66");
+ auto dst = pj_init_plus("+proj=longlat +ellps=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, towgs84_3param_noop) {
+ auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3");
+ auto dst = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 10;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, towgs84_7param_noop) {
+ auto src =
+ pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7");
+ auto dst =
+ pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 10;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_towgs84_3param_to_datum) {
+ auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 90 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ double z = 10;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10 + 1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_towgs84_3param_to_datum_no_z) {
+ auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 90 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_towgs84_7param_to_datum) {
+ auto src =
+ pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0,0,0,0,0.5");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 90 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ double z = 10;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 14.189073500223458, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, datum_to_longlat_towgs84_3param) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
+ double x = 90 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ double z = 10 + 1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, datum_to_longlat_towgs84_7param) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst =
+ pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0,0,0,0,0.5");
+ double x = 90 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ double z = 14.189073500223458;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, ellps_grs80_towgs84_to_datum_wgs84) {
+ auto src = pj_init_plus("+proj=longlat +ellps=GRS80 +towgs84=0,0,0");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 10;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-15) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-15) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, longlat_nadgrids_to_datum) {
+ auto src = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
+ auto dst = pj_init_plus("+proj=longlat +datum=NAD83");
+ double x = -100 * DEG_TO_RAD;
+ double y = 40 * DEG_TO_RAD;
+ double z = 10;
+ int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
+ EXPECT_TRUE(ret == 0 || ret == PJD_ERR_FAILED_TO_LOAD_GRID);
+ if (ret == 0) {
+ EXPECT_NEAR(x, -100.00040583667015 * DEG_TO_RAD, 1e-12)
+ << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 40.000005895651363 * DEG_TO_RAD, 1e-12)
+ << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10.000043224543333, 1e-8);
+ }
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, nadgrids_noop) {
+ auto src = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
+ auto dst = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
+ double x = -100 * DEG_TO_RAD;
+ double y = 40 * DEG_TO_RAD;
+ double z = 10;
+ int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
+ EXPECT_TRUE(ret == 0);
+ if (ret == 0) {
+ EXPECT_NEAR(x, -100 * DEG_TO_RAD, 1e-15) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 40 * DEG_TO_RAD, 1e-15) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ }
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, datum_to_longlat_nadgrids) {
+ auto src = pj_init_plus("+proj=longlat +datum=NAD83");
+ auto dst = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
+ double x = -100.00040583667015 * DEG_TO_RAD;
+ double y = 40.000005895651363 * DEG_TO_RAD;
+ double z = 10.000043224543333;
+ int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
+ EXPECT_TRUE(ret == 0 || ret == PJD_ERR_FAILED_TO_LOAD_GRID);
+ if (ret == 0) {
+ EXPECT_NEAR(x, -100 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 40 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 10, 1e-8);
+ }
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, long_wrap) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +lon_wrap=180");
+ double x = -1 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 359 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, src_vto_meter) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84 +vto_meter=1000");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 1000, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, dest_vto_meter) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +vto_meter=1000");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 1000;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, src_axis_neu_with_z) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 49 * DEG_TO_RAD;
+ double y = 2 * DEG_TO_RAD;
+ double z = 1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, src_axis_neu_without_z) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 49 * DEG_TO_RAD;
+ double y = 2 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, src_axis_swd) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=swd");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
+ double x = 49 * DEG_TO_RAD;
+ double y = 2 * DEG_TO_RAD;
+ double z = -1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, -2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, -49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, dst_axis_neu) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, 49 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, 2 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, 1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, dst_axis_swd) {
+ auto src = pj_init_plus("+proj=longlat +datum=WGS84");
+ auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +axis=swd");
+ double x = 2 * DEG_TO_RAD;
+ double y = 49 * DEG_TO_RAD;
+ double z = 1;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
+ EXPECT_NEAR(x, -49 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
+ EXPECT_NEAR(y, -2 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
+ EXPECT_NEAR(z, -1, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(pj_transform_test, init_epsg) {
+ auto src = pj_init_plus("+init=epsg:4326");
+ ASSERT_TRUE(src != nullptr);
+ auto dst = pj_init_plus("+init=epsg:32631");
+ double x = 3 * DEG_TO_RAD;
+ double y = 0 * DEG_TO_RAD;
+ EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
+ EXPECT_NEAR(x, 500000, 1e-8);
+ EXPECT_NEAR(y, 0, 1e-8);
+ pj_free(src);
+ pj_free(dst);
+}
+
+} // namespace
diff --git a/test/unit/proj_errno_string_test.cpp b/test/unit/proj_errno_string_test.cpp
index 92840d34..dcdff5c4 100644
--- a/test/unit/proj_errno_string_test.cpp
+++ b/test/unit/proj_errno_string_test.cpp
@@ -34,18 +34,20 @@
namespace {
-TEST(ProjErrnoStringTest, NoError) {
- EXPECT_EQ(0, proj_errno_string(0));
-}
+TEST(ProjErrnoStringTest, NoError) { EXPECT_EQ(0, proj_errno_string(0)); }
TEST(ProjErrnoStringTest, ProjErrnos) {
EXPECT_STREQ("no arguments in initialization list", proj_errno_string(-1));
- EXPECT_STREQ("invalid projection system error (-1000)", proj_errno_string(-1000));
- EXPECT_STREQ("invalid projection system error (-9999)", proj_errno_string(-9999));
+ EXPECT_STREQ("invalid projection system error (-1000)",
+ proj_errno_string(-1000));
+ EXPECT_STREQ("invalid projection system error (-9999)",
+ proj_errno_string(-9999));
// for errnos < -9999, -9999 is always returned
const int min = std::numeric_limits<int>::min();
- EXPECT_STREQ("invalid projection system error (-9999)",proj_errno_string(min));
- EXPECT_STREQ("invalid projection system error (-9999)", proj_errno_string(-10000));
+ EXPECT_STREQ("invalid projection system error (-9999)",
+ proj_errno_string(min));
+ EXPECT_STREQ("invalid projection system error (-9999)",
+ proj_errno_string(-10000));
}
TEST(ProjErrnoStringTest, SystemErrnos) {
@@ -65,4 +67,4 @@ TEST(ProjErrnoStringTest, SystemErrnos) {
#endif
}
-} // namespace
+} // namespace
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 8c9f114b..7db38601 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -29,6 +29,7 @@
#include "gtest_include.h"
#include "proj.h"
+#include "proj_experimental.h"
#include "proj/common.hpp"
#include "proj/coordinateoperation.hpp"
@@ -198,13 +199,14 @@ TEST_F(CApi, proj_obj_as_wkt) {
ASSERT_NE(obj, nullptr);
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018, nullptr);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT2_2018, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEOGCRS[") == 0) << wkt;
}
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018_SIMPLIFIED, nullptr);
+ auto wkt =
+ proj_obj_as_wkt(m_ctxt, obj, PJ_WKT2_2018_SIMPLIFIED, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEOGCRS[") == 0) << wkt;
EXPECT_TRUE(std::string(wkt).find("ANGULARUNIT[") == std::string::npos)
@@ -212,13 +214,14 @@ TEST_F(CApi, proj_obj_as_wkt) {
}
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2015, nullptr);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT2_2015, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEODCRS[") == 0) << wkt;
}
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2015_SIMPLIFIED, nullptr);
+ auto wkt =
+ proj_obj_as_wkt(m_ctxt, obj, PJ_WKT2_2015_SIMPLIFIED, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEODCRS[") == 0) << wkt;
EXPECT_TRUE(std::string(wkt).find("ANGULARUNIT[") == std::string::npos)
@@ -226,13 +229,13 @@ TEST_F(CApi, proj_obj_as_wkt) {
}
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, nullptr);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEOGCS[\"WGS 84\"") == 0) << wkt;
}
{
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_ESRI, nullptr);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_ESRI, nullptr);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("GEOGCS[\"GCS_WGS_1984\"") == 0)
<< wkt;
@@ -241,7 +244,7 @@ TEST_F(CApi, proj_obj_as_wkt) {
// MULTILINE=NO
{
const char *const options[] = {"MULTILINE=NO", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, options);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("\n") == std::string::npos) << wkt;
}
@@ -249,7 +252,7 @@ TEST_F(CApi, proj_obj_as_wkt) {
// INDENTATION_WIDTH=2
{
const char *const options[] = {"INDENTATION_WIDTH=2", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, options);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("\n DATUM") != std::string::npos)
<< wkt;
@@ -258,7 +261,7 @@ TEST_F(CApi, proj_obj_as_wkt) {
// OUTPUT_AXIS=NO
{
const char *const options[] = {"OUTPUT_AXIS=NO", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, options);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("AXIS") == std::string::npos) << wkt;
}
@@ -266,7 +269,7 @@ TEST_F(CApi, proj_obj_as_wkt) {
// OUTPUT_AXIS=AUTO
{
const char *const options[] = {"OUTPUT_AXIS=AUTO", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, options);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("AXIS") == std::string::npos) << wkt;
}
@@ -274,7 +277,7 @@ TEST_F(CApi, proj_obj_as_wkt) {
// OUTPUT_AXIS=YES
{
const char *const options[] = {"OUTPUT_AXIS=YES", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, options);
ASSERT_NE(wkt, nullptr);
EXPECT_TRUE(std::string(wkt).find("AXIS") != std::string::npos) << wkt;
}
@@ -282,13 +285,32 @@ TEST_F(CApi, proj_obj_as_wkt) {
// unsupported option
{
const char *const options[] = {"unsupported=yes", nullptr};
- auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018, options);
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT2_2018, options);
EXPECT_EQ(wkt, nullptr);
}
}
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_obj_as_wkt_check_db_use) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, "GEOGCS[\"AGD66\",DATUM[\"Australian_Geodetic_Datum_1966\","
+ "SPHEROID[\"Australian National Spheroid\",6378160,298.25]],"
+ "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]]",
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto wkt = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_ESRI, nullptr);
+ EXPECT_EQ(std::string(wkt),
+ "GEOGCS[\"GCS_Australian_1966\",DATUM[\"D_Australian_1966\","
+ "SPHEROID[\"Australian\",6378160.0,298.25]],"
+ "PRIMEM[\"Greenwich\",0.0],"
+ "UNIT[\"Degree\",0.0174532925199433]]");
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_obj_as_wkt_incompatible_WKT1) {
auto obj = proj_obj_create_from_wkt(
m_ctxt,
@@ -297,7 +319,7 @@ TEST_F(CApi, proj_obj_as_wkt_incompatible_WKT1) {
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- auto wkt1_GDAL = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, nullptr);
+ auto wkt1_GDAL = proj_obj_as_wkt(m_ctxt, obj, PJ_WKT1_GDAL, nullptr);
ASSERT_EQ(wkt1_GDAL, nullptr);
}
@@ -313,7 +335,7 @@ TEST_F(CApi, proj_obj_as_proj_string) {
ASSERT_NE(obj, nullptr);
{
- auto proj_5 = proj_obj_as_proj_string(obj, PJ_PROJ_5, nullptr);
+ auto proj_5 = proj_obj_as_proj_string(m_ctxt, obj, PJ_PROJ_5, nullptr);
ASSERT_NE(proj_5, nullptr);
EXPECT_EQ(std::string(proj_5), "+proj=pipeline +step +proj=longlat "
"+ellps=WGS84 +step +proj=unitconvert "
@@ -321,7 +343,7 @@ TEST_F(CApi, proj_obj_as_proj_string) {
"+proj=axisswap +order=2,1");
}
{
- auto proj_4 = proj_obj_as_proj_string(obj, PJ_PROJ_4, nullptr);
+ auto proj_4 = proj_obj_as_proj_string(m_ctxt, obj, PJ_PROJ_4, nullptr);
ASSERT_NE(proj_4, nullptr);
EXPECT_EQ(std::string(proj_4), "+proj=longlat +datum=WGS84 +no_defs");
}
@@ -337,7 +359,7 @@ TEST_F(CApi, proj_obj_as_proj_string_incompatible_WKT1) {
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- auto str = proj_obj_as_proj_string(obj, PJ_PROJ_5, nullptr);
+ auto str = proj_obj_as_proj_string(m_ctxt, obj, PJ_PROJ_5, nullptr);
ASSERT_EQ(str, nullptr);
}
@@ -349,7 +371,7 @@ TEST_F(CApi, proj_obj_as_proj_string_etmerc_option_yes) {
ASSERT_NE(obj, nullptr);
const char *options[] = {"USE_ETMERC=YES", nullptr};
- auto str = proj_obj_as_proj_string(obj, PJ_PROJ_4, options);
+ auto str = proj_obj_as_proj_string(m_ctxt, obj, PJ_PROJ_4, options);
ASSERT_NE(str, nullptr);
EXPECT_EQ(str, std::string("+proj=etmerc +lat_0=0 +lon_0=0 +k=1 +x_0=0 "
"+y_0=0 +datum=WGS84 +units=m +no_defs"));
@@ -364,7 +386,7 @@ TEST_F(CApi, proj_obj_as_proj_string_etmerc_option_no) {
ASSERT_NE(obj, nullptr);
const char *options[] = {"USE_ETMERC=NO", nullptr};
- auto str = proj_obj_as_proj_string(obj, PJ_PROJ_4, options);
+ auto str = proj_obj_as_proj_string(m_ctxt, obj, PJ_PROJ_4, options);
ASSERT_NE(str, nullptr);
EXPECT_EQ(str, std::string("+proj=tmerc +lat_0=0 +lon_0=3 +k=0.9996 "
"+x_0=500000 +y_0=0 +datum=WGS84 +units=m "
@@ -379,17 +401,37 @@ TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84) {
ObjectKeeper keeper(crs);
ASSERT_NE(crs, nullptr);
- auto res = proj_obj_crs_create_bound_crs_to_WGS84(crs);
+ auto res = proj_obj_crs_create_bound_crs_to_WGS84(m_ctxt, crs);
ObjectKeeper keeper_res(res);
ASSERT_NE(res, nullptr);
- auto proj_4 = proj_obj_as_proj_string(res, PJ_PROJ_4, nullptr);
+ auto proj_4 = proj_obj_as_proj_string(m_ctxt, res, PJ_PROJ_4, nullptr);
ASSERT_NE(proj_4, nullptr);
EXPECT_EQ(std::string(proj_4),
"+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 "
"+y_0=500000 +ellps=krass "
"+towgs84=2.329,-147.042,-92.08,-0.309,0.325,0.497,5.69 "
"+units=m +no_defs");
+
+ auto base_crs = proj_obj_get_source_crs(m_ctxt, res);
+ ObjectKeeper keeper_base_crs(base_crs);
+ ASSERT_NE(base_crs, nullptr);
+
+ auto hub_crs = proj_obj_get_target_crs(m_ctxt, res);
+ ObjectKeeper keeper_hub_crs(hub_crs);
+ ASSERT_NE(hub_crs, nullptr);
+
+ auto transf =
+ proj_obj_crs_get_coordoperation(m_ctxt, res, nullptr, nullptr, nullptr);
+ ObjectKeeper keeper_transf(transf);
+ ASSERT_NE(transf, nullptr);
+
+ auto res2 =
+ proj_obj_crs_create_bound_crs(m_ctxt, base_crs, hub_crs, transf);
+ ObjectKeeper keeper_res2(res2);
+ ASSERT_NE(res2, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(res, res2, PJ_COMP_STRICT));
}
// ---------------------------------------------------------------------------
@@ -404,7 +446,7 @@ TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84_on_invalid_type) {
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- auto res = proj_obj_crs_create_bound_crs_to_WGS84(obj);
+ auto res = proj_obj_crs_create_bound_crs_to_WGS84(m_ctxt, obj);
ASSERT_EQ(res, nullptr);
}
@@ -647,7 +689,7 @@ TEST_F(CApi, proj_crs) {
ObjectKeeper keeper(crs);
EXPECT_TRUE(proj_obj_is_crs(crs));
- auto geodCRS = proj_obj_crs_get_geodetic_crs(crs);
+ auto geodCRS = proj_obj_crs_get_geodetic_crs(m_ctxt, crs);
ASSERT_NE(geodCRS, nullptr);
ObjectKeeper keeper_geogCRS(geodCRS);
EXPECT_TRUE(proj_obj_is_crs(geodCRS));
@@ -655,37 +697,44 @@ TEST_F(CApi, proj_crs) {
ASSERT_TRUE(geogCRS_name != nullptr);
EXPECT_EQ(geogCRS_name, std::string("WGS 84"));
- auto datum = proj_obj_crs_get_horizontal_datum(crs);
+ auto h_datum = proj_obj_crs_get_horizontal_datum(m_ctxt, crs);
+ ASSERT_NE(h_datum, nullptr);
+ ObjectKeeper keeper_h_datum(h_datum);
+
+ auto datum = proj_obj_crs_get_datum(m_ctxt, crs);
ASSERT_NE(datum, nullptr);
ObjectKeeper keeper_datum(datum);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(h_datum, datum, PJ_COMP_STRICT));
+
auto datum_name = proj_obj_get_name(datum);
ASSERT_TRUE(datum_name != nullptr);
EXPECT_EQ(datum_name, std::string("World Geodetic System 1984"));
- auto ellipsoid = proj_obj_get_ellipsoid(crs);
+ auto ellipsoid = proj_obj_get_ellipsoid(m_ctxt, crs);
ASSERT_NE(ellipsoid, nullptr);
ObjectKeeper keeper_ellipsoid(ellipsoid);
auto ellipsoid_name = proj_obj_get_name(ellipsoid);
ASSERT_TRUE(ellipsoid_name != nullptr);
EXPECT_EQ(ellipsoid_name, std::string("WGS 84"));
- auto ellipsoid_from_datum = proj_obj_get_ellipsoid(datum);
+ auto ellipsoid_from_datum = proj_obj_get_ellipsoid(m_ctxt, datum);
ASSERT_NE(ellipsoid_from_datum, nullptr);
ObjectKeeper keeper_ellipsoid_from_datum(ellipsoid_from_datum);
- EXPECT_EQ(proj_obj_get_ellipsoid(ellipsoid), nullptr);
+ EXPECT_EQ(proj_obj_get_ellipsoid(m_ctxt, ellipsoid), nullptr);
EXPECT_FALSE(proj_obj_is_crs(ellipsoid));
double a;
double b;
int b_is_computed;
double rf;
- EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(ellipsoid, nullptr, nullptr,
- nullptr, nullptr));
- EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(ellipsoid, &a, &b,
+ EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(m_ctxt, ellipsoid, nullptr,
+ nullptr, nullptr, nullptr));
+ EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(m_ctxt, ellipsoid, &a, &b,
&b_is_computed, &rf));
- EXPECT_FALSE(
- proj_obj_ellipsoid_get_parameters(crs, &a, &b, &b_is_computed, &rf));
+ EXPECT_FALSE(proj_obj_ellipsoid_get_parameters(m_ctxt, crs, &a, &b,
+ &b_is_computed, &rf));
EXPECT_EQ(a, 6378137);
EXPECT_NEAR(b, 6356752.31424518, 1e-9);
EXPECT_EQ(b_is_computed, 1);
@@ -708,31 +757,31 @@ TEST_F(CApi, proj_obj_get_prime_meridian) {
ASSERT_NE(crs, nullptr);
ObjectKeeper keeper(crs);
- auto pm = proj_obj_get_prime_meridian(crs);
+ auto pm = proj_obj_get_prime_meridian(m_ctxt, crs);
ASSERT_NE(pm, nullptr);
ObjectKeeper keeper_pm(pm);
auto pm_name = proj_obj_get_name(pm);
ASSERT_TRUE(pm_name != nullptr);
EXPECT_EQ(pm_name, std::string("Greenwich"));
- EXPECT_EQ(proj_obj_get_prime_meridian(pm), nullptr);
+ EXPECT_EQ(proj_obj_get_prime_meridian(m_ctxt, pm), nullptr);
- EXPECT_TRUE(
- proj_obj_prime_meridian_get_parameters(pm, nullptr, nullptr, nullptr));
+ EXPECT_TRUE(proj_obj_prime_meridian_get_parameters(m_ctxt, pm, nullptr,
+ nullptr, nullptr));
double longitude = -1;
double longitude_unit = 0;
const char *longitude_unit_name = nullptr;
EXPECT_TRUE(proj_obj_prime_meridian_get_parameters(
- pm, &longitude, &longitude_unit, &longitude_unit_name));
+ m_ctxt, pm, &longitude, &longitude_unit, &longitude_unit_name));
EXPECT_EQ(longitude, 0);
EXPECT_NEAR(longitude_unit, UnitOfMeasure::DEGREE.conversionToSI(), 1e-10);
ASSERT_TRUE(longitude_unit_name != nullptr);
EXPECT_EQ(longitude_unit_name, std::string("degree"));
- auto datum = proj_obj_crs_get_horizontal_datum(crs);
+ auto datum = proj_obj_crs_get_horizontal_datum(m_ctxt, crs);
ASSERT_NE(datum, nullptr);
ObjectKeeper keeper_datum(datum);
- auto pm_from_datum = proj_obj_get_prime_meridian(datum);
+ auto pm_from_datum = proj_obj_get_prime_meridian(m_ctxt, datum);
ASSERT_NE(pm_from_datum, nullptr);
ObjectKeeper keeper_pm_from_datum(pm_from_datum);
}
@@ -748,16 +797,16 @@ TEST_F(CApi, proj_crs_compound) {
ObjectKeeper keeper(crs);
EXPECT_EQ(proj_obj_get_type(crs), PJ_OBJ_TYPE_COMPOUND_CRS);
- EXPECT_EQ(proj_obj_crs_get_sub_crs(crs, -1), nullptr);
- EXPECT_EQ(proj_obj_crs_get_sub_crs(crs, 2), nullptr);
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(m_ctxt, crs, -1), nullptr);
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(m_ctxt, crs, 2), nullptr);
- auto subcrs_horiz = proj_obj_crs_get_sub_crs(crs, 0);
+ auto subcrs_horiz = proj_obj_crs_get_sub_crs(m_ctxt, crs, 0);
ASSERT_NE(subcrs_horiz, nullptr);
ObjectKeeper keeper_subcrs_horiz(subcrs_horiz);
EXPECT_EQ(proj_obj_get_type(subcrs_horiz), PJ_OBJ_TYPE_PROJECTED_CRS);
- EXPECT_EQ(proj_obj_crs_get_sub_crs(subcrs_horiz, 0), nullptr);
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(m_ctxt, subcrs_horiz, 0), nullptr);
- auto subcrs_vertical = proj_obj_crs_get_sub_crs(crs, 1);
+ auto subcrs_vertical = proj_obj_crs_get_sub_crs(m_ctxt, crs, 1);
ASSERT_NE(subcrs_vertical, nullptr);
ObjectKeeper keeper_subcrs_vertical(subcrs_vertical);
EXPECT_EQ(proj_obj_get_type(subcrs_vertical), PJ_OBJ_TYPE_VERTICAL_CRS);
@@ -773,12 +822,12 @@ TEST_F(CApi, proj_obj_get_source_target_crs_bound_crs) {
ASSERT_NE(crs, nullptr);
ObjectKeeper keeper(crs);
- auto sourceCRS = proj_obj_get_source_crs(crs);
+ auto sourceCRS = proj_obj_get_source_crs(m_ctxt, crs);
ASSERT_NE(sourceCRS, nullptr);
ObjectKeeper keeper_sourceCRS(sourceCRS);
EXPECT_EQ(std::string(proj_obj_get_name(sourceCRS)), "NTF (Paris)");
- auto targetCRS = proj_obj_get_target_crs(crs);
+ auto targetCRS = proj_obj_get_target_crs(m_ctxt, crs);
ASSERT_NE(targetCRS, nullptr);
ObjectKeeper keeper_targetCRS(targetCRS);
EXPECT_EQ(std::string(proj_obj_get_name(targetCRS)), "WGS 84");
@@ -796,12 +845,12 @@ TEST_F(CApi, proj_obj_get_source_target_crs_transformation) {
ASSERT_NE(obj, nullptr);
ObjectKeeper keeper(obj);
- auto sourceCRS = proj_obj_get_source_crs(obj);
+ auto sourceCRS = proj_obj_get_source_crs(m_ctxt, obj);
ASSERT_NE(sourceCRS, nullptr);
ObjectKeeper keeper_sourceCRS(sourceCRS);
EXPECT_EQ(std::string(proj_obj_get_name(sourceCRS)), "NTF (Paris)");
- auto targetCRS = proj_obj_get_target_crs(obj);
+ auto targetCRS = proj_obj_get_target_crs(m_ctxt, obj);
ASSERT_NE(targetCRS, nullptr);
ObjectKeeper keeper_targetCRS(targetCRS);
EXPECT_EQ(std::string(proj_obj_get_name(targetCRS)), "WGS 84");
@@ -809,6 +858,22 @@ TEST_F(CApi, proj_obj_get_source_target_crs_transformation) {
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_obj_get_source_crs_of_projected_crs) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ auto sourceCRS = proj_obj_get_source_crs(m_ctxt, crs);
+ ASSERT_NE(sourceCRS, nullptr);
+ ObjectKeeper keeper_sourceCRS(sourceCRS);
+ EXPECT_EQ(std::string(proj_obj_get_name(sourceCRS)), "WGS 84");
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_obj_get_source_target_crs_conversion_without_crs) {
auto obj = proj_obj_create_from_database(
m_ctxt, "EPSG", "16031", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, false,
@@ -816,10 +881,10 @@ TEST_F(CApi, proj_obj_get_source_target_crs_conversion_without_crs) {
ASSERT_NE(obj, nullptr);
ObjectKeeper keeper(obj);
- auto sourceCRS = proj_obj_get_source_crs(obj);
+ auto sourceCRS = proj_obj_get_source_crs(m_ctxt, obj);
ASSERT_EQ(sourceCRS, nullptr);
- auto targetCRS = proj_obj_get_target_crs(obj);
+ auto targetCRS = proj_obj_get_target_crs(m_ctxt, obj);
ASSERT_EQ(targetCRS, nullptr);
}
@@ -831,10 +896,10 @@ TEST_F(CApi, proj_obj_get_source_target_crs_invalid_object) {
ASSERT_NE(obj, nullptr);
ObjectKeeper keeper(obj);
- auto sourceCRS = proj_obj_get_source_crs(obj);
+ auto sourceCRS = proj_obj_get_source_crs(m_ctxt, obj);
ASSERT_EQ(sourceCRS, nullptr);
- auto targetCRS = proj_obj_get_target_crs(obj);
+ auto targetCRS = proj_obj_get_target_crs(m_ctxt, obj);
ASSERT_EQ(targetCRS, nullptr);
}
@@ -923,21 +988,21 @@ TEST_F(CApi, conversion) {
ObjectKeeper keeper(crs);
{
- auto conv =
- proj_obj_crs_get_coordoperation(crs, nullptr, nullptr, nullptr);
+ auto conv = proj_obj_crs_get_coordoperation(m_ctxt, crs, nullptr,
+ nullptr, nullptr);
ASSERT_NE(conv, nullptr);
ObjectKeeper keeper_conv(conv);
- ASSERT_EQ(
- proj_obj_crs_get_coordoperation(conv, nullptr, nullptr, nullptr),
- nullptr);
+ ASSERT_EQ(proj_obj_crs_get_coordoperation(m_ctxt, conv, nullptr,
+ nullptr, nullptr),
+ nullptr);
}
const char *methodName = nullptr;
const char *methodAuthorityName = nullptr;
const char *methodCode = nullptr;
auto conv = proj_obj_crs_get_coordoperation(
- crs, &methodName, &methodAuthorityName, &methodCode);
+ m_ctxt, crs, &methodName, &methodAuthorityName, &methodCode);
ASSERT_NE(conv, nullptr);
ObjectKeeper keeper_conv(conv);
@@ -948,16 +1013,17 @@ TEST_F(CApi, conversion) {
EXPECT_EQ(methodAuthorityName, std::string("EPSG"));
EXPECT_EQ(methodCode, std::string("9807"));
- EXPECT_EQ(proj_coordoperation_get_param_count(conv), 5);
- EXPECT_EQ(proj_coordoperation_get_param_index(conv, "foo"), -1);
- EXPECT_EQ(proj_coordoperation_get_param_index(conv, "False easting"), 3);
+ EXPECT_EQ(proj_coordoperation_get_param_count(m_ctxt, conv), 5);
+ EXPECT_EQ(proj_coordoperation_get_param_index(m_ctxt, conv, "foo"), -1);
+ EXPECT_EQ(
+ proj_coordoperation_get_param_index(m_ctxt, conv, "False easting"), 3);
- EXPECT_FALSE(proj_coordoperation_get_param(conv, -1, nullptr, nullptr,
+ EXPECT_FALSE(proj_coordoperation_get_param(m_ctxt, conv, -1, nullptr,
nullptr, nullptr, nullptr,
- nullptr, nullptr));
- EXPECT_FALSE(proj_coordoperation_get_param(conv, 5, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+ EXPECT_FALSE(proj_coordoperation_get_param(m_ctxt, conv, 5, nullptr,
nullptr, nullptr, nullptr,
- nullptr, nullptr));
+ nullptr, nullptr, nullptr));
const char *name = nullptr;
const char *nameAuthorityName = nullptr;
@@ -967,8 +1033,8 @@ TEST_F(CApi, conversion) {
double valueUnitConvFactor = 0;
const char *valueUnitName = nullptr;
EXPECT_TRUE(proj_coordoperation_get_param(
- conv, 3, &name, &nameAuthorityName, &nameCode, &value, &valueString,
- &valueUnitConvFactor, &valueUnitName));
+ m_ctxt, conv, 3, &name, &nameAuthorityName, &nameCode, &value,
+ &valueString, &valueUnitConvFactor, &valueUnitName));
ASSERT_NE(name, nullptr);
ASSERT_NE(nameAuthorityName, nullptr);
ASSERT_NE(nameCode, nullptr);
@@ -993,7 +1059,7 @@ TEST_F(CApi, transformation_from_boundCRS) {
ObjectKeeper keeper(crs);
auto transf =
- proj_obj_crs_get_coordoperation(crs, nullptr, nullptr, nullptr);
+ proj_obj_crs_get_coordoperation(m_ctxt, crs, nullptr, nullptr, nullptr);
ASSERT_NE(transf, nullptr);
ObjectKeeper keeper_transf(transf);
}
@@ -1007,7 +1073,7 @@ TEST_F(CApi, proj_coordoperation_get_grid_used) {
ASSERT_NE(op, nullptr);
ObjectKeeper keeper(op);
- EXPECT_EQ(proj_coordoperation_get_grid_used_count(op), 1);
+ EXPECT_EQ(proj_coordoperation_get_grid_used_count(m_ctxt, op), 1);
const char *shortName = nullptr;
const char *fullName = nullptr;
const char *packageName = nullptr;
@@ -1015,16 +1081,16 @@ TEST_F(CApi, proj_coordoperation_get_grid_used) {
int directDownload = 0;
int openLicense = 0;
int available = 0;
- EXPECT_EQ(proj_coordoperation_get_grid_used(op, -1, nullptr, nullptr,
+ EXPECT_EQ(proj_coordoperation_get_grid_used(m_ctxt, op, -1, nullptr,
nullptr, nullptr, nullptr,
- nullptr, nullptr),
+ nullptr, nullptr, nullptr),
0);
- EXPECT_EQ(proj_coordoperation_get_grid_used(op, 1, nullptr, nullptr,
+ EXPECT_EQ(proj_coordoperation_get_grid_used(m_ctxt, op, 1, nullptr, nullptr,
nullptr, nullptr, nullptr,
nullptr, nullptr),
0);
EXPECT_EQ(proj_coordoperation_get_grid_used(
- op, 0, &shortName, &fullName, &packageName, &url,
+ m_ctxt, op, 0, &shortName, &fullName, &packageName, &url,
&directDownload, &openLicense, &available),
1);
ASSERT_NE(shortName, nullptr);
@@ -1049,7 +1115,7 @@ TEST_F(CApi, proj_coordoperation_is_instanciable) {
nullptr);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper(op);
- EXPECT_EQ(proj_coordoperation_is_instanciable(op), 1);
+ EXPECT_EQ(proj_coordoperation_is_instanciable(m_ctxt, op), 1);
}
// ---------------------------------------------------------------------------
@@ -1070,20 +1136,21 @@ TEST_F(CApi, proj_obj_create_operations) {
ObjectKeeper keeper_target_crs(target_crs);
proj_operation_factory_context_set_spatial_criterion(
- ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ m_ctxt, ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
proj_operation_factory_context_set_grid_availability_use(
- ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+ m_ctxt, ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
- auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ auto res = proj_obj_create_operations(m_ctxt, source_crs, target_crs, ctxt);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
- EXPECT_EQ(proj_obj_list_get_count(res), 7);
+ EXPECT_EQ(proj_obj_list_get_count(res), 8);
- EXPECT_EQ(proj_obj_list_get(res, -1), nullptr);
- EXPECT_EQ(proj_obj_list_get(res, proj_obj_list_get_count(res)), nullptr);
- auto op = proj_obj_list_get(res, 0);
+ EXPECT_EQ(proj_obj_list_get(m_ctxt, res, -1), nullptr);
+ EXPECT_EQ(proj_obj_list_get(m_ctxt, res, proj_obj_list_get_count(res)),
+ nullptr);
+ auto op = proj_obj_list_get(m_ctxt, res, 0);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper_op(op);
@@ -1112,11 +1179,12 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) {
ASSERT_NE(ctxt, nullptr);
ContextKeeper keeper_ctxt(ctxt);
- auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ auto res =
+ proj_obj_create_operations(m_ctxt, source_crs, target_crs, ctxt);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
EXPECT_EQ(proj_obj_list_get_count(res), 1);
- auto op = proj_obj_list_get(res, 0);
+ auto op = proj_obj_list_get(m_ctxt, res, 0);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper_op(op);
@@ -1131,14 +1199,15 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) {
auto ctxt = proj_create_operation_factory_context(m_ctxt, nullptr);
ASSERT_NE(ctxt, nullptr);
ContextKeeper keeper_ctxt(ctxt);
- proj_operation_factory_context_set_allow_use_intermediate_crs(ctxt,
- false);
+ proj_operation_factory_context_set_allow_use_intermediate_crs(
+ m_ctxt, ctxt, false);
- auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ auto res =
+ proj_obj_create_operations(m_ctxt, source_crs, target_crs, ctxt);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
EXPECT_EQ(proj_obj_list_get_count(res), 1);
- auto op = proj_obj_list_get(res, 0);
+ auto op = proj_obj_list_get(m_ctxt, res, 0);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper_op(op);
@@ -1153,18 +1222,19 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) {
ContextKeeper keeper_ctxt(ctxt);
const char *pivots[] = {"EPSG", "4301", nullptr};
- proj_operation_factory_context_set_allowed_intermediate_crs(ctxt,
- pivots);
+ proj_operation_factory_context_set_allowed_intermediate_crs(
+ m_ctxt, ctxt, pivots);
proj_operation_factory_context_set_spatial_criterion(
- ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ m_ctxt, ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
proj_operation_factory_context_set_grid_availability_use(
- ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+ m_ctxt, ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
- auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ auto res =
+ proj_obj_create_operations(m_ctxt, source_crs, target_crs, ctxt);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
- EXPECT_EQ(proj_obj_list_get_count(res), 6);
- auto op = proj_obj_list_get(res, 0);
+ EXPECT_EQ(proj_obj_list_get_count(res), 7);
+ auto op = proj_obj_list_get(m_ctxt, res, 1);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper_op(op);
@@ -1181,19 +1251,20 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) {
ContextKeeper keeper_ctxt(ctxt);
const char *pivots[] = {"EPSG", "4612", nullptr};
- proj_operation_factory_context_set_allowed_intermediate_crs(ctxt,
- pivots);
+ proj_operation_factory_context_set_allowed_intermediate_crs(
+ m_ctxt, ctxt, pivots);
proj_operation_factory_context_set_spatial_criterion(
- ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ m_ctxt, ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
proj_operation_factory_context_set_grid_availability_use(
- ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+ m_ctxt, ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
- auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ auto res =
+ proj_obj_create_operations(m_ctxt, source_crs, target_crs, ctxt);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
// includes 2 results from ESRI
- EXPECT_EQ(proj_obj_list_get_count(res), 4);
- auto op = proj_obj_list_get(res, 0);
+ EXPECT_EQ(proj_obj_list_get_count(res), 5);
+ auto op = proj_obj_list_get(m_ctxt, res, 0);
ASSERT_NE(op, nullptr);
ObjectKeeper keeper_op(op);
@@ -1364,13 +1435,13 @@ TEST_F(CApi, proj_obj_identify) {
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
{
- auto res = proj_obj_identify(obj, nullptr, nullptr, nullptr);
+ auto res = proj_obj_identify(m_ctxt, obj, nullptr, nullptr, nullptr);
ObjListKeeper keeper_res(res);
EXPECT_EQ(proj_obj_list_get_count(res), 1);
}
{
int *confidence = nullptr;
- auto res = proj_obj_identify(obj, "EPSG", nullptr, &confidence);
+ auto res = proj_obj_identify(m_ctxt, obj, "EPSG", nullptr, &confidence);
ObjListKeeper keeper_res(res);
EXPECT_EQ(proj_obj_list_get_count(res), 1);
EXPECT_EQ(confidence[0], 100);
@@ -1383,7 +1454,8 @@ TEST_F(CApi, proj_obj_identify) {
.c_str(),
nullptr);
ObjectKeeper keeperEllps(objEllps);
- auto res = proj_obj_identify(objEllps, nullptr, nullptr, nullptr);
+ auto res =
+ proj_obj_identify(m_ctxt, objEllps, nullptr, nullptr, nullptr);
ObjListKeeper keeper_res(res);
EXPECT_EQ(res, nullptr);
}
@@ -1397,14 +1469,15 @@ TEST_F(CApi, proj_obj_get_area_of_use) {
m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
ASSERT_NE(crs, nullptr);
ObjectKeeper keeper(crs);
- EXPECT_TRUE(proj_obj_get_area_of_use(crs, nullptr, nullptr, nullptr,
- nullptr, nullptr));
+ EXPECT_TRUE(proj_obj_get_area_of_use(m_ctxt, crs, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
const char *name = nullptr;
double w;
double s;
double e;
double n;
- EXPECT_TRUE(proj_obj_get_area_of_use(crs, &w, &s, &e, &n, &name));
+ EXPECT_TRUE(
+ proj_obj_get_area_of_use(m_ctxt, crs, &w, &s, &e, &n, &name));
EXPECT_EQ(w, -180);
EXPECT_EQ(s, -90);
EXPECT_EQ(e, 180);
@@ -1417,8 +1490,8 @@ TEST_F(CApi, proj_obj_get_area_of_use) {
proj_obj_create_from_user_input(m_ctxt, "+proj=longlat", nullptr);
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- EXPECT_FALSE(proj_obj_get_area_of_use(obj, nullptr, nullptr, nullptr,
- nullptr, nullptr));
+ EXPECT_FALSE(proj_obj_get_area_of_use(m_ctxt, obj, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
}
}
@@ -1430,7 +1503,7 @@ TEST_F(CApi, proj_coordoperation_get_accuracy) {
m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
ASSERT_NE(crs, nullptr);
ObjectKeeper keeper(crs);
- EXPECT_EQ(proj_coordoperation_get_accuracy(crs), -1.0);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(m_ctxt, crs), -1.0);
}
{
auto obj = proj_obj_create_from_database(
@@ -1438,25 +1511,30 @@ TEST_F(CApi, proj_coordoperation_get_accuracy) {
nullptr);
ASSERT_NE(obj, nullptr);
ObjectKeeper keeper(obj);
- EXPECT_EQ(proj_coordoperation_get_accuracy(obj), 16.0);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(m_ctxt, obj), 16.0);
}
{
auto obj =
proj_obj_create_from_user_input(m_ctxt, "+proj=helmert", nullptr);
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- EXPECT_EQ(proj_coordoperation_get_accuracy(obj), -1.0);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(m_ctxt, obj), -1.0);
}
}
// ---------------------------------------------------------------------------
TEST_F(CApi, proj_obj_create_geographic_crs) {
+
+ auto cs = proj_obj_create_ellipsoidal_2D_cs(
+ m_ctxt, PJ_ELLPS2D_LATITUDE_LONGITUDE, nullptr, 0);
+ ObjectKeeper keeper_cs(cs);
+ ASSERT_NE(cs, nullptr);
+
{
auto obj = proj_obj_create_geographic_crs(
m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
- 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433,
- true);
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
@@ -1469,490 +1547,822 @@ TEST_F(CApi, proj_obj_create_geographic_crs) {
EXPECT_NE(objRef, nullptr);
EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+
+ auto datum = proj_obj_crs_get_datum(m_ctxt, obj);
+ ObjectKeeper keeper_datum(datum);
+ ASSERT_NE(datum, nullptr);
+
+ auto obj2 = proj_obj_create_geographic_crs_from_datum(m_ctxt, "WGS 84",
+ datum, cs);
+ ObjectKeeper keeperObj(obj2);
+ ASSERT_NE(obj2, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, obj2, PJ_COMP_STRICT));
}
{
auto obj = proj_obj_create_geographic_crs(m_ctxt, nullptr, nullptr,
nullptr, 1.0, 0.0, nullptr,
- 0.0, nullptr, 0.0, false);
+ 0.0, nullptr, 0.0, cs);
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
}
+
+ // Datum with GDAL_WKT1 spelling: special case of WGS_1984
+ {
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "WGS_1984", "WGS 84", 6378137, 298.257223563,
+ "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+ }
+
+ // Datum with GDAL_WKT1 spelling: database query
+ {
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "NAD83", "North_American_Datum_1983", "GRS 1980", 6378137,
+ 298.257222101, "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4269->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+ }
}
// ---------------------------------------------------------------------------
-TEST_F(CApi, proj_obj_create_projections) {
+TEST_F(CApi, proj_obj_create_geocentric_crs) {
+ {
+ auto obj = proj_obj_create_geocentric_crs(
+ m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
- auto geogCRS = proj_obj_create_geographic_crs(
- m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
- 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433, true);
- ObjectKeeper keepergeogCRS(geogCRS);
- ASSERT_NE(geogCRS, nullptr);
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4978->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+
+ auto datum = proj_obj_crs_get_datum(m_ctxt, obj);
+ ObjectKeeper keeper_datum(datum);
+ ASSERT_NE(datum, nullptr);
+
+ auto obj2 = proj_obj_create_geocentric_crs_from_datum(
+ m_ctxt, "WGS 84", datum, "Metre", 1.0);
+ ObjectKeeper keeperObj(obj2);
+ ASSERT_NE(obj2, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, obj2, PJ_COMP_STRICT));
+ }
+ {
+ auto obj = proj_obj_create_geocentric_crs(
+ m_ctxt, nullptr, nullptr, nullptr, 1.0, 0.0, nullptr, 0.0, nullptr,
+ 0.0, nullptr, 0.0);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ }
+}
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_projections) {
/* BEGIN: Generated by scripts/create_c_api_projections.py*/
{
- auto projCRS =
- proj_obj_create_projected_crs_UTM(geogCRS, nullptr, 0, 0);
+ auto projCRS = proj_obj_create_conversion_utm(m_ctxt, 0, 0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_TransverseMercator(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_transverse_mercator(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_GaussSchreiberTransverseMercator(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_gauss_schreiber_transverse_mercator(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_TransverseMercatorSouthOriented(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_transverse_mercator_south_oriented(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_TwoPointEquidistant(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_two_point_equidistant(
+ m_ctxt, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_TunisiaMappingGrid(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_tunisia_mapping_grid(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_AlbersEqualArea(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_albers_equal_area(
+ m_ctxt, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_LambertConicConformal_1SP(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_lambert_conic_conformal_1sp(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_LambertConicConformal_2SP(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_lambert_conic_conformal_2sp(
+ m_ctxt, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_LambertConicConformal_2SP_Michigan(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
- 0.0174532925199433, "Metre", 1.0);
+ proj_obj_create_conversion_lambert_conic_conformal_2sp_michigan(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_LambertConicConformal_2SP_Belgium(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree",
- 0.0174532925199433, "Metre", 1.0);
+ proj_obj_create_conversion_lambert_conic_conformal_2sp_belgium(
+ m_ctxt, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_AzimuthalEquidistant(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_azimuthal_equidistant(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_GuamProjection(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_guam_projection(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Bonne(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_bonne(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_LambertCylindricalEqualAreaSpherical(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_lambert_cylindrical_equal_area_spherical(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_LambertCylindricalEqualArea(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_lambert_cylindrical_equal_area(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_CassiniSoldner(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_cassini_soldner(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EquidistantConic(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_equidistant_conic(
+ m_ctxt, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertI(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_i(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertII(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_ii(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertIII(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_iii(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertIV(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_iv(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertV(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_v(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EckertVI(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_eckert_vi(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EquidistantCylindrical(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_equidistant_cylindrical(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_EquidistantCylindricalSpherical(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_equidistant_cylindrical_spherical(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Gall(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_gall(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_GoodeHomolosine(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_goode_homolosine(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_InterruptedGoodeHomolosine(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_interrupted_goode_homolosine(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_GeostationarySatelliteSweepX(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_geostationary_satellite_sweep_x(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_GeostationarySatelliteSweepY(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_geostationary_satellite_sweep_y(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Gnomonic(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_gnomonic(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_HotineObliqueMercatorVariantA(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
- 0.0174532925199433, "Metre", 1.0);
+ proj_obj_create_conversion_hotine_oblique_mercator_variant_a(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_HotineObliqueMercatorVariantB(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
- 0.0174532925199433, "Metre", 1.0);
+ proj_obj_create_conversion_hotine_oblique_mercator_variant_b(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_HotineObliqueMercatorTwoPointNaturalOrigin(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, "Degree",
- 0.0174532925199433, "Metre", 1.0);
+ proj_obj_create_conversion_hotine_oblique_mercator_two_point_natural_origin(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_InternationalMapWorldPolyconic(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_international_map_world_polyconic(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_KrovakNorthOriented(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_krovak_north_oriented(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Krovak(
- geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_krovak(
+ m_ctxt, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_LambertAzimuthalEqualArea(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_lambert_azimuthal_equal_area(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_MillerCylindrical(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_miller_cylindrical(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_MercatorVariantA(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_mercator_variant_a(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_MercatorVariantB(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_mercator_variant_b(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_PopularVisualisationPseudoMercator(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_popular_visualisation_pseudo_mercator(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Mollweide(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_mollweide(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_NewZealandMappingGrid(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_new_zealand_mapping_grid(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_ObliqueStereographic(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_oblique_stereographic(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Orthographic(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_orthographic(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_AmericanPolyconic(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_american_polyconic(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_PolarStereographicVariantA(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_polar_stereographic_variant_a(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_PolarStereographicVariantB(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_polar_stereographic_variant_b(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Robinson(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_robinson(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Sinusoidal(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_sinusoidal(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_Stereographic(
- geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ auto projCRS = proj_obj_create_conversion_stereographic(
+ m_ctxt, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_VanDerGrinten(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_van_der_grinten(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerI(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_i(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerII(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_ii(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerIII(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_iii(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerIV(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_iv(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerV(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_v(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerVI(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_vi(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_WagnerVII(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_wagner_vii(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
auto projCRS =
- proj_obj_create_projected_crs_QuadrilateralizedSphericalCube(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
- "Metre", 1.0);
+ proj_obj_create_conversion_quadrilateralized_spherical_cube(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_SphericalCrossTrackHeight(
- geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_spherical_cross_track_height(
+ m_ctxt, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
{
- auto projCRS = proj_obj_create_projected_crs_EqualEarth(
- geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
- 1.0);
+ auto projCRS = proj_obj_create_conversion_equal_earth(
+ m_ctxt, 0, 0, 0, "Degree", 0.0174532925199433, "Metre", 1.0);
ObjectKeeper keeper_projCRS(projCRS);
ASSERT_NE(projCRS, nullptr);
}
/* END: Generated by scripts/create_c_api_projections.py*/
}
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_cs_get_axis_info) {
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ auto cs = proj_obj_crs_get_coordinate_system(m_ctxt, crs);
+ ASSERT_NE(cs, nullptr);
+ ObjectKeeper keeperCs(cs);
+
+ EXPECT_EQ(proj_obj_cs_get_type(m_ctxt, cs), PJ_CS_TYPE_ELLIPSOIDAL);
+
+ EXPECT_EQ(proj_obj_cs_get_axis_count(m_ctxt, cs), 2);
+
+ EXPECT_FALSE(proj_obj_cs_get_axis_info(m_ctxt, cs, -1, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+
+ EXPECT_FALSE(proj_obj_cs_get_axis_info(m_ctxt, cs, 2, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+
+ EXPECT_TRUE(proj_obj_cs_get_axis_info(m_ctxt, cs, 0, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+
+ const char *name = nullptr;
+ const char *abbrev = nullptr;
+ const char *direction = nullptr;
+ double unitConvFactor = 0.0;
+ const char *unitName = nullptr;
+
+ EXPECT_TRUE(proj_obj_cs_get_axis_info(m_ctxt, cs, 0, &name, &abbrev,
+ &direction, &unitConvFactor,
+ &unitName));
+ ASSERT_NE(name, nullptr);
+ ASSERT_NE(abbrev, nullptr);
+ ASSERT_NE(direction, nullptr);
+ ASSERT_NE(unitName, nullptr);
+ EXPECT_EQ(std::string(name), "Geodetic latitude");
+ EXPECT_EQ(std::string(abbrev), "Lat");
+ EXPECT_EQ(std::string(direction), "north");
+ EXPECT_EQ(unitConvFactor, 0.017453292519943295) << unitConvFactor;
+ EXPECT_EQ(std::string(unitName), "degree");
+ }
+
+ // Non CRS object
+ {
+ auto obj = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "1170", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, false,
+ nullptr);
+ ASSERT_NE(obj, nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_EQ(proj_obj_crs_get_coordinate_system(m_ctxt, obj), nullptr);
+
+ EXPECT_EQ(proj_obj_cs_get_type(m_ctxt, obj), PJ_CS_TYPE_UNKNOWN);
+
+ EXPECT_EQ(proj_obj_cs_get_axis_count(m_ctxt, obj), -1);
+
+ EXPECT_FALSE(proj_obj_cs_get_axis_info(m_ctxt, obj, 0, nullptr, nullptr,
+ nullptr, nullptr, nullptr));
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_get_database_metadata) {
+ EXPECT_TRUE(proj_context_get_database_metadata(m_ctxt, "IGNF.VERSION") !=
+ nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_clone) {
+ auto obj =
+ proj_obj_create_from_proj_string(m_ctxt, "+proj=longlat", nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto clone = proj_obj_clone(m_ctxt, obj);
+ ObjectKeeper keeperClone(clone);
+ ASSERT_NE(clone, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, clone, PJ_COMP_STRICT));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_alter_geodetic_crs) {
+ auto projCRS = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+
+ auto newGeodCRS =
+ proj_obj_create_from_proj_string(m_ctxt, "+proj=longlat", nullptr);
+ ObjectKeeper keeper_newGeodCRS(newGeodCRS);
+ ASSERT_NE(newGeodCRS, nullptr);
+
+ auto geodCRS = proj_obj_crs_get_geodetic_crs(m_ctxt, projCRS);
+ ObjectKeeper keeper_geodCRS(geodCRS);
+ ASSERT_NE(geodCRS, nullptr);
+
+ auto geodCRSAltered =
+ proj_obj_crs_alter_geodetic_crs(m_ctxt, geodCRS, newGeodCRS);
+ ObjectKeeper keeper_geodCRSAltered(geodCRSAltered);
+ ASSERT_NE(geodCRSAltered, nullptr);
+ EXPECT_TRUE(
+ proj_obj_is_equivalent_to(geodCRSAltered, newGeodCRS, PJ_COMP_STRICT));
+
+ auto projCRSAltered =
+ proj_obj_crs_alter_geodetic_crs(m_ctxt, projCRS, newGeodCRS);
+ ObjectKeeper keeper_projCRSAltered(projCRSAltered);
+ ASSERT_NE(projCRSAltered, nullptr);
+
+ EXPECT_EQ(proj_obj_get_type(projCRSAltered), PJ_OBJ_TYPE_PROJECTED_CRS);
+
+ auto projCRSAltered_geodCRS =
+ proj_obj_crs_get_geodetic_crs(m_ctxt, projCRSAltered);
+ ObjectKeeper keeper_projCRSAltered_geodCRS(projCRSAltered_geodCRS);
+ ASSERT_NE(projCRSAltered_geodCRS, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(projCRSAltered_geodCRS, newGeodCRS,
+ PJ_COMP_STRICT));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_alter_cs_angular_unit) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(crs);
+ ASSERT_NE(crs, nullptr);
+
+ auto alteredCRS =
+ proj_obj_crs_alter_cs_angular_unit(m_ctxt, crs, "my unit", 2);
+ ObjectKeeper keeper_alteredCRS(alteredCRS);
+ ASSERT_NE(alteredCRS, nullptr);
+
+ auto cs = proj_obj_crs_get_coordinate_system(m_ctxt, alteredCRS);
+ ASSERT_NE(cs, nullptr);
+ ObjectKeeper keeperCs(cs);
+ double unitConvFactor = 0.0;
+ const char *unitName = nullptr;
+
+ EXPECT_TRUE(proj_obj_cs_get_axis_info(m_ctxt, cs, 0, nullptr, nullptr,
+ nullptr, &unitConvFactor, &unitName));
+ ASSERT_NE(unitName, nullptr);
+ EXPECT_EQ(unitConvFactor, 2) << unitConvFactor;
+ EXPECT_EQ(std::string(unitName), "my unit");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_alter_cs_linear_unit) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(crs);
+ ASSERT_NE(crs, nullptr);
+
+ auto alteredCRS =
+ proj_obj_crs_alter_cs_linear_unit(m_ctxt, crs, "my unit", 2);
+ ObjectKeeper keeper_alteredCRS(alteredCRS);
+ ASSERT_NE(alteredCRS, nullptr);
+
+ auto cs = proj_obj_crs_get_coordinate_system(m_ctxt, alteredCRS);
+ ASSERT_NE(cs, nullptr);
+ ObjectKeeper keeperCs(cs);
+ double unitConvFactor = 0.0;
+ const char *unitName = nullptr;
+
+ EXPECT_TRUE(proj_obj_cs_get_axis_info(m_ctxt, cs, 0, nullptr, nullptr,
+ nullptr, &unitConvFactor, &unitName));
+ ASSERT_NE(unitName, nullptr);
+ EXPECT_EQ(unitConvFactor, 2) << unitConvFactor;
+ EXPECT_EQ(std::string(unitName), "my unit");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_alter_parameters_linear_unit) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(crs);
+ ASSERT_NE(crs, nullptr);
+
+ {
+ auto alteredCRS = proj_obj_crs_alter_parameters_linear_unit(
+ m_ctxt, crs, "my unit", 2, false);
+ ObjectKeeper keeper_alteredCRS(alteredCRS);
+ ASSERT_NE(alteredCRS, nullptr);
+
+ auto wkt = proj_obj_as_wkt(m_ctxt, alteredCRS, PJ_WKT2_2018, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("500000") != std::string::npos)
+ << wkt;
+ EXPECT_TRUE(std::string(wkt).find("\"my unit\",2") != std::string::npos)
+ << wkt;
+ }
+
+ {
+ auto alteredCRS = proj_obj_crs_alter_parameters_linear_unit(
+ m_ctxt, crs, "my unit", 2, true);
+ ObjectKeeper keeper_alteredCRS(alteredCRS);
+ ASSERT_NE(alteredCRS, nullptr);
+
+ auto wkt = proj_obj_as_wkt(m_ctxt, alteredCRS, PJ_WKT2_2018, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("250000") != std::string::npos)
+ << wkt;
+ EXPECT_TRUE(std::string(wkt).find("\"my unit\",2") != std::string::npos)
+ << wkt;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_engineering_crs) {
+
+ auto crs = proj_obj_create_engineering_crs(m_ctxt, "name");
+ ObjectKeeper keeper(crs);
+ ASSERT_NE(crs, nullptr);
+ auto wkt = proj_obj_as_wkt(m_ctxt, crs, PJ_WKT1_GDAL, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_EQ(std::string(wkt), "LOCAL_CS[\"name\"]") << wkt;
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_alter_name) {
+
+ auto cs = proj_obj_create_ellipsoidal_2D_cs(
+ m_ctxt, PJ_ELLPS2D_LONGITUDE_LATITUDE, nullptr, 0);
+ ObjectKeeper keeper_cs(cs);
+ ASSERT_NE(cs, nullptr);
+
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433, cs);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto alteredObj = proj_obj_alter_name(m_ctxt, obj, "new name");
+ ObjectKeeper keeper_alteredObj(alteredObj);
+ ASSERT_NE(alteredObj, nullptr);
+
+ EXPECT_EQ(std::string(proj_obj_get_name(alteredObj)), "new name");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_projected_crs) {
+
+ PJ_PARAM_DESCRIPTION param;
+ param.name = "param name";
+ param.auth_name = nullptr;
+ param.code = nullptr;
+ param.value = 0.99;
+ param.unit_name = nullptr;
+ param.unit_conv_factor = 1.0;
+ param.unit_type = PJ_UT_SCALE;
+
+ auto conv = proj_obj_create_conversion(m_ctxt, "conv", "conv auth",
+ "conv code", "method", "method auth",
+ "method code", 1, &param);
+ ObjectKeeper keeper_conv(conv);
+ ASSERT_NE(conv, nullptr);
+
+ auto geog_cs = proj_obj_create_ellipsoidal_2D_cs(
+ m_ctxt, PJ_ELLPS2D_LONGITUDE_LATITUDE, nullptr, 0);
+ ObjectKeeper keeper_geog_cs(geog_cs);
+ ASSERT_NE(geog_cs, nullptr);
+
+ auto geogCRS = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433, geog_cs);
+ ObjectKeeper keeper_geogCRS(geogCRS);
+ ASSERT_NE(geogCRS, nullptr);
+
+ auto cs = proj_obj_create_cartesian_2D_cs(
+ m_ctxt, PJ_CART2D_EASTING_NORTHING, nullptr, 0);
+ ObjectKeeper keeper_cs(cs);
+ ASSERT_NE(cs, nullptr);
+
+ auto projCRS =
+ proj_obj_create_projected_crs(m_ctxt, "my CRS", geogCRS, conv, cs);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+}
+
} // namespace
diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp
index 55df5875..3f044de0 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -1107,6 +1107,9 @@ TEST(crs, geocentricCRS_as_WKT1_GDAL) {
" AUTHORITY[\"EPSG\",\"8901\"]],\n"
" UNIT[\"metre\",1,\n"
" AUTHORITY[\"EPSG\",\"9001\"]],\n"
+ " AXIS[\"Geocentric X\",OTHER],\n"
+ " AXIS[\"Geocentric Y\",OTHER],\n"
+ " AXIS[\"Geocentric Z\",NORTH],\n"
" AUTHORITY[\"EPSG\",\"4328\"]]");
}
@@ -1213,6 +1216,23 @@ TEST(crs, geodeticcrs_identify_no_db) {
EXPECT_EQ(res.front().first.get(), GeographicCRS::EPSG_4326.get());
EXPECT_EQ(res.front().second, 25);
}
+
+ {
+ // WKT1 identification
+ auto obj =
+ WKTParser()
+ .attachDatabaseContext(DatabaseContext::create())
+ .createFromWKT(
+ "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\","
+ "6378137,298.257223563]],PRIMEM[\"Greenwich\",0],"
+ "UNIT[\"Degree\",0.0174532925199433]]");
+ auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(nullptr);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().first.get(), GeographicCRS::EPSG_4326.get());
+ EXPECT_EQ(res.front().second, 100);
+ }
}
// ---------------------------------------------------------------------------
@@ -1665,6 +1685,60 @@ TEST(crs, projectedCRS_as_WKT1_ESRI) {
// ---------------------------------------------------------------------------
+TEST(crs, projectedCRS_with_ESRI_code_as_WKT1_ESRI) {
+ auto dbContext = DatabaseContext::create();
+ auto crs = AuthorityFactory::create(dbContext, "ESRI")
+ ->createProjectedCRS("102113");
+
+ // Comes literally from the text_definition column of
+ // projected_crs table
+ auto esri_wkt =
+ "PROJCS[\"WGS_1984_Web_Mercator\","
+ "GEOGCS[\"GCS_WGS_1984_Major_Auxiliary_Sphere\","
+ "DATUM[\"D_WGS_1984_Major_Auxiliary_Sphere\","
+ "SPHEROID[\"WGS_1984_Major_Auxiliary_Sphere\",6378137.0,0.0]],"
+ "PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],"
+ "PROJECTION[\"Mercator\"],PARAMETER[\"False_Easting\",0.0],"
+ "PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],"
+ "PARAMETER[\"Standard_Parallel_1\",0.0],UNIT[\"Meter\",1.0]]";
+
+ EXPECT_EQ(
+ crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
+ .get()),
+ esri_wkt);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, projectedCRS_from_WKT1_ESRI_as_WKT1_ESRI) {
+ auto dbContext = DatabaseContext::create();
+ // Comes literally from the text_definition column of
+ // projected_crs table
+ auto esri_wkt =
+ "PROJCS[\"WGS_1984_Web_Mercator\","
+ "GEOGCS[\"GCS_WGS_1984_Major_Auxiliary_Sphere\","
+ "DATUM[\"D_WGS_1984_Major_Auxiliary_Sphere\","
+ "SPHEROID[\"WGS_1984_Major_Auxiliary_Sphere\",6378137.0,0.0]],"
+ "PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],"
+ "PROJECTION[\"Mercator\"],PARAMETER[\"False_Easting\",0.0],"
+ "PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],"
+ "PARAMETER[\"Standard_Parallel_1\",0.0],UNIT[\"Meter\",1.0]]";
+
+ auto obj =
+ WKTParser().attachDatabaseContext(dbContext).createFromWKT(esri_wkt);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ EXPECT_EQ(
+ crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext)
+ .get()),
+ esri_wkt);
+}
+
+// ---------------------------------------------------------------------------
+
TEST(crs, projectedCRS_as_PROJ_string) {
auto crs = createProjected();
EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()),
@@ -1890,6 +1964,93 @@ TEST(crs, projectedCRS_identify_db) {
EXPECT_EQ(res.front().second, 70);
}
{
+ // Identify from a WKT1 string wit explicit correct axis order
+ auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(
+ "PROJCS[\"ETRS89 / UTM zone 32N (N-E)\",GEOGCS[\"ETRS89\","
+ "DATUM[\"European_Terrestrial_Reference_System_1989\","
+ "SPHEROID[\"GRS 1980\",6378137,298.257222101]],"
+ "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],"
+ "PROJECTION[\"Transverse_Mercator\"],"
+ "PARAMETER[\"latitude_of_origin\",0],"
+ "PARAMETER[\"central_meridian\",9],"
+ "PARAMETER[\"scale_factor\",0.9996],"
+ "PARAMETER[\"false_easting\",500000],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"metre\",1],"
+ "AXIS[\"Northing\",NORTH],AXIS[\"Easting\",EAST]]");
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().first->getEPSGCode(), 3044);
+ EXPECT_EQ(res.front().second, 100);
+ }
+ {
+ // Identify from a WKT1 string wit wrong axis order
+ auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(
+ "PROJCS[\"ETRS89 / UTM zone 32N (N-E)\",GEOGCS[\"ETRS89\","
+ "DATUM[\"European_Terrestrial_Reference_System_1989\","
+ "SPHEROID[\"GRS 1980\",6378137,298.257222101]],"
+ "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],"
+ "PROJECTION[\"Transverse_Mercator\"],"
+ "PARAMETER[\"latitude_of_origin\",0],"
+ "PARAMETER[\"central_meridian\",9],"
+ "PARAMETER[\"scale_factor\",0.9996],"
+ "PARAMETER[\"false_easting\",500000],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"metre\",1],"
+ "AXIS[\"Easting\",EAST], AXIS[\"Northing\",NORTH]]");
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().first->getEPSGCode(), 3044);
+ EXPECT_EQ(res.front().second, 25);
+ }
+ {
+ // Identify from a WKT1 string, without explicit axis
+ auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(
+ "PROJCS[\"ETRS89 / UTM zone 32N (N-E)\",GEOGCS[\"ETRS89\","
+ "DATUM[\"European_Terrestrial_Reference_System_1989\","
+ "SPHEROID[\"GRS 1980\",6378137,298.257222101]],"
+ "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]],"
+ "PROJECTION[\"Transverse_Mercator\"],"
+ "PARAMETER[\"latitude_of_origin\",0],"
+ "PARAMETER[\"central_meridian\",9],"
+ "PARAMETER[\"scale_factor\",0.9996],"
+ "PARAMETER[\"false_easting\",500000],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"metre\",1]]");
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().first->getEPSGCode(), 3044);
+ EXPECT_EQ(res.front().second, 100);
+ }
+ {
+ // Identify from a WKT ESRI with bad PROJCS and GEOGCS names.
+ auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(
+ "PROJCS[\"Lambert Conformal Conic\",GEOGCS[\"grs80\","
+ "DATUM[\"D_North_American_1983\","
+ "SPHEROID[\"Geodetic_Reference_System_1980\","
+ "6378137,298.257222101]],PRIMEM[\"Greenwich\",0],"
+ "UNIT[\"Degree\",0.017453292519943295]],"
+ "PROJECTION[\"Lambert_Conformal_Conic\"],"
+ "PARAMETER[\"standard_parallel_1\",34.33333333333334],"
+ "PARAMETER[\"standard_parallel_2\",36.16666666666666],"
+ "PARAMETER[\"latitude_of_origin\",33.75],"
+ "PARAMETER[\"central_meridian\",-79],"
+ "PARAMETER[\"false_easting\",609601.22],"
+ "PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]");
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().first->getEPSGCode(), 32119);
+ EXPECT_EQ(res.front().second, 70);
+ }
+ {
// No equivalent CRS to input one in result set
auto obj =
PROJStringParser().createFromPROJString("+proj=tmerc +datum=WGS84");
@@ -3407,6 +3568,40 @@ TEST(crs, boundCRS_identify_db) {
"NZGD2000 to WGS 84 (1)");
EXPECT_EQ(res.front().second, 50);
}
+
+ {
+ // WKT has EPSG code but the definition doesn't match with the official
+ // one (namely linear units are different)
+ // https://github.com/OSGeo/gdal/issues/990
+ // Also test that we can handle the synthetic Null geographic offset
+ // between NAD83 and WGS84
+ auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(
+ "PROJCS[\"NAD83 / Ohio North\",GEOGCS[\"NAD83\","
+ "DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS 1980\","
+ "6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],"
+ "TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6269\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree\",0.0174532925199433, AUTHORITY[\"EPSG\",\"9122\"]],"
+ "AUTHORITY[\"EPSG\",\"4269\"]],"
+ "PROJECTION[\"Lambert_Conformal_Conic_2SP\"],"
+ "PARAMETER[\"standard_parallel_1\",41.7],"
+ "PARAMETER[\"standard_parallel_2\",40.43333333333333],"
+ "PARAMETER[\"latitude_of_origin\",39.66666666666666],"
+ "PARAMETER[\"central_meridian\",-82.5],"
+ "PARAMETER[\"false_easting\",1968503.937007874],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"International Foot\",0.3048,AUTHORITY[\"EPSG\",\"9002\"]],"
+ "AXIS[\"X\",EAST],AXIS[\"Y\",NORTH],AUTHORITY[\"EPSG\",\"32122\"]"
+ "]");
+ auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1);
+ EXPECT_EQ(res.front().second, 25);
+ auto wkt = crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ EXPECT_TRUE(wkt.find("32122") != std::string::npos) << wkt;
+ }
}
// ---------------------------------------------------------------------------
@@ -4662,3 +4857,136 @@ TEST(crs, crs_stripVerticalComponent) {
EXPECT_EQ(projCRS->coordinateSystem()->axisList().size(), 2);
}
}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, crs_alterGeodeticCRS) {
+
+ {
+ auto crs = GeographicCRS::EPSG_4326->alterGeodeticCRS(
+ GeographicCRS::EPSG_4979);
+ EXPECT_TRUE(crs->isEquivalentTo(GeographicCRS::EPSG_4979.get()));
+ }
+
+ {
+ auto crs =
+ createProjected()->alterGeodeticCRS(GeographicCRS::EPSG_4979);
+ auto projCRS = dynamic_cast<ProjectedCRS *>(crs.get());
+ ASSERT_TRUE(projCRS != nullptr);
+ EXPECT_TRUE(
+ projCRS->baseCRS()->isEquivalentTo(GeographicCRS::EPSG_4979.get()));
+ }
+
+ {
+ auto crs =
+ createCompoundCRS()->alterGeodeticCRS(GeographicCRS::EPSG_4979);
+ auto compoundCRS = dynamic_cast<CompoundCRS *>(crs.get());
+ ASSERT_TRUE(compoundCRS != nullptr);
+ EXPECT_TRUE(compoundCRS->componentReferenceSystems()[0]
+ ->extractGeographicCRS()
+ ->isEquivalentTo(GeographicCRS::EPSG_4979.get()));
+ }
+
+ {
+ auto crs =
+ createVerticalCRS()->alterGeodeticCRS(GeographicCRS::EPSG_4979);
+ EXPECT_TRUE(crs->isEquivalentTo(createVerticalCRS().get()));
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, crs_alterCSLinearUnit) {
+
+ {
+ auto crs =
+ createProjected()->alterCSLinearUnit(UnitOfMeasure("my unit", 2));
+ auto projCRS = dynamic_cast<ProjectedCRS *>(crs.get());
+ ASSERT_TRUE(projCRS != nullptr);
+ auto cs = projCRS->coordinateSystem();
+ ASSERT_EQ(cs->axisList().size(), 2U);
+ EXPECT_EQ(cs->axisList()[0]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[0]->unit().conversionToSI(), 2);
+ EXPECT_EQ(cs->axisList()[1]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[1]->unit().conversionToSI(), 2);
+ }
+
+ {
+ auto crs = GeodeticCRS::EPSG_4978->alterCSLinearUnit(
+ UnitOfMeasure("my unit", 2));
+ auto geodCRS = dynamic_cast<GeodeticCRS *>(crs.get());
+ ASSERT_TRUE(geodCRS != nullptr);
+ auto cs =
+ dynamic_cast<CartesianCS *>(geodCRS->coordinateSystem().get());
+ ASSERT_EQ(cs->axisList().size(), 3U);
+ EXPECT_EQ(cs->axisList()[0]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[0]->unit().conversionToSI(), 2);
+ EXPECT_EQ(cs->axisList()[1]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[1]->unit().conversionToSI(), 2);
+ EXPECT_EQ(cs->axisList()[2]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[2]->unit().conversionToSI(), 2);
+ }
+
+ {
+ auto crs = GeographicCRS::EPSG_4979->alterCSLinearUnit(
+ UnitOfMeasure("my unit", 2));
+ auto geogCRS = dynamic_cast<GeographicCRS *>(crs.get());
+ ASSERT_TRUE(geogCRS != nullptr);
+ auto cs = geogCRS->coordinateSystem();
+ ASSERT_EQ(cs->axisList().size(), 3U);
+ EXPECT_NE(cs->axisList()[0]->unit().name(), "my unit");
+ EXPECT_NE(cs->axisList()[0]->unit().conversionToSI(), 2);
+ EXPECT_NE(cs->axisList()[1]->unit().name(), "my unit");
+ EXPECT_NE(cs->axisList()[1]->unit().conversionToSI(), 2);
+ EXPECT_EQ(cs->axisList()[2]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[2]->unit().conversionToSI(), 2);
+ }
+
+ {
+ auto crs =
+ createVerticalCRS()->alterCSLinearUnit(UnitOfMeasure("my unit", 2));
+ auto vertCRS = dynamic_cast<VerticalCRS *>(crs.get());
+ ASSERT_TRUE(vertCRS != nullptr);
+ auto cs = vertCRS->coordinateSystem();
+ ASSERT_EQ(cs->axisList().size(), 1U);
+ EXPECT_EQ(cs->axisList()[0]->unit().name(), "my unit");
+ EXPECT_EQ(cs->axisList()[0]->unit().conversionToSI(), 2);
+ }
+
+ {
+ // Not implemented on compoundCRS
+ auto crs =
+ createCompoundCRS()->alterCSLinearUnit(UnitOfMeasure("my unit", 2));
+ EXPECT_TRUE(createCompoundCRS()->isEquivalentTo(crs.get()));
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, alterParametersLinearUnit) {
+ {
+ auto crs = createProjected()->alterParametersLinearUnit(
+ UnitOfMeasure("my unit", 2), false);
+ auto wkt =
+ crs->exportToWKT(&WKTFormatter::create()->setMultiLine(false));
+ EXPECT_TRUE(wkt.find("PARAMETER[\"Longitude of natural origin\",3") !=
+ std::string::npos)
+ << wkt;
+ EXPECT_TRUE(
+ wkt.find(
+ "PARAMETER[\"False easting\",500000,UNIT[\"my unit\",2]") !=
+ std::string::npos)
+ << wkt;
+ }
+ {
+ auto crs = createProjected()->alterParametersLinearUnit(
+ UnitOfMeasure("my unit", 2), true);
+ auto wkt =
+ crs->exportToWKT(&WKTFormatter::create()->setMultiLine(false));
+ EXPECT_TRUE(
+ wkt.find(
+ "PARAMETER[\"False easting\",250000,UNIT[\"my unit\",2]") !=
+ std::string::npos)
+ << wkt;
+ }
+}
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 739bb729..7cdb0b40 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -2703,6 +2703,13 @@ TEST(factory, createObjectsFromName) {
.size(),
1);
+ // Deprecated object (but without explicit deprecated)
+ EXPECT_EQ(
+ factoryEPSG
+ ->createObjectsFromName("NAD27(CGQ77) / SCoPQ zone 2", {}, false, 2)
+ .size(),
+ 1);
+
const auto types = std::vector<AuthorityFactory::ObjectType>{
AuthorityFactory::ObjectType::PRIME_MERIDIAN,
AuthorityFactory::ObjectType::ELLIPSOID,
@@ -2729,4 +2736,14 @@ TEST(factory, createObjectsFromName) {
factory->createObjectsFromName("i_dont_exist", types, false, 1);
}
+// ---------------------------------------------------------------------------
+
+TEST(factory, getMetadata) {
+ auto ctxt = DatabaseContext::create();
+ EXPECT_EQ(ctxt->getMetadata("i_do_not_exist"), nullptr);
+ const char *IGNF_VERSION = ctxt->getMetadata("IGNF.VERSION");
+ ASSERT_TRUE(IGNF_VERSION != nullptr);
+ EXPECT_EQ(std::string(IGNF_VERSION), "3.0.2");
+}
+
} // namespace
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 26597f09..606d57a3 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -119,6 +119,11 @@ TEST(io, wkt_parsing) {
str = "A[" + str + "]";
}
EXPECT_THROW(WKTNode::createFrom(str), ParsingException);
+
+ {
+ auto wkt = "A[\"a\",B[\"b\",C[\"c\"]],D[\"d\"]]";
+ EXPECT_EQ(WKTNode::createFrom(wkt)->toString(), wkt);
+ }
}
// ---------------------------------------------------------------------------
@@ -401,6 +406,33 @@ TEST(wkt_parse, wkt1_EPSG_4326) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_EPSG_4267) {
+ auto obj =
+ WKTParser()
+ .attachDatabaseContext(DatabaseContext::create())
+ .createFromWKT(
+ "GEOGCS[\"NAD27\","
+ " DATUM[\"North_American_Datum_1927\","
+ " SPHEROID[\"Clarke 1866\",6378206.4,294.978698213898,"
+ " AUTHORITY[\"EPSG\",\"7008\"]],"
+ " AUTHORITY[\"EPSG\",\"6267\"]],"
+ " PRIMEM[\"Greenwich\",0,"
+ " AUTHORITY[\"EPSG\",\"8901\"]],"
+ " UNIT[\"degree\",0.0174532925199433,"
+ " AUTHORITY[\"EPSG\",\"9122\"]],"
+ " AUTHORITY[\"EPSG\",\"4267\"]]");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ ASSERT_EQ(datum->identifiers().size(), 1);
+ EXPECT_EQ(datum->identifiers()[0]->code(), "6267");
+ EXPECT_EQ(*(datum->identifiers()[0]->codeSpace()), "EPSG");
+ EXPECT_EQ(datum->nameStr(), "North American Datum 1927");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, wkt1_EPSG_4807_grad_mess) {
auto obj = WKTParser().createFromWKT(
"GEOGCS[\"NTF (Paris)\",\n"
@@ -493,6 +525,9 @@ TEST(wkt_parse, wkt1_geocentric_with_PROJ4_extension) {
" SPHEROID[\"WGS84\",6378137,298.257223563]],\n"
" PRIMEM[\"Greenwich\",0],\n"
" UNIT[\"Meter\",1],\n"
+ " AXIS[\"Geocentric X\",OTHER],\n"
+ " AXIS[\"Geocentric Y\",OTHER],\n"
+ " AXIS[\"Geocentric Z\",NORTH],\n"
" EXTENSION[\"PROJ4\",\"+proj=geocent +foo=bar +wktext\"]]";
auto obj = WKTParser().createFromWKT(wkt);
@@ -768,6 +803,28 @@ TEST(wkt_parse, wkt1_geocentric) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_geocentric_with_z_OTHER) {
+ auto wkt = "GEOCCS[\"WGS 84 (geocentric)\",\n"
+ " DATUM[\"WGS_1984\",\n"
+ " SPHEROID[\"WGS 84\",6378137,298.257223563,\n"
+ " AUTHORITY[\"EPSG\",\"7030\"]],\n"
+ " AUTHORITY[\"EPSG\",\"6326\"]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " AUTHORITY[\"EPSG\",\"8901\"]],\n"
+ " UNIT[\"metre\",1,\n"
+ " AUTHORITY[\"EPSG\",9001]],\n"
+ " AXIS[\"Geocentric X\",OTHER],\n"
+ " AXIS[\"Geocentric Y\",OTHER],\n"
+ " AXIS[\"Geocentric Z\",OTHER],\n"
+ " AUTHORITY[\"EPSG\",\"4328\"]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ checkGeocentric(crs);
+}
+
+// ---------------------------------------------------------------------------
+
static void checkProjected(ProjectedCRSPtr crs, bool checkEPSGCodes = true) {
EXPECT_EQ(crs->nameStr(), "WGS 84 / UTM zone 31N");
ASSERT_EQ(crs->identifiers().size(), 1);
@@ -966,6 +1023,33 @@ TEST(wkt_parse, wkt1_projected_with_PROJ4_extension) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_Mercator_1SP_with_latitude_origin_0) {
+ auto wkt = "PROJCS[\"unnamed\",\n"
+ " GEOGCS[\"WGS 84\",\n"
+ " DATUM[\"unknown\",\n"
+ " SPHEROID[\"WGS84\",6378137,298.257223563]],\n"
+ " PRIMEM[\"Greenwich\",0],\n"
+ " UNIT[\"degree\",0.0174532925199433]],\n"
+ " PROJECTION[\"Mercator_1SP\"],\n"
+ " PARAMETER[\"latitude_of_origin\",0],\n"
+ " PARAMETER[\"central_meridian\",0],\n"
+ " PARAMETER[\"scale_factor\",1],\n"
+ " PARAMETER[\"false_easting\",0],\n"
+ " PARAMETER[\"false_northing\",0],\n"
+ " UNIT[\"Meter\",1],\n"
+ " AXIS[\"Easting\",EAST],\n"
+ " AXIS[\"Northing\",NORTH]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto got_wkt = crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ EXPECT_TRUE(got_wkt.find("Mercator_1SP") != std::string::npos) << got_wkt;
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, wkt1_krovak_south_west) {
auto wkt =
"PROJCS[\"S-JTSK / Krovak\","
@@ -2641,9 +2725,10 @@ TEST(wkt_parse, LOCAL_CS_short) {
// ---------------------------------------------------------------------------
-TEST(wkt_parse, LOCAL_CS_long_one_aix) {
+TEST(wkt_parse, LOCAL_CS_long_one_axis) {
auto wkt = "LOCAL_CS[\"Engineering CRS\",\n"
" LOCAL_DATUM[\"Engineering datum\",12345],\n"
+ " UNIT[\"meter\",1],\n"
" AXIS[\"height\",up]]";
auto obj = WKTParser().createFromWKT(wkt);
@@ -2661,6 +2746,7 @@ TEST(wkt_parse, LOCAL_CS_long_one_aix) {
TEST(wkt_parse, LOCAL_CS_long_two_axis) {
auto wkt = "LOCAL_CS[\"Engineering CRS\",\n"
" LOCAL_DATUM[\"Engineering datum\",12345],\n"
+ " UNIT[\"meter\",1],\n"
" AXIS[\"Easting\",EAST],\n"
" AXIS[\"Northing\",NORTH]]";
@@ -4139,7 +4225,7 @@ TEST(wkt_parse, invalid_GEOGCS) {
TEST(wkt_parse, invalid_UNIT) {
std::string startWKT("GEODCRS[\"x\",DATUM[\"x\",SPHEROID[\"x\",1,0.5]],CS["
"ellipsoidal,2],AXIS[\"latitude\",north],AXIS["
- "\"longitude\",east,");
+ "\"longitude\",east],");
EXPECT_NO_THROW(WKTParser().createFromWKT(
startWKT + "UNIT[\"degree\",0.0174532925199433]]]"));
@@ -4228,31 +4314,35 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
// CS: OK
EXPECT_NO_THROW(WKTParser().createFromWKT(
startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS["
- "\"longitude\",east]]"));
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"));
// CS: Cartesian with 2 axis unexpected
- EXPECT_THROW(WKTParser().createFromWKT(startWKT +
- ",CS[Cartesian,2],AXIS[\"latitude\","
- "north],AXIS[\"longitude\",east]]"),
+ EXPECT_THROW(WKTParser().createFromWKT(
+ startWKT + ",CS[Cartesian,2],AXIS[\"latitude\","
+ "north],AXIS[\"longitude\",east],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// CS: missing axis
EXPECT_THROW(WKTParser().createFromWKT(
- startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north]]"),
+ startWKT + ",CS[ellipsoidal,2],AXIS[\"latitude\",north],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// not enough children in AXIS
EXPECT_THROW(
WKTParser().createFromWKT(
startWKT +
- ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS[\"longitude\"]]"),
+ ",CS[ellipsoidal,2],AXIS[\"latitude\",north],AXIS[\"longitude\"],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// not enough children in ORDER
EXPECT_THROW(WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],"
+ "UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// invalid value in ORDER
@@ -4260,7 +4350,7 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[\"x\"]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// unexpected ORDER value
@@ -4268,7 +4358,7 @@ TEST(wkt_parse, invalid_CS_of_GEODCRS) {
WKTParser().createFromWKT(
startWKT +
",CS[ellipsoidal,2],AXIS[\"latitude\",north,ORDER[2]],AXIS["
- "\"longitude\",east]]"),
+ "\"longitude\",east],UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// Invalid CS type
@@ -4794,7 +4884,8 @@ TEST(wkt_parse, invalid_DerivedGeographicCRS) {
" METHOD[\"bar\"]],\n"
" CS[ellipsoidal,2],\n"
" AXIS[\"latitude\",north],\n"
- " AXIS[\"longitude\",east]]"));
+ " AXIS[\"longitude\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"));
// Missing DERIVINGCONVERSION
EXPECT_THROW(
@@ -4805,7 +4896,8 @@ TEST(wkt_parse, invalid_DerivedGeographicCRS) {
" ELLIPSOID[\"WGS 84\",6378137,298.257223563]]],\n"
" CS[ellipsoidal,2],\n"
" AXIS[\"latitude\",north],\n"
- " AXIS[\"longitude\",east]]"),
+ " AXIS[\"longitude\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"),
ParsingException);
// Missing CS
@@ -4982,18 +5074,20 @@ TEST(wkt_parse, invalid_LOCAL_CS) {
TEST(wkt_parse, invalid_ParametricCRS) {
- EXPECT_NO_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " PDATUM[\"name\"],\n"
- " CS[parametric,1],\n"
- " AXIS[\"time (T)\",future]]"));
+ EXPECT_NO_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " PDATUM[\"name\"],\n"
+ " CS[parametric,1],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"));
// Missing PDATUM
- EXPECT_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " CS[parametric,1],\n"
- " AXIS[\"time (T)\",future]]"),
- ParsingException);
+ EXPECT_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " CS[parametric,1],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"),
+ ParsingException);
// Missing CS
EXPECT_THROW(WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
@@ -5001,13 +5095,15 @@ TEST(wkt_parse, invalid_ParametricCRS) {
ParsingException);
// Invalid number of axis for CS
- EXPECT_THROW(
- WKTParser().createFromWKT("PARAMETRICCRS[\"name\",\n"
- " PDATUM[\"name\"],\n"
- " CS[parametric,2],\n"
- " AXIS[\"time (T)\",future],\n"
- " AXIS[\"time (T)\",future]]"),
- ParsingException);
+ EXPECT_THROW(WKTParser().createFromWKT(
+ "PARAMETRICCRS[\"name\",\n"
+ " PDATUM[\"name\"],\n"
+ " CS[parametric,2],\n"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]"
+ " AXIS[\"pressure (hPa)\",up,\n"
+ " PARAMETRICUNIT[\"HectoPascal\",100]]]"),
+ ParsingException);
// Invalid CS type
EXPECT_THROW(
@@ -5034,7 +5130,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"));
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"));
EXPECT_THROW(
WKTParser().createFromWKT("DERIVEDPROJCRS[\"derived projectedCRS\",\n"
@@ -5042,7 +5139,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"),
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing DERIVINGCONVERSION
@@ -5058,7 +5156,8 @@ TEST(wkt_parse, invalid_DERIVEDPROJCRS) {
" METHOD[\"PROJ unimplemented\"]]],\n"
" CS[Cartesian,2],\n"
" AXIS[\"(E)\",east],\n"
- " AXIS[\"(N)\",north]]"),
+ " AXIS[\"(N)\",north],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing CS
@@ -5087,7 +5186,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" DERIVINGCONVERSION[\"unnamed\",\n"
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[vertical,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"));
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"));
// Missing DERIVINGCONVERSION
EXPECT_THROW(WKTParser().createFromWKT(
@@ -5095,7 +5195,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" BASEVERTCRS[\"ODN height\",\n"
" VDATUM[\"Ordnance Datum Newlyn\"]],\n"
" CS[vertical,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"),
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
// Missing CS
@@ -5115,7 +5216,8 @@ TEST(wkt_parse, invalid_DerivedVerticalCRS) {
" DERIVINGCONVERSION[\"unnamed\",\n"
" METHOD[\"PROJ unimplemented\"]],\n"
" CS[parametric,1],\n"
- " AXIS[\"gravity-related height (H)\",up]]"),
+ " AXIS[\"gravity-related height (H)\",up],\n"
+ " UNIT[\"metre\",1]]"),
ParsingException);
}
@@ -5381,6 +5483,20 @@ TEST(io, projstringformatter_cart_grs80_wgs84) {
// ---------------------------------------------------------------------------
+TEST(io, projstringformatter_axisswap_unitconvert_axisswap) {
+ auto fmt = PROJStringFormatter::create();
+ fmt->addStep("axisswap");
+ fmt->addParam("order", "2,1");
+ fmt->addStep("unitconvert");
+ fmt->addParam("xy_in", "rad");
+ fmt->addParam("xy_out", "deg");
+ fmt->addStep("axisswap");
+ fmt->addParam("order", "2,1");
+ EXPECT_EQ(fmt->toString(), "+proj=unitconvert +xy_in=rad +xy_out=deg");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(io, projparse_longlat) {
auto expected = "GEODCRS[\"unknown\",\n"
@@ -5672,23 +5788,33 @@ TEST(io, projparse_longlat_a_f_non_zero) {
PROJStringParser().createFromPROJString("+proj=longlat +a=2 +f=0.5");
auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
ASSERT_TRUE(crs != nullptr);
- WKTFormatterNNPtr f(WKTFormatter::create());
- f->simulCurNodeHasId();
- crs->exportToWKT(f.get());
- auto expected = "GEODCRS[\"unknown\",\n"
- " DATUM[\"unknown\",\n"
- " ELLIPSOID[\"unknown\",2,2,\n"
- " LENGTHUNIT[\"metre\",1]]],\n"
- " PRIMEM[\"Reference meridian\",0,\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
- " CS[ellipsoidal,2],\n"
- " AXIS[\"longitude\",east,\n"
- " ORDER[1],\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
- " AXIS[\"latitude\",north,\n"
- " ORDER[2],\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]]]";
- EXPECT_EQ(f->toString(), expected);
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+ auto rf = crs->ellipsoid()->computedInverseFlattening();
+ EXPECT_EQ(rf, 2) << rf;
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projparse_longlat_a_e) {
+ auto obj =
+ PROJStringParser().createFromPROJString("+proj=longlat +a=2 +e=0.5");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+ auto rf = crs->ellipsoid()->computedInverseFlattening();
+ EXPECT_NEAR(rf, 7.46410161513775, 1e-14) << rf;
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projparse_longlat_a_es) {
+ auto obj =
+ PROJStringParser().createFromPROJString("+proj=longlat +a=2 +es=0.5");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+ auto rf = crs->ellipsoid()->computedInverseFlattening();
+ EXPECT_EQ(rf, 3.4142135623730958) << rf;
}
// ---------------------------------------------------------------------------
@@ -5697,23 +5823,31 @@ TEST(io, projparse_longlat_R) {
auto obj = PROJStringParser().createFromPROJString("+proj=longlat +R=2");
auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
ASSERT_TRUE(crs != nullptr);
- WKTFormatterNNPtr f(WKTFormatter::create());
- f->simulCurNodeHasId();
- crs->exportToWKT(f.get());
- auto expected = "GEODCRS[\"unknown\",\n"
- " DATUM[\"unknown\",\n"
- " ELLIPSOID[\"unknown\",2,0,\n"
- " LENGTHUNIT[\"metre\",1]]],\n"
- " PRIMEM[\"Reference meridian\",0,\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
- " CS[ellipsoidal,2],\n"
- " AXIS[\"longitude\",east,\n"
- " ORDER[1],\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
- " AXIS[\"latitude\",north,\n"
- " ORDER[2],\n"
- " ANGLEUNIT[\"degree\",0.0174532925199433]]]";
- EXPECT_EQ(f->toString(), expected);
+ EXPECT_TRUE(crs->ellipsoid()->isSphere());
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projparse_longlat_a) {
+ auto obj = PROJStringParser().createFromPROJString("+proj=longlat +a=2");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_TRUE(crs->ellipsoid()->isSphere());
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projparse_longlat_a_override_ellps) {
+ auto obj = PROJStringParser().createFromPROJString(
+ "+proj=longlat +a=2 +ellps=WGS84");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_TRUE(!crs->ellipsoid()->isSphere());
+ EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2);
+ EXPECT_EQ(crs->ellipsoid()->computedInverseFlattening(), 298.25722356300003)
+ << crs->ellipsoid()->computedInverseFlattening();
}
// ---------------------------------------------------------------------------
@@ -7433,18 +7567,48 @@ TEST(io, projparse_projected_title) {
// ---------------------------------------------------------------------------
TEST(io, projparse_init) {
+ auto dbContext = DatabaseContext::create();
+
+ // Not allowed in non-compatibillity mode
+ EXPECT_THROW(PROJStringParser().createFromPROJString("init=epsg:4326"),
+ ParsingException);
+
+ {
+ // EPSG:4326 is normally latitude-longitude order with degree,
+ // but in compatibillity mode it will be long-lat radian
+ auto obj = createFromUserInput("init=epsg:4326", dbContext, true);
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_TRUE(crs->coordinateSystem()->isEquivalentTo(
+ EllipsoidalCS::createLongitudeLatitude(UnitOfMeasure::RADIAN)
+ .get()));
+ }
{
- auto obj = PROJStringParser().createFromPROJString("init=epsg:4326");
+ // EPSG:3040 is normally northing-easting order, but in compatibillity
+ // mode it will be easting-northing
+ auto obj = createFromUserInput("init=epsg:3040", dbContext, true);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_TRUE(crs->coordinateSystem()->isEquivalentTo(
+ CartesianCS::createEastingNorthing(UnitOfMeasure::METRE).get()));
+ }
+
+ {
+ auto obj =
+ PROJStringParser().createFromPROJString("init=ITRF2000:ITRF2005");
auto co = nn_dynamic_pointer_cast<CoordinateOperation>(obj);
ASSERT_TRUE(co != nullptr);
EXPECT_EQ(co->exportToPROJString(PROJStringFormatter::create().get()),
- "+init=epsg:4326");
+ "+proj=helmert +x=-0.0001 +y=0.0008 +z=0.0058 +rx=0 +ry=0 "
+ "+rz=0 +s=-0.0004 +dx=0.0002 +dy=-0.0001 +dz=0.0018 +drx=0 "
+ "+dry=0 +drz=0 +ds=-8e-06 +t_epoch=2000 "
+ "+convention=position_vector");
}
{
- auto obj = PROJStringParser().createFromPROJString(
- "title=mytitle init=epsg:4326 ellps=WGS84");
+ auto obj = createFromUserInput(
+ "title=mytitle init=epsg:4326 ellps=WGS84", dbContext, true);
auto co = nn_dynamic_pointer_cast<CoordinateOperation>(obj);
ASSERT_TRUE(co != nullptr);
EXPECT_EQ(co->nameStr(), "mytitle");
@@ -7453,13 +7617,24 @@ TEST(io, projparse_init) {
}
{
- auto obj = PROJStringParser().createFromPROJString(
- "proj=pipeline step init=epsg:4326 step proj=longlat");
+ auto obj = createFromUserInput(
+ "proj=pipeline step init=epsg:4326 step proj=longlat", dbContext,
+ true);
auto co = nn_dynamic_pointer_cast<CoordinateOperation>(obj);
ASSERT_TRUE(co != nullptr);
EXPECT_EQ(co->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +init=epsg:4326 +step +proj=longlat");
}
+
+ {
+ auto obj = createFromUserInput(
+ "init=epsg:4326 proj=longlat ellps=GRS80", dbContext, true);
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +proj=longlat +ellps=GRS80 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg");
+ }
}
// ---------------------------------------------------------------------------
@@ -7491,10 +7666,6 @@ TEST(io, projparse_errors) {
EXPECT_THROW(PROJStringParser().createFromPROJString(
"proj=pipeline step init=epsg:4326 init=epsg:4326"),
ParsingException);
-
- EXPECT_THROW(PROJStringParser().createFromPROJString(
- "proj=pipeline step init=epsg:4326 proj=longlat"),
- ParsingException);
}
// ---------------------------------------------------------------------------
@@ -7532,9 +7703,6 @@ TEST(io, projparse_longlat_errors) {
PROJStringParser().createFromPROJString("+proj=longlat +R=invalid"),
ParsingException);
- EXPECT_THROW(PROJStringParser().createFromPROJString("+proj=longlat +a=1"),
- ParsingException);
-
EXPECT_THROW(PROJStringParser().createFromPROJString("+proj=longlat +b=1"),
ParsingException);
@@ -7607,6 +7775,7 @@ TEST(io, createFromUserInput) {
EXPECT_NO_THROW(createFromUserInput("+proj=longlat", nullptr));
EXPECT_NO_THROW(createFromUserInput("EPSG:4326", dbContext));
+ EXPECT_NO_THROW(createFromUserInput("epsg:4326", dbContext));
EXPECT_NO_THROW(
createFromUserInput("urn:ogc:def:crs:EPSG::4326", dbContext));
EXPECT_NO_THROW(createFromUserInput(
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index e62eddf9..057f1717 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -1142,6 +1142,36 @@ TEST(operation, transformation_createTOWGS84) {
// ---------------------------------------------------------------------------
+TEST(operation, createAxisOrderReversal) {
+
+ auto latLongDeg = GeographicCRS::create(
+ PropertyMap(), GeodeticReferenceFrame::EPSG_6326,
+ EllipsoidalCS::createLatitudeLongitude(UnitOfMeasure::DEGREE));
+ auto longLatDeg = GeographicCRS::create(
+ PropertyMap(), GeodeticReferenceFrame::EPSG_6326,
+ EllipsoidalCS::createLongitudeLatitude(UnitOfMeasure::DEGREE));
+ {
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ latLongDeg, longLatDeg);
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=axisswap +order=2,1");
+ }
+ {
+ auto longLatRad = GeographicCRS::create(
+ PropertyMap(), GeodeticReferenceFrame::EPSG_6326,
+ EllipsoidalCS::createLongitudeLatitude(UnitOfMeasure::RADIAN));
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ longLatRad, latLongDeg);
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +proj=axisswap +order=2,1 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg");
+ }
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, utm_export) {
auto conv = Conversion::createUTM(PropertyMap(), 1, false);
EXPECT_EQ(conv->exportToPROJString(PROJStringFormatter::create().get()),
@@ -2986,6 +3016,29 @@ TEST(operation, webmerc_import_from_GDAL_wkt1) {
// ---------------------------------------------------------------------------
+TEST(operation, webmerc_import_from_GDAL_wkt1_with_EPSG_code) {
+
+ auto projCRS = ProjectedCRS::create(
+ PropertyMap()
+ .set(IdentifiedObject::NAME_KEY, "Pseudo-Mercator")
+ .set(Identifier::CODESPACE_KEY, "EPSG")
+ .set(Identifier::CODE_KEY, "3857"),
+ GeographicCRS::EPSG_4326,
+ Conversion::createPopularVisualisationPseudoMercator(
+ PropertyMap(), Angle(0), Angle(0), Length(0), Length(0)),
+ CartesianCS::createEastingNorthing(UnitOfMeasure::METRE));
+
+ auto wkt1 = projCRS->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ EXPECT_TRUE(wkt1.find("3857") != std::string::npos) << wkt1;
+ auto obj = WKTParser().createFromWKT(wkt1);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ EXPECT_EQ(crs->identifiers().size(), 1);
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, webmerc_import_from_GDAL_wkt1_EPSG_3785_deprecated) {
auto wkt1 =
@@ -3134,6 +3187,44 @@ TEST(operation, webmerc_import_from_WKT2_EPSG_3785_deprecated) {
// ---------------------------------------------------------------------------
+TEST(operation, webmerc_import_from_broken_esri_WGS_84_Pseudo_Mercator) {
+
+ // Likely the result of a broken export of GDAL morphToESRI()
+ auto wkt1 = "PROJCS[\"WGS_84_Pseudo_Mercator\",GEOGCS[\"GCS_WGS_1984\","
+ "DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\","
+ "6378137,298.257223563]],PRIMEM[\"Greenwich\",0],"
+ "UNIT[\"Degree\",0.017453292519943295]],"
+ "PROJECTION[\"Mercator\"],PARAMETER[\"central_meridian\",0],"
+ "PARAMETER[\"false_easting\",0],"
+ "PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1],"
+ "PARAMETER[\"standard_parallel_1\",0.0]]";
+
+ auto obj = WKTParser().createFromWKT(wkt1);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto convGot = crs->derivingConversion();
+
+ EXPECT_EQ(convGot->exportToWKT(WKTFormatter::create().get()),
+ "CONVERSION[\"unnamed\",\n"
+ " METHOD[\"Popular Visualisation Pseudo Mercator\",\n"
+ " ID[\"EPSG\",1024]],\n"
+ " PARAMETER[\"Latitude of natural origin\",0,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8801]],\n"
+ " PARAMETER[\"Longitude of natural origin\",0,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8802]],\n"
+ " PARAMETER[\"False easting\",0,\n"
+ " LENGTHUNIT[\"metre\",1],\n"
+ " ID[\"EPSG\",8806]],\n"
+ " PARAMETER[\"False northing\",0,\n"
+ " LENGTHUNIT[\"metre\",1],\n"
+ " ID[\"EPSG\",8807]]]");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, mollweide_export) {
auto conv = Conversion::createMollweide(PropertyMap(), Angle(1), Length(2),
@@ -4215,7 +4306,7 @@ TEST(operation, geogCRS_to_geogCRS_context_ntv1_ntv2_ctable2) {
authFactory->createCoordinateReferenceSystem("4267"), // NAD27
authFactory->createCoordinateReferenceSystem("4269"), // NAD83
ctxt);
- ASSERT_EQ(list.size(), 6);
+ ASSERT_EQ(list.size(), 7);
EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
"+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=hgridshift "
@@ -4447,6 +4538,38 @@ TEST(operation, geogCRS_to_geogCRS_CH1903_to_CH1903plus_context) {
// ---------------------------------------------------------------------------
+TEST(operation, geogCRS_to_geogCRS_init_IGNF_to_init_IGNF_context) {
+
+ auto dbContext = DatabaseContext::create();
+
+ auto sourceCRS_obj = PROJStringParser()
+ .attachDatabaseContext(dbContext)
+ .setUsePROJ4InitRules(true)
+ .createFromPROJString("+init=IGNF:NTFG");
+ auto sourceCRS = nn_dynamic_pointer_cast<CRS>(sourceCRS_obj);
+ ASSERT_TRUE(sourceCRS != nullptr);
+
+ auto targetCRS_obj = PROJStringParser()
+ .attachDatabaseContext(dbContext)
+ .setUsePROJ4InitRules(true)
+ .createFromPROJString("+init=IGNF:RGF93G");
+ auto targetCRS = nn_dynamic_pointer_cast<CRS>(targetCRS_obj);
+ ASSERT_TRUE(targetCRS != nullptr);
+
+ auto authFactory = AuthorityFactory::create(dbContext, std::string());
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ NN_CHECK_ASSERT(sourceCRS), NN_CHECK_ASSERT(targetCRS), ctxt);
+ ASSERT_EQ(list.size(), 1);
+
+ EXPECT_EQ(list[0]->nameStr(),
+ "NOUVELLE TRIANGULATION DE LA FRANCE (NTF) vers RGF93 (ETRS89)");
+ EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=hgridshift +grids=ntf_r93.gsb");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, geogCRS_to_geogCRS_3D) {
auto geogcrs_m_obj =
@@ -5080,6 +5203,83 @@ TEST(operation, boundCRS_of_geogCRS_to_unrelated_geogCRS) {
// ---------------------------------------------------------------------------
+TEST(operation, createOperation_boundCRS_identified_by_datum) {
+ auto objSrc =
+ PROJStringParser().createFromPROJString("+proj=longlat +datum=WGS84");
+ auto src = nn_dynamic_pointer_cast<GeographicCRS>(objSrc);
+ ASSERT_TRUE(src != nullptr);
+
+ auto objDest = PROJStringParser().createFromPROJString(
+ "+proj=utm +zone=32 +a=6378249.2 +b=6356515 "
+ "+towgs84=-263.0,6.0,431.0 +no_defs");
+ auto dest = nn_dynamic_pointer_cast<BoundCRS>(objDest);
+ ASSERT_TRUE(dest != nullptr);
+
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dest));
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +proj=cart +ellps=WGS84 "
+ "+step +proj=helmert +x=263 +y=-6 +z=-431 "
+ "+step +inv +proj=cart +ellps=clrk80ign "
+ "+step +proj=utm +zone=32 +ellps=clrk80ign");
+
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), std::string());
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dest), ctxt);
+ ASSERT_EQ(list.size(), 1U);
+ EXPECT_TRUE(list[0]->isEquivalentTo(op.get()));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(operation, boundCRS_of_clrk_66_geogCRS_to_nad83_geogCRS) {
+ auto objSrc = PROJStringParser().createFromPROJString(
+ "+proj=latlong +ellps=clrk66 +nadgrids=ntv1_can.dat,conus");
+ auto src = nn_dynamic_pointer_cast<CRS>(objSrc);
+ ASSERT_TRUE(src != nullptr);
+
+ auto objDest =
+ PROJStringParser().createFromPROJString("+proj=latlong +datum=NAD83");
+ auto dest = nn_dynamic_pointer_cast<CRS>(objDest);
+ ASSERT_TRUE(dest != nullptr);
+
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dest));
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +proj=hgridshift +grids=ntv1_can.dat,conus "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(operation, boundCRS_of_clrk_66_projCRS_to_nad83_geogCRS) {
+ auto objSrc = PROJStringParser().createFromPROJString(
+ "+proj=utm +zone=17 +ellps=clrk66 +nadgrids=ntv1_can.dat,conus");
+ auto src = nn_dynamic_pointer_cast<CRS>(objSrc);
+ ASSERT_TRUE(src != nullptr);
+
+ auto objDest =
+ PROJStringParser().createFromPROJString("+proj=latlong +datum=NAD83");
+ auto dest = nn_dynamic_pointer_cast<CRS>(objDest);
+ ASSERT_TRUE(dest != nullptr);
+
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dest));
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +inv +proj=utm +zone=17 +ellps=clrk66 "
+ "+step +proj=hgridshift +grids=ntv1_can.dat,conus "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, boundCRS_of_projCRS_to_geogCRS) {
auto utm31 = ProjectedCRS::create(
PropertyMap(), GeographicCRS::EPSG_4807,
@@ -5834,6 +6034,25 @@ TEST(operation, createOperation_on_crs_with_canonical_bound_crs) {
// ---------------------------------------------------------------------------
+TEST(operation, createOperation_fallback_to_proj4_strings) {
+ auto objDest = PROJStringParser().createFromPROJString(
+ "+proj=longlat +geoc +ellps=WGS84");
+ auto dest = nn_dynamic_pointer_cast<GeographicCRS>(objDest);
+ ASSERT_TRUE(dest != nullptr);
+
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ GeographicCRS::EPSG_4326, NN_CHECK_ASSERT(dest));
+ ASSERT_TRUE(op != nullptr);
+ EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline +step +proj=axisswap +order=2,1 "
+ "+step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +inv +proj=longlat +datum=WGS84 "
+ "+step +proj=longlat +geoc +ellps=WGS84 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, mercator_variant_A_to_variant_B) {
auto projCRS = ProjectedCRS::create(
PropertyMap(), GeographicCRS::EPSG_4326,