From afb37da0535186c6909d4410efc0a20c4a88c8c9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 21 Nov 2018 21:49:52 +0100 Subject: createFromUserInput("authname:code"): make it case insensitive regarding authname --- test/unit/test_io.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 26597f09..00da162c 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -7607,6 +7607,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( -- cgit v1.2.3 From 85a4e9149152dd97463651496854f9ecbd720b84 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 21 Nov 2018 22:55:53 +0100 Subject: Move 'builtins' test of src/gie.c to test/unit/gie_self_tests.cpp --- test/unit/CMakeLists.txt | 8 + test/unit/Makefile.am | 16 +- test/unit/gie_self_tests.cpp | 562 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 580 insertions(+), 6 deletions(-) create mode 100644 test/unit/gie_self_tests.cpp (limited to 'test/unit') diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 5138dafc..8a25d7a3 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -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..913a3f29 100644 --- a/test/unit/Makefile.am +++ b/test/unit/Makefile.am @@ -13,13 +13,11 @@ noinst_PROGRAMS = basic_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 -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 @@ -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: basic_test-check pj_phi2_test-check proj_errno_string_test-check test_cpp_api-check gie_self_tests-check diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp new file mode 100644 index 00000000..67a44fe5 --- /dev/null +++ b/test/unit/gie_self_tests.cpp @@ -0,0 +1,562 @@ +/****************************************************************************** + * + * Project: PROJ + * Purpose: Test + * Author: Even Rouault + * + ****************************************************************************** + * 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 +#include + +namespace { + +// --------------------------------------------------------------------------- + +TEST( gie, cart_selftest ) { + PJ_CONTEXT *ctx; + PJ *P; + PJ_COORD a, b, obs[2]; + PJ_COORD coord[2]; + + PJ_INFO info; + PJ_PROJ_INFO pj_info; + PJ_GRID_INFO grid_info; + PJ_INIT_INFO init_info; + + PJ_FACTORS factors; + + const PJ_OPERATIONS *oper_list; + const PJ_ELLPS *ellps_list; + const PJ_UNITS *unit_list; + const PJ_PRIME_MERIDIANS *pm_list; + + int err; + size_t n, sz; + double dist, h, t; + const char * const args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; + char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"}; + char buf[40]; + + /* An utm projection on the GRS80 ellipsoid */ + P = proj_create (PJ_DEFAULT_CTX, arg); + 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(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(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); + + /* test proj_create_crs_to_crs() */ + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL); + ASSERT_TRUE( P != nullptr ); + + 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); + ASSERT_LE(dist, 1e-7); + proj_destroy(P); + + /* let's make sure that only entries in init-files results in a usable PJ */ + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84", NULL); + ASSERT_TRUE( P == nullptr ); + proj_destroy(P); + + /* ********************************************************************** */ + /* Test info functions */ + /* ********************************************************************** */ + + /* proj_info() */ + /* this one is difficult to test, since the output changes with the setup */ + info = proj_info(); + + if (info.version[0] != '\0' ) { + char tmpstr[64]; + sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch); + 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 */ + 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); + + + /* check io-predicates */ + + /* angular in on fwd, linear out */ + 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 ); + 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 -- cgit v1.2.3 From b9d50247190e7b9ecd849ab260eb45edca3236cb Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 22 Nov 2018 21:32:51 +0100 Subject: Fix transformation between geographic CRS that differ by axis order and units --- test/unit/test_io.cpp | 14 ++++++++++++++ test/unit/test_operation.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 00da162c..6ccd5578 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -5381,6 +5381,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" diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index e62eddf9..528aa6b8 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()), -- cgit v1.2.3 From 549268ff39d4ef614bc8a32d7bd735e87802d78b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 22 Nov 2018 21:56:33 +0100 Subject: Make proj_create_crs_to_crs() use proj_obj_create_operations() and use area of use argument, and make createFromUserInput() recognize init=epsg: / init=IGNF: in legacy mode, that is when proj_context_get_use_proj4_init_rules() is used --- test/unit/gie_self_tests.cpp | 78 ++++++++++++++++++++++++++++++++------------ test/unit/test_io.cpp | 35 ++++++++++++++++++-- 2 files changed, 91 insertions(+), 22 deletions(-) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index 67a44fe5..8b90a22d 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -49,24 +49,11 @@ TEST( gie, cart_selftest ) { PJ_COORD a, b, obs[2]; PJ_COORD coord[2]; - PJ_INFO info; - PJ_PROJ_INFO pj_info; - PJ_GRID_INFO grid_info; - PJ_INIT_INFO init_info; - - PJ_FACTORS factors; - - const PJ_OPERATIONS *oper_list; - const PJ_ELLPS *ellps_list; - const PJ_UNITS *unit_list; - const PJ_PRIME_MERIDIANS *pm_list; - int err; size_t n, sz; double dist, h, t; const char * const args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; char arg[50] = {"+proj=utm; +zone=32; +ellps=GRS80"}; - char buf[40]; /* An utm projection on the GRS80 ellipsoid */ P = proj_create (PJ_DEFAULT_CTX, arg); @@ -246,10 +233,32 @@ TEST( gie, cart_selftest ) { /* 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() */ - P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL); + 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; @@ -257,14 +266,39 @@ TEST( gie, cart_selftest ) { b.xy.y = 5999669.3036037628; a = proj_trans(P, PJ_FWD, a); - ASSERT_LE(dist, 1e-7); + EXPECT_NEAR( a.xy.x, b.xy.x, 1e-9); + EXPECT_NEAR( a.xy.y, b.xy.y, 1e-9); proj_destroy(P); - /* let's make sure that only entries in init-files results in a usable PJ */ + /* 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 ); + 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( 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 */ /* ********************************************************************** */ @@ -345,7 +379,7 @@ TEST( gie, cart_selftest ) { proj_destroy(P); /* Check that proj_list_* functions work by looping through them */ - n = 0; + size_t n = 0; for (oper_list = proj_list_operations(); oper_list->id; ++oper_list) n++; ASSERT_NE(n, 0U); @@ -361,11 +395,15 @@ TEST( gie, cart_selftest ) { 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 */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80"); + 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)); @@ -425,7 +463,7 @@ TEST( gie, cart_selftest ) { /* 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 ); - a = proj_coord(NAN, NAN, NAN, NAN); + 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]) ) ); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 6ccd5578..99f58739 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -7448,12 +7448,43 @@ TEST(io, projparse_projected_title) { TEST(io, projparse_init) { + // 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 dbContext = DatabaseContext::create(); + auto obj = createFromUserInput("init=epsg:4326", dbContext, true); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_TRUE(crs->coordinateSystem()->isEquivalentTo( + EllipsoidalCS::createLongitudeLatitude(UnitOfMeasure::RADIAN) + .get())); + } + + { + // EPSG:3040 is normally northing-easting order, but in compatibillity + // mode it will be easting-northing + auto dbContext = DatabaseContext::create(); + auto obj = createFromUserInput("init=epsg:3040", dbContext, true); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_TRUE(crs->coordinateSystem()->isEquivalentTo( + CartesianCS::createEastingNorthing(UnitOfMeasure::METRE).get())); + } + { - auto obj = PROJStringParser().createFromPROJString("init=epsg:4326"); + auto obj = + PROJStringParser().createFromPROJString("init=ITRF2000:ITRF2005"); auto co = nn_dynamic_pointer_cast(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"); } { -- cgit v1.2.3 From a66c12277666489cac74535bad8d2cf565ad542d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 23 Nov 2018 15:51:33 +0100 Subject: cs2cs: upgrade to use proj_create_crs_to_crs() --- test/unit/test_c_api.cpp | 81 +++++++++++++++++++++++++++ test/unit/test_io.cpp | 103 ++++++++++++++++++++-------------- test/unit/test_operation.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+), 41 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 8c9f114b..6c22cade 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -809,6 +809,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(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, @@ -1955,4 +1971,69 @@ TEST_F(CApi, proj_obj_create_projections) { /* 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(crs); + ASSERT_NE(cs, nullptr); + ObjectKeeper keeperCs(cs); + + const char *type = proj_obj_cs_get_type(cs); + ASSERT_NE(type, nullptr); + EXPECT_EQ(std::string(type), "Ellipsoidal"); + + EXPECT_EQ(proj_obj_cs_get_axis_count(cs), 2); + + EXPECT_FALSE(proj_obj_cs_get_axis_info(cs, -1, nullptr, nullptr, + nullptr, nullptr, nullptr)); + + EXPECT_FALSE(proj_obj_cs_get_axis_info(cs, 2, nullptr, nullptr, nullptr, + nullptr, nullptr)); + + EXPECT_TRUE(proj_obj_cs_get_axis_info(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(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(obj), nullptr); + + EXPECT_EQ(proj_obj_cs_get_type(obj), nullptr); + + EXPECT_EQ(proj_obj_cs_get_axis_count(obj), -1); + + EXPECT_FALSE(proj_obj_cs_get_axis_info(obj, 0, nullptr, nullptr, + nullptr, nullptr, nullptr)); + } +} + } // namespace diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 99f58739..a4974234 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -5686,23 +5686,33 @@ TEST(io, projparse_longlat_a_f_non_zero) { PROJStringParser().createFromPROJString("+proj=longlat +a=2 +f=0.5"); auto crs = nn_dynamic_pointer_cast(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(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(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->ellipsoid()->semiMajorAxis().getSIValue(), 2); + auto rf = crs->ellipsoid()->computedInverseFlattening(); + EXPECT_EQ(rf, 3.4142135623730958) << rf; } // --------------------------------------------------------------------------- @@ -5711,23 +5721,31 @@ TEST(io, projparse_longlat_R) { auto obj = PROJStringParser().createFromPROJString("+proj=longlat +R=2"); auto crs = nn_dynamic_pointer_cast(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(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(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(); } // --------------------------------------------------------------------------- @@ -7505,6 +7523,16 @@ TEST(io, projparse_init) { EXPECT_EQ(co->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +init=epsg:4326 +step +proj=longlat"); } + + { + auto obj = PROJStringParser().createFromPROJString( + "init=epsg:4326 proj=longlat ellps=GRS80"); + auto crs = nn_dynamic_pointer_cast(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"); + } } // --------------------------------------------------------------------------- @@ -7536,10 +7564,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); } // --------------------------------------------------------------------------- @@ -7577,9 +7601,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); diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 528aa6b8..818c10ec 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4477,6 +4477,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(sourceCRS_obj); + ASSERT_TRUE(sourceCRS != nullptr); + + auto targetCRS_obj = PROJStringParser() + .attachDatabaseContext(dbContext) + .setUsePROJ4InitRules(true) + .createFromPROJString("+init=IGNF:RGF93G"); + auto targetCRS = nn_dynamic_pointer_cast(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 = @@ -5110,6 +5142,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(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(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(objSrc); + ASSERT_TRUE(src != nullptr); + + auto objDest = + PROJStringParser().createFromPROJString("+proj=latlong +datum=NAD83"); + auto dest = nn_dynamic_pointer_cast(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(objSrc); + ASSERT_TRUE(src != nullptr); + + auto objDest = + PROJStringParser().createFromPROJString("+proj=latlong +datum=NAD83"); + auto dest = nn_dynamic_pointer_cast(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, @@ -5864,6 +5973,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(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, -- cgit v1.2.3 From c57e293fbf2b79a24519c70d558e1268515a9ee6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 24 Nov 2018 11:01:11 +0100 Subject: Reformat test .cpp files --- test/unit/gie_self_tests.cpp | 452 ++++++++++++++++++----------------- test/unit/main.cpp | 8 +- test/unit/pj_phi2_test.cpp | 3 +- test/unit/proj_errno_string_test.cpp | 18 +- 4 files changed, 251 insertions(+), 230 deletions(-) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index 8b90a22d..7aca3001 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -43,7 +43,7 @@ namespace { // --------------------------------------------------------------------------- -TEST( gie, cart_selftest ) { +TEST(gie, cart_selftest) { PJ_CONTEXT *ctx; PJ *P; PJ_COORD a, b, obs[2]; @@ -52,187 +52,177 @@ TEST( gie, cart_selftest ) { int err; size_t n, sz; double dist, h, t; - const char * const args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; + 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 ); + P = proj_create(PJ_DEFAULT_CTX, arg); + ASSERT_TRUE(P != nullptr); /* Clean up */ - proj_destroy (P); + proj_destroy(P); /* Same projection, now using argc/argv style initialization */ - P = proj_create_argv (PJ_DEFAULT_CTX, 3, const_cast(args)); - ASSERT_TRUE( P != nullptr ); + P = proj_create_argv(PJ_DEFAULT_CTX, 3, const_cast(args)); + ASSERT_TRUE(P != nullptr); /* zero initialize everything, then set (longitude, latitude) to (12, 55) */ - a = proj_coord (0,0,0,0); + 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); + b = proj_trans(P, PJ_FWD, a); /* Inverse projection */ - a = proj_trans (P, PJ_INV, b); + a = proj_trans(P, PJ_INV, b); /* Null projection */ - a = proj_trans (P, PJ_IDENT, a); + a = proj_trans(P, PJ_IDENT, a); /* Forward again, to get two linear items for comparison */ - a = proj_trans (P, PJ_FWD, a); + a = proj_trans(P, PJ_FWD, a); - dist = proj_xy_dist (a, b); + dist = proj_xy_dist(a, b); ASSERT_LE(dist, 2e-9); /* Clear any previous error */ - proj_errno_reset (P); + proj_errno_reset(P); /* Invalid projection */ - a = proj_trans (P, static_cast(42), a); + a = proj_trans(P, static_cast(42), a); ASSERT_EQ(a.lpz.lam, HUGE_VAL); - err = proj_errno (P); + err = proj_errno(P); ASSERT_NE(err, 0); /* Clear error again */ - proj_errno_reset (P); + proj_errno_reset(P); /* Clean up */ - proj_destroy (P); + proj_destroy(P); /* Now do some 3D transformations */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80"); - ASSERT_TRUE( P != nullptr ); + 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); + /* 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; + a.lpz.z = 100; /* Forward projection: 3D-Cartesian-to-Ellipsoidal */ - b = proj_trans (P, PJ_FWD, a); + 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); + 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 = b = proj_coord(0, 0, 0, 0); a.lpz.lam = proj_torad(0); a.lpz.phi = proj_torad(90); - a.lpz.z = 100; + a.lpz.z = 100; /* Forward projection: Ellipsoidal-to-3D-Cartesian */ - dist = proj_roundtrip (P, PJ_FWD, 1, &a); + 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 = b = proj_coord(0, 0, 0, 0); a.lpz.lam = proj_torad(0); a.lpz.phi = proj_torad(-90); - a.lpz.z = 100; + a.lpz.z = 100; b = a; /* Forward projection: Ellipsoidal-to-3D-Cartesian */ - dist = proj_roundtrip (P, PJ_FWD, 1, &a); + 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); + b = proj_trans(P, PJ_INV, b); /* Move p to another context */ - ctx = proj_context_create (); - ASSERT_NE (ctx, pj_get_default_ctx()); + ctx = proj_context_create(); + ASSERT_NE(ctx, pj_get_default_ctx()); - proj_context_set (P, ctx); - ASSERT_EQ (ctx, P->ctx); + proj_context_set(P, ctx); + ASSERT_EQ(ctx, P->ctx); - b = proj_trans (P, PJ_FWD, b); + 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_set(P, 0); + ASSERT_EQ(pj_get_default_ctx(), P->ctx); - proj_context_destroy (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); - + 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 ); + 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); + 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 - ); + 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); + 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); + 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 - ); + 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); + 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)); + 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); + 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); + proj_destroy(P); } // --------------------------------------------------------------------------- @@ -254,34 +244,38 @@ class gieTest : public ::testing::Test { // --------------------------------------------------------------------------- -TEST_F( gieTest, proj_create_crs_to_crs ) { +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 ); + 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.x = 700000.0; a.xy.y = 6000000.0; - b.xy.x = 307788.8761171057; + 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); + 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 ); + 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 ); + 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( gie, info_functions ) { +TEST(gie, info_functions) { PJ_INFO info; PJ_PROJ_INFO pj_info; PJ_GRID_INFO grid_info; @@ -307,19 +301,20 @@ TEST( gie, info_functions ) { /* this one is difficult to test, since the output changes with the setup */ info = proj_info(); - if (info.version[0] != '\0' ) { + 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_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() ); + 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 */ + 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); @@ -327,156 +322,164 @@ TEST( gie, info_functions ) { 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" ); + 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" ); + 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), "" ); + ASSERT_EQ(std::string(grid_info.filename), ""); /* proj_init_info() */ init_info = proj_init_info("unknowninit"); - ASSERT_EQ( std::string(init_info.filename), "" ); + 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" ); - + /* 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(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')); + 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); + 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 = 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 */ + 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 */ + 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++; + 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++; + 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++; + 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++; + for (pm_list = proj_list_prime_meridians(); pm_list->id; ++pm_list) + n++; ASSERT_NE(n, 0U); - } // --------------------------------------------------------------------------- -TEST( gie, io_predicates ) { +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)); + 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)); + 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)); + "+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)); + 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)); + " +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)); + 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); + 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 ); + 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]) ) ); + 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]) ) ); + 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) { +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); @@ -497,7 +500,7 @@ static void test_time(const char* args, double tol, double t_in, double t_exp) { // --------------------------------------------------------------------------- -TEST( gie, unitconvert_selftest ) { +TEST(gie, unitconvert_selftest) { char args1[] = "+proj=unitconvert +t_in=decimalyear +t_out=decimalyear"; double in1 = 2004.25; @@ -521,7 +524,6 @@ TEST( gie, unitconvert_selftest ) { test_time(args5, 1e-6, in5, in5); } - static const char tc32_utm32[] = { " +proj=horner" " +ellps=intl" @@ -529,11 +531,22 @@ static const char tc32_utm32[] = { " +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" -}; + " +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" @@ -543,56 +556,63 @@ static const char sb_utm32[] = { " +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" -}; + " +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 ) { +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 ); + /* 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 = b = proj_coord(0, 0, 0, 0); a.uv.v = 6125305.4245; - a.uv.u = 878354.8539; + 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 ); + /* 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 ); + /* 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); + /* 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; + a.uv.u = 495136.8544; c.uv.v = 6130000.0000; - c.uv.u = 620000.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 ); + 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 ); + 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 ); + dist = proj_roundtrip(P, PJ_FWD, 1, &a); + EXPECT_LE(dist, 0.01); proj_destroy(P); } 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/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::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 -- cgit v1.2.3 From 7e05bd0ff52fe3ba78dfd75f9ebebe3dfe715bca Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 24 Nov 2018 11:19:45 +0100 Subject: Add unit test for pj_tranform() now that cs2cs no longer use it --- test/unit/CMakeLists.txt | 8 +- test/unit/Makefile.am | 12 +- test/unit/basic_test.cpp | 44 --- test/unit/pj_transform_test.cpp | 583 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 593 insertions(+), 54 deletions(-) delete mode 100644 test/unit/basic_test.cpp create mode 100644 test/unit/pj_transform_test.cpp (limited to 'test/unit') diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 8a25d7a3..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 diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am index 913a3f29..236ad444 100644 --- a/test/unit/Makefile.am +++ b/test/unit/Makefile.am @@ -9,17 +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 -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 @@ -45,4 +45,4 @@ gie_self_tests_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la @S gie_self_tests-check: gie_self_tests PROJ_LIB=$(PROJ_LIB) ./gie_self_tests -check-local: basic_test-check pj_phi2_test-check proj_errno_string_test-check test_cpp_api-check gie_self_tests-check +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 - * - ****************************************************************************** - * Copyright (c) 2018, Even Rouault - * - * 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 -#include - -namespace { - -// --------------------------------------------------------------------------- - -TEST( dumy, dummy ) { - std::unique_ptr 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/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 + * + ****************************************************************************** + * Copyright (c) 2018, Even Rouault + * + * 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 + +// PROJ include order is sensitive +// clang-format off +#include +#include +// 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 -- cgit v1.2.3 From 67758b2c67ea329116b59818c038797667c4e1d1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 26 Nov 2018 15:47:57 +0100 Subject: Redirect epsg:XXXX and IGNF:XXXX CRS expansions to the database, and remove the data/epsg and data/IGNF files --- test/unit/test_c_api.cpp | 7 +++++++ test/unit/test_factory.cpp | 10 ++++++++++ test/unit/test_io.cpp | 16 ++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 6c22cade..d23920f5 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -2036,4 +2036,11 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { } } +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_context_get_database_metadata) { + EXPECT_TRUE(proj_context_get_database_metadata(m_ctxt, "IGNF.VERSION") != + nullptr); +} + } // namespace diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 739bb729..20869d91 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -2729,4 +2729,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 a4974234..a2a865ad 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -7465,6 +7465,7 @@ 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"), @@ -7473,7 +7474,6 @@ TEST(io, projparse_init) { { // EPSG:4326 is normally latitude-longitude order with degree, // but in compatibillity mode it will be long-lat radian - auto dbContext = DatabaseContext::create(); auto obj = createFromUserInput("init=epsg:4326", dbContext, true); auto crs = nn_dynamic_pointer_cast(obj); ASSERT_TRUE(crs != nullptr); @@ -7485,7 +7485,6 @@ TEST(io, projparse_init) { { // EPSG:3040 is normally northing-easting order, but in compatibillity // mode it will be easting-northing - auto dbContext = DatabaseContext::create(); auto obj = createFromUserInput("init=epsg:3040", dbContext, true); auto crs = nn_dynamic_pointer_cast(obj); ASSERT_TRUE(crs != nullptr); @@ -7506,8 +7505,8 @@ TEST(io, projparse_init) { } { - 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(obj); ASSERT_TRUE(co != nullptr); EXPECT_EQ(co->nameStr(), "mytitle"); @@ -7516,8 +7515,9 @@ 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(obj); ASSERT_TRUE(co != nullptr); EXPECT_EQ(co->exportToPROJString(PROJStringFormatter::create().get()), @@ -7525,8 +7525,8 @@ TEST(io, projparse_init) { } { - auto obj = PROJStringParser().createFromPROJString( - "init=epsg:4326 proj=longlat ellps=GRS80"); + auto obj = createFromUserInput( + "init=epsg:4326 proj=longlat ellps=GRS80", dbContext, true); auto crs = nn_dynamic_pointer_cast(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), -- cgit v1.2.3 From ff7f5da97563f697fd70eeb161dbebe24b39e8d2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 28 Nov 2018 19:51:49 +0100 Subject: importFromWKT: check we have a valid unit where we need one --- test/unit/test_io.cpp | 112 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 36 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index a2a865ad..fa0305cc 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -768,6 +768,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(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); @@ -2641,9 +2663,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 +2684,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 +4163,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 +4252,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 +4288,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 +4296,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 +4822,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 +4834,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 +5012,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 +5033,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 +5068,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 +5077,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 +5094,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 +5124,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 +5133,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 +5154,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); } -- cgit v1.2.3 From d87573cf62b339f22b24595fd05714f1b4e3bda3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 28 Nov 2018 20:13:42 +0100 Subject: exportToWKT WKT1_GDAL: export axis by default for GeocentricCRS --- test/unit/test_crs.cpp | 3 +++ test/unit/test_io.cpp | 3 +++ 2 files changed, 6 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index 55df5875..fa64620c 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\"]]"); } diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index fa0305cc..7fdb1358 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -493,6 +493,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); -- cgit v1.2.3 From 6d9a1a909886762cc99e1d8f289e2b60ea787bf7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 29 Nov 2018 02:52:22 +0100 Subject: Preserve EPSG code when importFromWKT WKT1_GDAL of EPSG:3857 --- test/unit/test_operation.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 818c10ec..c2e35e89 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -3016,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(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->identifiers().size(), 1); +} + +// --------------------------------------------------------------------------- + TEST(operation, webmerc_import_from_GDAL_wkt1_EPSG_3785_deprecated) { auto wkt1 = -- cgit v1.2.3 From cf855b24d2b901054bee90309cdc5df00dfb3085 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 28 Nov 2018 14:52:56 +0100 Subject: C API extensions and renaming - proj_obj_create_projected_XXXXX() are renamed to proj_obj_create_conversion_snake_case() and just instanciate a Conversion object - Advanced manipulation functions are moved to a dedicated section at bottom of proj.h - New C API needed for GDAL OGRSpatialReference --- test/unit/test_c_api.cpp | 656 ++++++++++++++++++++++++++++++++--------------- test/unit/test_crs.cpp | 133 ++++++++++ 2 files changed, 584 insertions(+), 205 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index d23920f5..e033c0c8 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -390,6 +390,25 @@ TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84) { "+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(res); + ObjectKeeper keeper_base_crs(base_crs); + ASSERT_NE(base_crs, nullptr); + + auto hub_crs = proj_obj_get_target_crs(res); + ObjectKeeper keeper_hub_crs(hub_crs); + ASSERT_NE(hub_crs, nullptr); + + auto transf = + proj_obj_crs_get_coordoperation(res, nullptr, nullptr, nullptr); + ObjectKeeper keeper_transf(transf); + ASSERT_NE(transf, nullptr); + + auto res2 = proj_obj_crs_create_bound_crs(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)); } // --------------------------------------------------------------------------- @@ -655,9 +674,16 @@ 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(crs); + ASSERT_NE(h_datum, nullptr); + ObjectKeeper keeper_h_datum(h_datum); + + auto datum = proj_obj_crs_get_datum(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")); @@ -1468,11 +1494,16 @@ TEST_F(CApi, proj_coordoperation_get_accuracy) { // --------------------------------------------------------------------------- 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); @@ -1485,11 +1516,22 @@ 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(obj); + ObjectKeeper keeper_datum(datum); + ASSERT_NE(datum, nullptr); + + auto obj2 = + proj_obj_create_geographic_crs_from_datum("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); } @@ -1497,474 +1539,458 @@ TEST_F(CApi, proj_obj_create_geographic_crs) { // --------------------------------------------------------------------------- -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(obj); + ObjectKeeper keeper_datum(datum); + ASSERT_NE(datum, nullptr); + + auto obj2 = proj_obj_create_geocentric_crs_from_datum("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); } @@ -1984,9 +2010,7 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { ASSERT_NE(cs, nullptr); ObjectKeeper keeperCs(cs); - const char *type = proj_obj_cs_get_type(cs); - ASSERT_NE(type, nullptr); - EXPECT_EQ(std::string(type), "Ellipsoidal"); + EXPECT_EQ(proj_obj_cs_get_type(cs), PJ_CS_TYPE_ELLIPSOIDAL); EXPECT_EQ(proj_obj_cs_get_axis_count(cs), 2); @@ -2027,7 +2051,7 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { ObjectKeeper keeper(obj); EXPECT_EQ(proj_obj_crs_get_coordinate_system(obj), nullptr); - EXPECT_EQ(proj_obj_cs_get_type(obj), nullptr); + EXPECT_EQ(proj_obj_cs_get_type(obj), PJ_CS_TYPE_UNKNOWN); EXPECT_EQ(proj_obj_cs_get_axis_count(obj), -1); @@ -2043,4 +2067,226 @@ TEST_F(CApi, proj_context_get_database_metadata) { 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(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(projCRS); + ObjectKeeper keeper_geodCRS(geodCRS); + ASSERT_NE(geodCRS, nullptr); + + auto geodCRSAltered = proj_obj_crs_alter_geodetic_crs(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(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(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(crs, "my unit", 2); + ObjectKeeper keeper_alteredCRS(alteredCRS); + ASSERT_NE(alteredCRS, nullptr); + + auto cs = proj_obj_crs_get_coordinate_system(alteredCRS); + ASSERT_NE(cs, nullptr); + ObjectKeeper keeperCs(cs); + double unitConvFactor = 0.0; + const char *unitName = nullptr; + + EXPECT_TRUE(proj_obj_cs_get_axis_info(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(crs, "my unit", 2); + ObjectKeeper keeper_alteredCRS(alteredCRS); + ASSERT_NE(alteredCRS, nullptr); + + auto cs = proj_obj_crs_get_coordinate_system(alteredCRS); + ASSERT_NE(cs, nullptr); + ObjectKeeper keeperCs(cs); + double unitConvFactor = 0.0; + const char *unitName = nullptr; + + EXPECT_TRUE(proj_obj_cs_get_axis_info(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(crs, "my unit", 2, false); + ObjectKeeper keeper_alteredCRS(alteredCRS); + ASSERT_NE(alteredCRS, nullptr); + + auto wkt = proj_obj_as_wkt(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(crs, "my unit", 2, true); + ObjectKeeper keeper_alteredCRS(alteredCRS); + ASSERT_NE(alteredCRS, nullptr); + + auto wkt = proj_obj_as_wkt(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(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(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, ¶m); + 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("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 fa64620c..bbbf2154 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -4665,3 +4665,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(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(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(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(crs.get()); + ASSERT_TRUE(geodCRS != nullptr); + auto cs = + dynamic_cast(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(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(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; + } +} -- cgit v1.2.3 From 7b3ab527074e301bc81cedee7b8111c633ecf306 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 29 Nov 2018 12:35:49 +0100 Subject: proj_create_crs_to_crs(): rename arguments, update doc, and add a few test cases --- test/unit/gie_self_tests.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index 7aca3001..b7af926b 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -275,6 +275,50 @@ TEST_F(gieTest, proj_create_crs_to_crs) { // --------------------------------------------------------------------------- +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; -- cgit v1.2.3 From 53b83f447b82b59d944d63b336839676d8265b88 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 29 Nov 2018 16:04:49 +0100 Subject: importFromWKT v1: properly handle latitude_of_origin=0 for Mercator_1SP --- test/unit/test_io.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 7fdb1358..0cf36766 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -991,6 +991,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(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\"," -- cgit v1.2.3 From 664bd689bf8dd3ca38a5071459902b89114e88eb Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Nov 2018 02:36:00 +0100 Subject: C API: do not 'cache' PROJ context in PJ_OBJ objects We store the PJ_CONTEXT* in the PJ_OBJ objects, but this might cause issues in multi-threaded uses. For example, before this change, let's imagie: - a PJ_OBJ is created in thread A with a PJ_CONTEXT that is specific to this thread A - PJ_OBJ is transfered to another thread that operates on it. It might thus use the PJ_CONTEXT that was TLS(A) - in the meantime thread A does completely different things, but still operate on its PJ_CONTEXT. We might get a concurrent use of the PJ_CONTEXT despite working on different PJ_OBJ Another situation is when using constructor functions that take two PJ_OBJ. Up to now, we arbitrarily selected the context of one of the arguments to attach it to the new object. So better be explicit on which context is used. For reference, in those wrappers of the C++ API, the context is mostly used for two things: - reporting C++ exceptions as PROJ errors with the error handler attached to the PJ_CONTEXT - using the database handle that is associated with the PJ_CONTEXT. --- test/unit/test_c_api.cpp | 330 +++++++++++++++++++++++++---------------------- 1 file changed, 174 insertions(+), 156 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index e033c0c8..51de990b 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -198,13 +198,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 +213,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 +228,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 +243,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 +251,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 +260,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 +268,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 +276,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,7 +284,7 @@ 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); } } @@ -297,7 +299,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 +315,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 +323,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 +339,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 +351,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 +366,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,11 +381,11 @@ 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 " @@ -391,20 +393,21 @@ TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84) { "+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(res); + 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(res); + 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(res, nullptr, nullptr, nullptr); + 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(base_crs, hub_crs, transf); + auto res2 = + proj_obj_crs_create_bound_crs(m_ctxt, base_crs, hub_crs, transf); ObjectKeeper keeper_res2(res2); ASSERT_NE(res2, nullptr); @@ -423,7 +426,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); } @@ -666,7 +669,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)); @@ -674,11 +677,11 @@ TEST_F(CApi, proj_crs) { ASSERT_TRUE(geogCRS_name != nullptr); EXPECT_EQ(geogCRS_name, std::string("WGS 84")); - auto h_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(crs); + auto datum = proj_obj_crs_get_datum(m_ctxt, crs); ASSERT_NE(datum, nullptr); ObjectKeeper keeper_datum(datum); @@ -688,30 +691,30 @@ TEST_F(CApi, proj_crs) { 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); @@ -734,31 +737,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); } @@ -774,16 +777,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); @@ -799,12 +802,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"); @@ -822,12 +825,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"); @@ -843,7 +846,7 @@ TEST_F(CApi, proj_obj_get_source_crs_of_projected_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)), "WGS 84"); @@ -858,10 +861,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); } @@ -873,10 +876,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); } @@ -965,21 +968,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); @@ -990,16 +993,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; @@ -1009,8 +1013,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); @@ -1035,7 +1039,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); } @@ -1049,7 +1053,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; @@ -1057,16 +1061,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); @@ -1091,7 +1095,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); } // --------------------------------------------------------------------------- @@ -1112,20 +1116,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(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); @@ -1154,11 +1159,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); @@ -1173,14 +1179,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); @@ -1195,18 +1202,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); + auto op = proj_obj_list_get(m_ctxt, res, 0); ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); @@ -1223,19 +1231,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); + auto op = proj_obj_list_get(m_ctxt, res, 0); ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); @@ -1406,13 +1415,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); @@ -1425,7 +1434,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); } @@ -1439,14 +1449,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); @@ -1459,8 +1470,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)); } } @@ -1472,7 +1483,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( @@ -1480,14 +1491,14 @@ 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); } } @@ -1517,12 +1528,12 @@ TEST_F(CApi, proj_obj_create_geographic_crs) { EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT)); - auto datum = proj_obj_crs_get_datum(obj); + 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("WGS 84", datum, cs); + auto obj2 = proj_obj_create_geographic_crs_from_datum(m_ctxt, "WGS 84", + datum, cs); ObjectKeeper keeperObj(obj2); ASSERT_NE(obj2, nullptr); @@ -1558,12 +1569,12 @@ TEST_F(CApi, proj_obj_create_geocentric_crs) { EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT)); - auto datum = proj_obj_crs_get_datum(obj); + 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("WGS 84", datum, - "Metre", 1.0); + auto obj2 = proj_obj_create_geocentric_crs_from_datum( + m_ctxt, "WGS 84", datum, "Metre", 1.0); ObjectKeeper keeperObj(obj2); ASSERT_NE(obj2, nullptr); @@ -2006,22 +2017,22 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { ASSERT_NE(crs, nullptr); ObjectKeeper keeper(crs); - auto cs = proj_obj_crs_get_coordinate_system(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(cs), PJ_CS_TYPE_ELLIPSOIDAL); + EXPECT_EQ(proj_obj_cs_get_type(m_ctxt, cs), PJ_CS_TYPE_ELLIPSOIDAL); - EXPECT_EQ(proj_obj_cs_get_axis_count(cs), 2); + EXPECT_EQ(proj_obj_cs_get_axis_count(m_ctxt, cs), 2); - EXPECT_FALSE(proj_obj_cs_get_axis_info(cs, -1, nullptr, nullptr, + 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(cs, 2, 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(cs, 0, 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; @@ -2029,8 +2040,9 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { double unitConvFactor = 0.0; const char *unitName = nullptr; - EXPECT_TRUE(proj_obj_cs_get_axis_info(cs, 0, &name, &abbrev, &direction, - &unitConvFactor, &unitName)); + 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); @@ -2049,13 +2061,13 @@ TEST_F(CApi, proj_obj_cs_get_axis_info) { nullptr); ASSERT_NE(obj, nullptr); ObjectKeeper keeper(obj); - EXPECT_EQ(proj_obj_crs_get_coordinate_system(obj), nullptr); + EXPECT_EQ(proj_obj_crs_get_coordinate_system(m_ctxt, obj), nullptr); - EXPECT_EQ(proj_obj_cs_get_type(obj), PJ_CS_TYPE_UNKNOWN); + EXPECT_EQ(proj_obj_cs_get_type(m_ctxt, obj), PJ_CS_TYPE_UNKNOWN); - EXPECT_EQ(proj_obj_cs_get_axis_count(obj), -1); + EXPECT_EQ(proj_obj_cs_get_axis_count(m_ctxt, obj), -1); - EXPECT_FALSE(proj_obj_cs_get_axis_info(obj, 0, nullptr, nullptr, + EXPECT_FALSE(proj_obj_cs_get_axis_info(m_ctxt, obj, 0, nullptr, nullptr, nullptr, nullptr, nullptr)); } } @@ -2075,7 +2087,7 @@ TEST_F(CApi, proj_obj_clone) { ObjectKeeper keeper(obj); ASSERT_NE(obj, nullptr); - auto clone = proj_obj_clone(obj); + auto clone = proj_obj_clone(m_ctxt, obj); ObjectKeeper keeperClone(clone); ASSERT_NE(clone, nullptr); @@ -2097,23 +2109,26 @@ TEST_F(CApi, proj_obj_crs_alter_geodetic_crs) { ObjectKeeper keeper_newGeodCRS(newGeodCRS); ASSERT_NE(newGeodCRS, nullptr); - auto geodCRS = proj_obj_crs_get_geodetic_crs(projCRS); + 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(geodCRS, newGeodCRS); + 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(projCRS, newGeodCRS); + 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(projCRSAltered); + auto projCRSAltered_geodCRS = + proj_obj_crs_get_geodetic_crs(m_ctxt, projCRSAltered); ObjectKeeper keeper_projCRSAltered_geodCRS(projCRSAltered_geodCRS); ASSERT_NE(projCRSAltered_geodCRS, nullptr); @@ -2132,18 +2147,19 @@ TEST_F(CApi, proj_obj_crs_alter_cs_angular_unit) { ObjectKeeper keeper(crs); ASSERT_NE(crs, nullptr); - auto alteredCRS = proj_obj_crs_alter_cs_angular_unit(crs, "my unit", 2); + 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(alteredCRS); + 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(cs, 0, nullptr, nullptr, nullptr, - &unitConvFactor, &unitName)); + 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"); @@ -2159,18 +2175,19 @@ TEST_F(CApi, proj_obj_crs_alter_cs_linear_unit) { ObjectKeeper keeper(crs); ASSERT_NE(crs, nullptr); - auto alteredCRS = proj_obj_crs_alter_cs_linear_unit(crs, "my unit", 2); + 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(alteredCRS); + 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(cs, 0, nullptr, nullptr, nullptr, - &unitConvFactor, &unitName)); + 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"); @@ -2187,12 +2204,12 @@ TEST_F(CApi, proj_obj_crs_alter_parameters_linear_unit) { ASSERT_NE(crs, nullptr); { - auto alteredCRS = - proj_obj_crs_alter_parameters_linear_unit(crs, "my unit", 2, false); + 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(alteredCRS, PJ_WKT2_2018, 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; @@ -2201,12 +2218,12 @@ TEST_F(CApi, proj_obj_crs_alter_parameters_linear_unit) { } { - auto alteredCRS = - proj_obj_crs_alter_parameters_linear_unit(crs, "my unit", 2, true); + 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(alteredCRS, PJ_WKT2_2018, 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; @@ -2222,7 +2239,7 @@ 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(crs, PJ_WKT1_GDAL, 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; } @@ -2242,7 +2259,7 @@ TEST_F(CApi, proj_obj_alter_name) { ObjectKeeper keeper(obj); ASSERT_NE(obj, nullptr); - auto alteredObj = proj_obj_alter_name(obj, "new name"); + auto alteredObj = proj_obj_alter_name(m_ctxt, obj, "new name"); ObjectKeeper keeper_alteredObj(alteredObj); ASSERT_NE(alteredObj, nullptr); @@ -2284,7 +2301,8 @@ TEST_F(CApi, proj_obj_create_projected_crs) { ObjectKeeper keeper_cs(cs); ASSERT_NE(cs, nullptr); - auto projCRS = proj_obj_create_projected_crs("my CRS", geogCRS, conv, cs); + auto projCRS = + proj_obj_create_projected_crs(m_ctxt, "my CRS", geogCRS, conv, cs); ObjectKeeper keeper_projCRS(projCRS); ASSERT_NE(projCRS, nullptr); } -- cgit v1.2.3 From b6a5c445e202e61c64b0986679a6e0a83724c322 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Nov 2018 16:15:36 +0100 Subject: API: move all advanced PJ_OBJ creation functions in a dedicated proj_experimental.h header --- test/unit/test_c_api.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 51de990b..59ba12ca 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" -- cgit v1.2.3 From 9d19d5578705e06990fb716adcb9e6a1529424aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 30 Nov 2018 18:37:12 +0100 Subject: importFromWKT: morph GDAL_WKT1 datum names into their EPSG spelling --- test/unit/test_c_api.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/test_io.cpp | 27 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 59ba12ca..855ebf36 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -292,6 +292,25 @@ TEST_F(CApi, proj_obj_as_wkt) { // --------------------------------------------------------------------------- +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, @@ -1547,6 +1566,44 @@ TEST_F(CApi, proj_obj_create_geographic_crs) { 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)); + } } // --------------------------------------------------------------------------- diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 0cf36766..6a2de028 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -401,6 +401,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(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" -- cgit v1.2.3 From 18dbc00dc30db7ca5fa7bd6a00115628324dcd0c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 1 Dec 2018 17:29:19 +0100 Subject: importFromWKT: deal with uncommon formulation of EPSG:3857 --- test/unit/test_operation.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index c2e35e89..bb8221fd 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -3187,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(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), -- cgit v1.2.3 From 0a746073ca3bba1f186024210555b81c741ace0c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 1 Dec 2018 20:21:20 +0100 Subject: Fix PROJ_GRID_AVAILABILITY_IGNORED --- test/unit/test_c_api.cpp | 8 ++++---- test/unit/test_operation.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 855ebf36..7db38601 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1145,7 +1145,7 @@ TEST_F(CApi, proj_obj_create_operations) { 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(m_ctxt, res, -1), nullptr); EXPECT_EQ(proj_obj_list_get(m_ctxt, res, proj_obj_list_get_count(res)), @@ -1233,8 +1233,8 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) { 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(m_ctxt, 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); @@ -1263,7 +1263,7 @@ TEST_F(CApi, proj_obj_create_operations_with_pivot) { ASSERT_NE(res, nullptr); ObjListKeeper keeper_res(res); // includes 2 results from ESRI - EXPECT_EQ(proj_obj_list_get_count(res), 4); + 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); diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index bb8221fd..057f1717 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4306,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 " -- cgit v1.2.3 From 0ab18674d2b1ea8060ce6eb59c676f9ce98d50fb Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 2 Dec 2018 19:12:28 +0100 Subject: improve identify() for projected and bound CRS --- test/unit/test_crs.cpp | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index bbbf2154..91ed145c 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1216,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(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); + } } // --------------------------------------------------------------------------- @@ -1892,6 +1909,71 @@ TEST(crs, projectedCRS_identify_db) { EXPECT_EQ(res.front().first->getEPSGCode(), 3375); 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(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(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(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); + } { // No equivalent CRS to input one in result set auto obj = @@ -3410,6 +3492,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(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; + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 9577f8e018a7fd3fe57fc934259f441cbf22cb1d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 2 Dec 2018 22:27:51 +0100 Subject: identify: improve GeographicCRS identification when the CRS name has no match --- test/unit/test_crs.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index 91ed145c..74f85d50 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1974,6 +1974,28 @@ TEST(crs, projectedCRS_identify_db) { 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(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 = -- cgit v1.2.3 From 2d8f295354ce20f2d375a985ff48fd5e7f8b90ca Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 3 Dec 2018 13:51:41 +0100 Subject: WKTParser: fix to avoid creation of empty nodes --- test/unit/test_io.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 6a2de028..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); + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From ba111ac8323ff194039a06db87d1fb17ed8175b3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 3 Dec 2018 16:44:21 +0100 Subject: Export to ESRI WKT: make it use verbatim WKT definition from the database when possible --- test/unit/test_crs.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++ test/unit/test_factory.cpp | 7 ++++++ 2 files changed, 61 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index 74f85d50..3f044de0 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1685,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(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()), diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 20869d91..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::PRIME_MERIDIAN, AuthorityFactory::ObjectType::ELLIPSOID, -- cgit v1.2.3