aboutsummaryrefslogtreecommitdiff
path: root/test/unit
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-17 00:24:03 +0100
committerEven Rouault <even.rouault@spatialys.com>2020-01-17 00:52:19 +0100
commit4724025e6c817761052fc0dc8810fd489a9e0104 (patch)
tree21117e52f95b8f36880efef8cd71c1fcec21242c /test/unit
parent66fd99a8831955034cb25c8468ecfe1f9d3a7d62 (diff)
parentd76e6202d27c730b4dcbf16b8c1575c11b703485 (diff)
downloadPROJ-4724025e6c817761052fc0dc8810fd489a9e0104.tar.gz
PROJ-4724025e6c817761052fc0dc8810fd489a9e0104.zip
Merge branch 'master' into rfc4_merge_back_master
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/CMakeLists.txt30
-rw-r--r--test/unit/Makefile.am2
-rw-r--r--test/unit/pj_transform_test.cpp32
-rw-r--r--test/unit/test_c_api.cpp62
-rw-r--r--test/unit/test_crs.cpp184
-rw-r--r--test/unit/test_datum.cpp3
-rw-r--r--test/unit/test_factory.cpp10
-rw-r--r--test/unit/test_io.cpp98
-rw-r--r--test/unit/test_operation.cpp138
9 files changed, 517 insertions, 42 deletions
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index e14d4c70..f5890f1a 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -71,7 +71,7 @@ target_link_libraries(proj_pj_transform_test
${PROJ_LIBRARIES})
add_test(NAME proj_pj_transform_test COMMAND proj_pj_transform_test)
set_property(TEST proj_pj_transform_test
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
add_executable(proj_errno_string_test
@@ -82,7 +82,7 @@ target_link_libraries(proj_errno_string_test
${PROJ_LIBRARIES})
add_test(NAME proj_errno_string_test COMMAND proj_errno_string_test)
set_property(TEST proj_errno_string_test
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
add_executable(proj_angular_io_test
main.cpp
@@ -92,7 +92,7 @@ target_link_libraries(proj_angular_io_test
${PROJ_LIBRARIES})
add_test(NAME proj_angular_io_test COMMAND proj_angular_io_test)
set_property(TEST proj_angular_io_test
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
add_executable(proj_context_test
main.cpp
@@ -102,7 +102,7 @@ target_link_libraries(proj_context_test
${PROJ_LIBRARIES})
add_test(NAME proj_context_test COMMAND proj_context_test)
set_property(TEST proj_context_test
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
if(MSVC AND BUILD_LIBPROJ_SHARED)
# ph_phi2_test not compatible of a .dll build
@@ -115,7 +115,7 @@ else()
${PROJ_LIBRARIES})
add_test(NAME pj_phi2_test COMMAND pj_phi2_test)
set_property(TEST pj_phi2_test
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
endif()
add_executable(proj_test_cpp_api
@@ -135,13 +135,8 @@ target_link_libraries(proj_test_cpp_api
${PROJ_LIBRARIES}
${SQLITE3_LIBRARY})
add_test(NAME proj_test_cpp_api COMMAND proj_test_cpp_api)
-if(MSVC)
- set_property(TEST proj_test_cpp_api
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data\\;${PROJECT_SOURCE_DIR}/data")
-else()
- set_property(TEST proj_test_cpp_api
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data:${PROJECT_SOURCE_DIR}/data")
-endif()
+set_property(TEST proj_test_cpp_api
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
add_executable(gie_self_tests
@@ -152,7 +147,7 @@ target_link_libraries(gie_self_tests
${PROJ_LIBRARIES})
add_test(NAME gie_self_tests COMMAND gie_self_tests)
set_property(TEST gie_self_tests
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data")
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests")
add_executable(test_network
@@ -167,10 +162,5 @@ target_link_libraries(test_network
${PROJ_LIBRARIES}
${SQLITE3_LIBRARY})
add_test(NAME test_network COMMAND test_network)
-if(MSVC)
- set_property(TEST test_network
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data\\;${PROJECT_SOURCE_DIR}/data;PROJ_SOURCE_DATA=${PROJECT_SOURCE_DIR}/data")
-else()
- set_property(TEST test_network
- PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data:${PROJECT_SOURCE_DIR}/data;PROJ_SOURCE_DATA=${PROJECT_SOURCE_DIR}/data")
-endif()
+set_property(TEST test_network
+ PROPERTY ENVIRONMENT "PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES;PROJ_LIB=${PROJECT_BINARY_DIR}/data/for_tests;PROJ_SOURCE_DATA=${PROJECT_SOURCE_DIR}/data")
diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am
index b7a26d4e..86ed383a 100644
--- a/test/unit/Makefile.am
+++ b/test/unit/Makefile.am
@@ -7,7 +7,7 @@ noinst_HEADERS = gtest_include.h test_primitives.hpp
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_srcdir)/test @GTEST_CFLAGS@ @SQLITE3_CFLAGS@
AM_CXXFLAGS = @CXX_WFLAGS@ @NO_ZERO_AS_NULL_POINTER_CONSTANT_FLAG@
-PROJ_LIB ?= ../../data
+PROJ_LIB ?= ../../data/for_tests
noinst_PROGRAMS = pj_transform_test
noinst_PROGRAMS += pj_phi2_test
diff --git a/test/unit/pj_transform_test.cpp b/test/unit/pj_transform_test.cpp
index 5ca8dcce..ddb054f0 100644
--- a/test/unit/pj_transform_test.cpp
+++ b/test/unit/pj_transform_test.cpp
@@ -632,6 +632,23 @@ TEST(proj_api_h, default_fileapi) {
// ---------------------------------------------------------------------------
+TEST(pj_transform_test, ob_tran_to_meter_as_dest) {
+ auto src = pj_init_plus(
+ "+ellps=WGS84 +a=57.29577951308232 +proj=eqc +lon_0=0.0 +no_defs");
+ auto dst = pj_init_plus("+ellps=WGS84 +proj=ob_tran +o_proj=latlon "
+ "+o_lon_p=0.0 +o_lat_p=90.0 +lon_0=360.0 "
+ "+to_meter=0.0174532925199433 +no_defs");
+ 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);
+}
+
+// ---------------------------------------------------------------------------
+
struct Spy {
bool gotInMyFOpen = false;
bool gotInMyFRead = false;
@@ -705,4 +722,19 @@ TEST(proj_api_h, custom_fileapi) {
EXPECT_TRUE(spy.gotInMyFClose);
}
+TEST(pj_transform_test, ob_tran_to_meter_as_srouce) {
+ auto src = pj_init_plus("+ellps=WGS84 +proj=ob_tran +o_proj=latlon "
+ "+o_lon_p=0.0 +o_lat_p=90.0 +lon_0=360.0 "
+ "+to_meter=0.0174532925199433 +no_defs");
+ auto dst = pj_init_plus(
+ "+ellps=WGS84 +a=57.29577951308232 +proj=eqc +lon_0=0.0 +no_defs");
+ 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);
+}
+
} // namespace
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 8871f679..5c6dabba 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -1668,7 +1668,7 @@ TEST_F(CApi, proj_create_from_name) {
false, 0, nullptr);
ASSERT_NE(res, nullptr);
ObjListKeeper keeper_res(res);
- EXPECT_EQ(proj_list_get_count(res), 4);
+ EXPECT_EQ(proj_list_get_count(res), 5);
}
{
auto res = proj_create_from_name(m_ctxt, "xx", "WGS 84", nullptr, 0,
@@ -3486,6 +3486,36 @@ TEST_F(CApi, proj_normalize_for_visualization_on_crs) {
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_coordoperation_create_inverse) {
+
+ auto P = proj_create(
+ m_ctxt, "+proj=pipeline +step +proj=axisswap +order=2,1 +step "
+ "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push "
+ "+v_3 +step +proj=cart +ellps=evrst30 +step +proj=helmert "
+ "+x=293 +y=836 +z=318 +rx=0.5 +ry=1.6 +rz=-2.8 +s=2.1 "
+ "+convention=position_vector +step +inv +proj=cart "
+ "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert "
+ "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1");
+ ObjectKeeper keeper_P(P);
+ ASSERT_NE(P, nullptr);
+ auto Pinversed = proj_coordoperation_create_inverse(m_ctxt, P);
+ ObjectKeeper keeper_Pinversed(Pinversed);
+ ASSERT_NE(Pinversed, nullptr);
+
+ auto projstr = proj_as_proj_string(m_ctxt, Pinversed, PJ_PROJ_5, nullptr);
+ ASSERT_NE(projstr, nullptr);
+ EXPECT_EQ(std::string(projstr),
+ "+proj=pipeline +step +proj=axisswap +order=2,1 +step "
+ "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 "
+ "+step +proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=293 "
+ "+y=836 +z=318 +rx=0.5 +ry=1.6 +rz=-2.8 +s=2.1 "
+ "+convention=position_vector +step +inv +proj=cart "
+ "+ellps=evrst30 +step +proj=pop +v_3 +step +proj=unitconvert "
+ "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1");
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_get_remarks) {
auto co = proj_create_from_database(m_ctxt, "EPSG", "8048",
PJ_CATEGORY_COORDINATE_OPERATION, false,
@@ -4456,4 +4486,34 @@ TEST_F(CApi, proj_context_set_sqlite3_vfs_name) {
proj_context_destroy(ctx);
}
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_is_equivalent_to_with_ctx) {
+ auto from_epsg = proj_create_from_database(m_ctxt, "EPSG", "7844",
+ PJ_CATEGORY_CRS, false, nullptr);
+ ObjectKeeper keeper_from_epsg(from_epsg);
+ ASSERT_NE(from_epsg, nullptr);
+
+ auto wkt = "GEOGCRS[\"GDA2020\",\n"
+ " DATUM[\"GDA2020\",\n"
+ " ELLIPSOID[\"GRS_1980\",6378137,298.257222101,\n"
+ " LENGTHUNIT[\"metre\",1]]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " ANGLEUNIT[\"Degree\",0.0174532925199433]],\n"
+ " CS[ellipsoidal,2],\n"
+ " AXIS[\"geodetic latitude (Lat)\",north,\n"
+ " ORDER[1],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
+ " AXIS[\"geodetic longitude (Lon)\",east,\n"
+ " ORDER[2],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]]]";
+ auto from_wkt =
+ proj_create_from_wkt(m_ctxt, wkt, nullptr, nullptr, nullptr);
+ ObjectKeeper keeper_from_wkt(from_wkt);
+ EXPECT_NE(from_wkt, nullptr);
+
+ EXPECT_TRUE(proj_is_equivalent_to_with_ctx(m_ctxt, from_epsg, from_wkt,
+ PJ_COMP_EQUIVALENT));
+}
+
} // namespace
diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp
index 427fd741..e6189a97 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -57,7 +57,8 @@ namespace {
struct UnrelatedObject : public IComparable {
UnrelatedObject() = default;
- bool _isEquivalentTo(const IComparable *, Criterion) const override {
+ bool _isEquivalentTo(const IComparable *, Criterion,
+ const DatabaseContextPtr &) const override {
assert(false);
return false;
}
@@ -755,7 +756,9 @@ TEST(crs, EPSG_27561_projected_with_geodetic_in_grad_as_PROJ_string_and_WKT1) {
nn_crs->DerivedCRS::isEquivalentTo(createUnrelatedObject().get()));
auto wkt1 = crs->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL,
+ DatabaseContext::create())
+ .get());
EXPECT_EQ(
wkt1,
"PROJCS[\"NTF (Paris) / Lambert Nord France\",\n"
@@ -856,7 +859,9 @@ TEST(crs, EPSG_2222_projected_unit_foot_as_PROJ_string_and_WKT1) {
"+x_0=213360 +y_0=0 +datum=NAD83 +units=ft +no_defs +type=crs");
auto wkt1 = crs->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL,
+ DatabaseContext::create())
+ .get());
EXPECT_EQ(wkt1,
"PROJCS[\"NAD83 / Arizona East (ft)\",\n"
" GEOGCS[\"NAD83\",\n"
@@ -903,11 +908,13 @@ TEST(crs, projected_with_parameter_unit_different_than_cs_unit_as_WKT1) {
ASSERT_TRUE(crs != nullptr);
auto wkt1 = crs->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL,
+ DatabaseContext::create())
+ .get());
EXPECT_EQ(wkt1,
"PROJCS[\"unknown\",\n"
" GEOGCS[\"unknown\",\n"
- " DATUM[\"Unknown_based_on_GRS80_ellipsoid\",\n"
+ " DATUM[\"Unknown based on GRS80 ellipsoid\",\n"
" SPHEROID[\"GRS 1980\",6378137,298.257222101]],\n"
" PRIMEM[\"Greenwich\",0],\n"
" UNIT[\"degree\",0.0174532925199433,\n"
@@ -943,6 +950,16 @@ TEST(crs, EPSG_32661_projected_north_pole_north_east) {
ASSERT_TRUE(op != nullptr);
EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
proj_string);
+
+ auto opNormalized = op->normalizeForVisualization();
+ auto proj_string_normalized =
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step "
+ "+proj=stere +lat_0=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 "
+ "+ellps=WGS84";
+ EXPECT_EQ(
+ opNormalized->exportToPROJString(PROJStringFormatter::create().get()),
+ proj_string_normalized);
}
// ---------------------------------------------------------------------------
@@ -964,6 +981,16 @@ TEST(crs, EPSG_5041_projected_north_pole_east_north) {
ASSERT_TRUE(op != nullptr);
EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
proj_string);
+
+ auto opNormalized = op->normalizeForVisualization();
+ auto proj_string_normalized =
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step "
+ "+proj=stere +lat_0=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 "
+ "+ellps=WGS84";
+ EXPECT_EQ(
+ opNormalized->exportToPROJString(PROJStringFormatter::create().get()),
+ proj_string_normalized);
}
// ---------------------------------------------------------------------------
@@ -985,6 +1012,16 @@ TEST(crs, EPSG_32761_projected_south_pole_north_east) {
ASSERT_TRUE(op != nullptr);
EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
proj_string);
+
+ auto opNormalized = op->normalizeForVisualization();
+ auto proj_string_normalized =
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step "
+ "+proj=stere +lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 "
+ "+ellps=WGS84";
+ EXPECT_EQ(
+ opNormalized->exportToPROJString(PROJStringFormatter::create().get()),
+ proj_string_normalized);
}
// ---------------------------------------------------------------------------
@@ -1006,6 +1043,16 @@ TEST(crs, EPSG_5042_projected_south_pole_east_north) {
ASSERT_TRUE(op != nullptr);
EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()),
proj_string);
+
+ auto opNormalized = op->normalizeForVisualization();
+ auto proj_string_normalized =
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step "
+ "+proj=stere +lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 "
+ "+ellps=WGS84";
+ EXPECT_EQ(
+ opNormalized->exportToPROJString(PROJStringFormatter::create().get()),
+ proj_string_normalized);
}
// ---------------------------------------------------------------------------
@@ -1511,6 +1558,75 @@ TEST(crs, geodeticcrs_identify_db) {
EXPECT_EQ(res.front().first->identifiers()[0]->code(), "4326");
EXPECT_EQ(res.front().second, 70);
}
+
+ {
+ // Identify by code, but datum name is an alias of the official one
+ auto wkt = "GEOGCRS[\"GDA2020\",\n"
+ " DATUM[\"GDA2020\",\n"
+ " ELLIPSOID[\"GRS_1980\",6378137,298.257222101,\n"
+ " LENGTHUNIT[\"metre\",1]]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " ANGLEUNIT[\"Degree\",0.0174532925199433]],\n"
+ " CS[ellipsoidal,2],\n"
+ " AXIS[\"geodetic latitude (Lat)\",north,\n"
+ " ORDER[1],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
+ " AXIS[\"geodetic longitude (Lon)\",east,\n"
+ " ORDER[2],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
+ " ID[\"EPSG\",7844]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto allFactory = AuthorityFactory::create(dbContext, std::string());
+ auto res = crs->identify(allFactory);
+ ASSERT_EQ(res.size(), 1U);
+ ASSERT_TRUE(!res.front().first->identifiers().empty());
+ EXPECT_EQ(*res.front().first->identifiers()[0]->codeSpace(), "EPSG");
+ EXPECT_EQ(res.front().first->identifiers()[0]->code(), "7844");
+ EXPECT_EQ(res.front().second, 100);
+
+ EXPECT_TRUE(crs->_isEquivalentTo(res.front().first.get(),
+ IComparable::Criterion::EQUIVALENT,
+ dbContext));
+ EXPECT_TRUE(res.front().first->_isEquivalentTo(
+ crs.get(), IComparable::Criterion::EQUIVALENT, dbContext));
+ }
+
+ {
+ // Identify by name, but datum name is an alias of the official one
+ auto wkt = "GEOGCRS[\"GDA2020\",\n"
+ " DATUM[\"GDA2020\",\n"
+ " ELLIPSOID[\"GRS_1980\",6378137,298.257222101,\n"
+ " LENGTHUNIT[\"metre\",1]]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " ANGLEUNIT[\"Degree\",0.0174532925199433]],\n"
+ " CS[ellipsoidal,2],\n"
+ " AXIS[\"geodetic latitude (Lat)\",north,\n"
+ " ORDER[1],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
+ " AXIS[\"geodetic longitude (Lon)\",east,\n"
+ " ORDER[2],\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto allFactory = AuthorityFactory::create(dbContext, std::string());
+ auto res = crs->identify(allFactory);
+ ASSERT_EQ(res.size(), 1U);
+ ASSERT_TRUE(!res.front().first->identifiers().empty());
+ EXPECT_EQ(*res.front().first->identifiers()[0]->codeSpace(), "EPSG");
+ EXPECT_EQ(res.front().first->identifiers()[0]->code(), "7844");
+ EXPECT_EQ(res.front().second, 100);
+
+ EXPECT_TRUE(crs->_isEquivalentTo(res.front().first.get(),
+ IComparable::Criterion::EQUIVALENT,
+ dbContext));
+ EXPECT_TRUE(res.front().first->_isEquivalentTo(
+ crs.get(), IComparable::Criterion::EQUIVALENT, dbContext));
+ }
}
// ---------------------------------------------------------------------------
@@ -2281,6 +2397,38 @@ TEST(crs, projectedCRS_identify_db) {
// ---------------------------------------------------------------------------
+TEST(crs, projectedCRS_identify_wrong_auth_name_case) {
+ auto dbContext = DatabaseContext::create();
+ auto factoryAnonymous = AuthorityFactory::create(dbContext, std::string());
+ auto obj =
+ WKTParser()
+ .attachDatabaseContext(dbContext)
+ .setStrict(false)
+ .createFromWKT(
+ "PROJCS[\"World_Cylindrical_Equal_Area\","
+ "GEOGCS[\"GCS_WGS_1984\","
+ "DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\","
+ "6378137.0,298.257223563]],"
+ "PRIMEM[\"Greenwich\",0.0],"
+ "UNIT[\"Degree\",0.0174532925199433]],"
+ "PROJECTION[\"Cylindrical_Equal_Area\"],"
+ "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],"
+ "AUTHORITY[\"Esri\",54034]]"); // should be ESRI all caps
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryAnonymous);
+ ASSERT_EQ(res.size(), 1U);
+ const auto &ids = res.front().first->identifiers();
+ ASSERT_EQ(ids.size(), 1U);
+ EXPECT_EQ(*(ids.front()->codeSpace()), "ESRI");
+ EXPECT_EQ(ids.front()->code(), "54034");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(crs, mercator_1SP_as_WKT1_ESRI) {
auto obj = PROJStringParser().createFromPROJString(
@@ -3351,6 +3499,17 @@ TEST(crs, compoundCRS_identify_db) {
EXPECT_EQ(res.front().first->getEPSGCode(), 8769);
EXPECT_EQ(res.front().second, 70);
}
+ {
+ auto obj = PROJStringParser().createFromPROJString(
+ "+proj=tmerc +lat_0=0 +lon_0=72.05 +k=1 +x_0=3500000 "
+ "+y_0=-5811057.63 +ellps=krass "
+ "+towgs84=23.57,-140.95,-79.8,0,-0.35,-0.79,-0.22 "
+ "+geoidgrids=egm08_25.gtx +units=m +no_defs +type=crs");
+ auto crs = nn_dynamic_pointer_cast<CompoundCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ // Just check we don't get an exception
+ crs->identify(factory);
+ }
}
// ---------------------------------------------------------------------------
@@ -3753,6 +3912,21 @@ TEST(crs, boundCRS_identify_db) {
WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
EXPECT_TRUE(wkt.find("32122") != std::string::npos) << wkt;
}
+
+ {
+ // Identify from a PROJ string with +towgs84
+ auto obj = PROJStringParser().createFromPROJString(
+ "+proj=utm +zone=48 +a=6377276.345 +b=6356075.41314024 "
+ "+towgs84=198,881,317,0,0,0,0 +units=m +no_defs +type=crs");
+ auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto res = crs->identify(factoryEPSG);
+ ASSERT_EQ(res.size(), 1U);
+ auto boundCRS = dynamic_cast<const BoundCRS *>(res.front().first.get());
+ ASSERT_TRUE(boundCRS != nullptr);
+ EXPECT_EQ(boundCRS->baseCRS()->getEPSGCode(), 3148);
+ EXPECT_EQ(res.front().second, 70);
+ }
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp
index 8a5d67cf..adf0ae4b 100644
--- a/test/unit/test_datum.cpp
+++ b/test/unit/test_datum.cpp
@@ -44,7 +44,8 @@ namespace {
struct UnrelatedObject : public IComparable {
UnrelatedObject() = default;
- bool _isEquivalentTo(const IComparable *, Criterion) const override {
+ bool _isEquivalentTo(const IComparable *, Criterion,
+ const DatabaseContextPtr &) const override {
assert(false);
return false;
}
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index e342dad9..6a88e2b6 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -2737,8 +2737,8 @@ TEST(factory, createObjectsFromName) {
EXPECT_EQ(factory->createObjectsFromName("").size(), 0U);
- // ellipsoid + 3 geodeticCRS
- EXPECT_EQ(factory->createObjectsFromName("WGS 84", {}, false).size(), 4U);
+ // ellipsoid + datum + 3 geodeticCRS
+ EXPECT_EQ(factory->createObjectsFromName("WGS 84", {}, false).size(), 5U);
EXPECT_EQ(factory->createObjectsFromName("WGS 84", {}, true, 10).size(),
10U);
@@ -2753,7 +2753,9 @@ TEST(factory, createObjectsFromName) {
auto res = factoryEPSG->createObjectsFromName(
"WGS84", {AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS}, true);
EXPECT_EQ(res.size(),
- 8U); // EPSG:4326 and EPSG:4030 and the 6 WGS84 realizations
+ 9U); // EPSG:4326 and EPSG:4030 and the 6 WGS84 realizations
+ // and EPSG:7881 'Tritan St. Helena'' whose alias is
+ // 'WGS 84 Tritan St. Helena'
if (!res.empty()) {
EXPECT_EQ(res.front()->getEPSGCode(), 4326);
}
@@ -2876,7 +2878,7 @@ TEST(factory, getMetadata) {
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.3");
+ EXPECT_EQ(std::string(IGNF_VERSION), "3.1.0");
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 38dfc2b4..fd38847c 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -493,18 +493,14 @@ TEST(wkt_parse, wkt1_geographic_old_datum_name_from_EPSG_code) {
// ---------------------------------------------------------------------------
-TEST(wkt_parse, wkt1_geographic_old_datum_name_witout_EPSG_code) {
+TEST(wkt_parse, wkt1_geographic_old_datum_name_without_EPSG_code) {
auto wkt =
"GEOGCS[\"S-JTSK (Ferro)\",\n"
" "
"DATUM[\"System_Jednotne_Trigonometricke_Site_Katastralni_Ferro\",\n"
- " SPHEROID[\"Bessel 1841\",6377397.155,299.1528128,\n"
- " AUTHORITY[\"EPSG\",\"7004\"]]],\n"
- " PRIMEM[\"Ferro\",-17.66666666666667,\n"
- " AUTHORITY[\"EPSG\",\"8909\"]],\n"
- " UNIT[\"degree\",0.0174532925199433,\n"
- " AUTHORITY[\"EPSG\",\"9122\"]],\n"
- " AUTHORITY[\"EPSG\",\"4818\"]]";
+ " SPHEROID[\"Bessel 1841\",6377397.155,299.1528128]],\n"
+ " PRIMEM[\"Ferro\",-17.66666666666667],\n"
+ " UNIT[\"degree\",0.0174532925199433]]";
auto obj = WKTParser()
.attachDatabaseContext(DatabaseContext::create())
.createFromWKT(wkt);
@@ -5577,6 +5573,17 @@ TEST(wkt_parse, invalid_GEOCCS) {
"NORTH],AXIS[\"longitude\",EAST]]"),
ParsingException);
+ // ellipsoidal CS is invalid in a GEOCCS
+ EXPECT_THROW(WKTParser().createFromWKT(
+ "GEOCCS[\"WGS 84\",DATUM[\"World Geodetic System 1984\","
+ "ELLIPSOID[\"WGS 84\",6378274,298.257223564,"
+ "LENGTHUNIT[\"metre\",1]]],"
+ "CS[ellipsoidal,2],AXIS[\"geodetic latitude (Lat)\",north,"
+ "ANGLEUNIT[\"degree\",0.0174532925199433]],"
+ "AXIS[\"geodetic longitude (Lon)\",east,"
+ "ANGLEUNIT[\"degree\",0.0174532925199433]]]"),
+ ParsingException);
+
// 3 axis required
EXPECT_THROW(WKTParser().createFromWKT(
"GEOCCS[\"x\",DATUM[\"x\",SPHEROID[\"x\",1,0.5]],PRIMEM["
@@ -6856,6 +6863,30 @@ TEST(io, projstringformatter_optim_hgridshift_vgridshift_hgridshift_inv) {
"+step +proj=pop +v_1 +v_2");
}
+ // Test omit_fwd->omit_inv when inversing the pipeline
+ {
+ auto fmt = PROJStringFormatter::create();
+ fmt->startInversion();
+ fmt->ingestPROJString("+proj=hgridshift +grids=foo +omit_fwd");
+ fmt->stopInversion();
+
+ EXPECT_EQ(fmt->toString(),
+ "+proj=pipeline "
+ "+step +inv +proj=hgridshift +grids=foo +omit_inv");
+ }
+
+ // Test omit_inv->omit_fwd when inversing the pipeline
+ {
+ auto fmt = PROJStringFormatter::create();
+ fmt->startInversion();
+ fmt->ingestPROJString("+proj=hgridshift +grids=foo +omit_inv");
+ fmt->stopInversion();
+
+ EXPECT_EQ(fmt->toString(),
+ "+proj=pipeline "
+ "+step +inv +proj=hgridshift +grids=foo +omit_fwd");
+ }
+
// Variant with first hgridshift inverted, and second forward
{
auto fmt = PROJStringFormatter::create();
@@ -9324,6 +9355,20 @@ TEST(io, createFromUserInput) {
// ---------------------------------------------------------------------------
+TEST(io, createFromUserInput_hack_EPSG_102100) {
+ auto dbContext = DatabaseContext::create();
+ auto obj = createFromUserInput("EPSG:102100", dbContext);
+ auto crs = nn_dynamic_pointer_cast<CRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ const auto &ids = crs->identifiers();
+ ASSERT_EQ(ids.size(), 1U);
+ // we do not lie on the real authority
+ EXPECT_EQ(*ids[0]->codeSpace(), "ESRI");
+ EXPECT_EQ(ids[0]->code(), "102100");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(io, guessDialect) {
EXPECT_EQ(WKTParser().guessDialect("LOCAL_CS[\"foo\"]"),
WKTParser::WKTGuessedDialect::WKT1_GDAL);
@@ -11866,3 +11911,40 @@ TEST(json_import, multiple_ids) {
EXPECT_EQ(ellps->exportToJSON(&(JSONFormatter::create()->setSchema("foo"))),
json);
}
+
+// ---------------------------------------------------------------------------
+
+TEST(json_export, coordinate_system_id) {
+ auto json = "{\n"
+ " \"$schema\": \"foo\",\n"
+ " \"type\": \"CoordinateSystem\",\n"
+ " \"subtype\": \"ellipsoidal\",\n"
+ " \"axis\": [\n"
+ " {\n"
+ " \"name\": \"Geodetic latitude\",\n"
+ " \"abbreviation\": \"Lat\",\n"
+ " \"direction\": \"north\",\n"
+ " \"unit\": \"degree\"\n"
+ " },\n"
+ " {\n"
+ " \"name\": \"Geodetic longitude\",\n"
+ " \"abbreviation\": \"Lon\",\n"
+ " \"direction\": \"east\",\n"
+ " \"unit\": \"degree\"\n"
+ " }\n"
+ " ],\n"
+ " \"id\": {\n"
+ " \"authority\": \"EPSG\",\n"
+ " \"code\": 6422\n"
+ " }\n"
+ "}";
+
+ auto dbContext = DatabaseContext::create();
+ auto obj = createFromUserInput("EPSG:4326", dbContext);
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto cs = crs->coordinateSystem();
+ ASSERT_TRUE(cs != nullptr);
+ EXPECT_EQ(cs->exportToJSON(&(JSONFormatter::create()->setSchema("foo"))),
+ json);
+}
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index 753878c5..8ee5814b 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -65,7 +65,8 @@ namespace {
struct UnrelatedObject : public IComparable {
UnrelatedObject() = default;
- bool _isEquivalentTo(const IComparable *, Criterion) const override {
+ bool _isEquivalentTo(const IComparable *, Criterion,
+ const DatabaseContextPtr &) const override {
assert(false);
return false;
}
@@ -3257,7 +3258,9 @@ TEST(operation, webmerc_import_from_WKT2_EPSG_3785_deprecated) {
EXPECT_EQ(
crs->exportToWKT(
- WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()),
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL,
+ DatabaseContext::create())
+ .get()),
"PROJCS[\"Popular Visualisation CRS / Mercator\",\n"
" GEOGCS[\"Popular Visualisation CRS\",\n"
" DATUM[\"Popular_Visualisation_Datum\",\n"
@@ -4628,6 +4631,33 @@ TEST(operation, geogCRS_to_geogCRS_context_WGS84_G1674_to_WGS84_G1762) {
// ---------------------------------------------------------------------------
+TEST(operation, geogCRS_to_geogCRS_context_EPSG_4240_Indian1975_to_EPSG_4326) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0);
+ ctxt->setSpatialCriterion(
+ CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
+
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ authFactory->createCoordinateReferenceSystem("4240"), // Indian 1975
+ authFactory->createCoordinateReferenceSystem("4326"), ctxt);
+ ASSERT_EQ(list.size(), 3U);
+
+ // Indian 1975 to WGS 84 (4), 3.0 m, Thailand - onshore
+ EXPECT_EQ(list[0]->getEPSGCode(), 1812);
+
+ // The following is the one we want to see. It has a lesser accuracy than
+ // the above one and the same bbox, but the name of its area of use is
+ // slightly different
+ // Indian 1975 to WGS 84 (2), 5.0 m, Thailand - onshore and Gulf of Thailand
+ EXPECT_EQ(list[1]->getEPSGCode(), 1304);
+
+ // Indian 1975 to WGS 84 (3), 1.0 m, Thailand - Bongkot field
+ EXPECT_EQ(list[2]->getEPSGCode(), 1537);
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, vertCRS_to_geogCRS_context) {
auto authFactory =
AuthorityFactory::create(DatabaseContext::create(), "EPSG");
@@ -4687,6 +4717,19 @@ TEST(operation, vertCRS_to_geogCRS_context) {
list[0]->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=affine +s33=-0.304800609601219");
}
+ {
+ auto ctxt =
+ CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ // NZVD2016 height
+ authFactory->createCoordinateReferenceSystem("7839"),
+ // NZGD2000
+ authFactory->createCoordinateReferenceSystem("4959"), ctxt);
+ ASSERT_EQ(list.size(), 1U);
+ EXPECT_EQ(
+ list[0]->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=vgridshift +grids=nzgeoid2016.gtx +multiplier=1");
+ }
}
// ---------------------------------------------------------------------------
@@ -5576,6 +5619,69 @@ TEST(operation, projCRS_no_id_to_geogCRS_context) {
// ---------------------------------------------------------------------------
+TEST(operation, projCRS_3D_to_geogCRS_3D_context) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ ctxt->setSpatialCriterion(
+ CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
+ auto wkt = "PROJCRS[\"NAD83(HARN) / Oregon GIC Lambert (ft)\",\n"
+ " BASEGEOGCRS[\"NAD83(HARN)\",\n"
+ " DATUM[\"NAD83 (High Accuracy Reference Network)\",\n"
+ " ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n"
+ " LENGTHUNIT[\"metre\",1]]],\n"
+ " PRIMEM[\"Greenwich\",0,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433]],\n"
+ " ID[\"EPSG\",4957]],\n"
+ " CONVERSION[\"unnamed\",\n"
+ " METHOD[\"Lambert Conic Conformal (2SP)\",\n"
+ " ID[\"EPSG\",9802]],\n"
+ " PARAMETER[\"Latitude of false origin\",41.75,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8821]],\n"
+ " PARAMETER[\"Longitude of false origin\",-120.5,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8822]],\n"
+ " PARAMETER[\"Latitude of 1st standard parallel\",43,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8823]],\n"
+ " PARAMETER[\"Latitude of 2nd standard parallel\",45.5,\n"
+ " ANGLEUNIT[\"degree\",0.0174532925199433],\n"
+ " ID[\"EPSG\",8824]],\n"
+ " PARAMETER[\"Easting at false origin\",1312335.958,\n"
+ " LENGTHUNIT[\"foot\",0.3048],\n"
+ " ID[\"EPSG\",8826]],\n"
+ " PARAMETER[\"Northing at false origin\",0,\n"
+ " LENGTHUNIT[\"foot\",0.3048],\n"
+ " ID[\"EPSG\",8827]]],\n"
+ " CS[Cartesian,3],\n"
+ " AXIS[\"easting\",east,\n"
+ " ORDER[1],\n"
+ " LENGTHUNIT[\"foot\",0.3048]],\n"
+ " AXIS[\"northing\",north,\n"
+ " ORDER[2],\n"
+ " LENGTHUNIT[\"foot\",0.3048]],\n"
+ " AXIS[\"ellipsoidal height (h)\",up,\n"
+ " ORDER[3],\n"
+ " LENGTHUNIT[\"foot\",0.3048]]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto src = NN_CHECK_ASSERT(nn_dynamic_pointer_cast<CRS>(obj));
+ auto dst = authFactory->createCoordinateReferenceSystem(
+ "4957"); // NAD83(HARN) (3D)
+ auto list =
+ CoordinateOperationFactory::create()->createOperations(src, dst, ctxt);
+ ASSERT_EQ(list.size(), 1U);
+ EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ // Check that z ft->m conversion is done (and just once)
+ "+step +proj=unitconvert +xy_in=ft +z_in=ft +xy_out=m +z_out=m "
+ "+step +inv +proj=lcc +lat_0=41.75 +lon_0=-120.5 +lat_1=43 "
+ "+lat_2=45.5 +x_0=399999.9999984 +y_0=0 +ellps=GRS80 "
+ "+step +proj=unitconvert +xy_in=rad +z_in=m +xy_out=deg +z_out=m "
+ "+step +proj=axisswap +order=2,1");
+}
+// ---------------------------------------------------------------------------
+
TEST(operation, projCRS_3D_to_projCRS_2D_context) {
auto authFactory =
AuthorityFactory::create(DatabaseContext::create(), "EPSG");
@@ -6509,6 +6615,18 @@ TEST(operation, transformation_VERTCON_to_PROJ_string) {
PROJStringFormatter::create().get()),
"+proj=vgridshift +grids=bla.gtx +multiplier=0.001");
}
+// ---------------------------------------------------------------------------
+
+TEST(operation, transformation_NZLVD_to_PROJ_string) {
+ auto dbContext = DatabaseContext::create();
+ auto factory = AuthorityFactory::create(dbContext, "EPSG");
+ auto op = factory->createCoordinateOperation("7860", false);
+ EXPECT_EQ(op->exportToPROJString(
+ PROJStringFormatter::create(
+ PROJStringFormatter::Convention::PROJ_5, dbContext)
+ .get()),
+ "+proj=vgridshift +grids=auckht1946-nzvd2016.gtx +multiplier=1");
+}
// ---------------------------------------------------------------------------
@@ -7134,6 +7252,22 @@ TEST(operation, vertCRS_to_vertCRS_context) {
// ---------------------------------------------------------------------------
+TEST(operation, vertCRS_to_vertCRS_New_Zealand_context) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ // NZVD2016 height
+ authFactory->createCoordinateReferenceSystem("7839"),
+ // Auckland 1946 height
+ authFactory->createCoordinateReferenceSystem("5759"), ctxt);
+ ASSERT_EQ(list.size(), 1U);
+ EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=vgridshift +grids=auckht1946-nzvd2016.gtx +multiplier=1");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, compoundCRS_to_geogCRS_3D) {
auto compoundcrs_ft_obj = PROJStringParser().createFromPROJString(