aboutsummaryrefslogtreecommitdiff
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/CMakeLists.txt13
-rw-r--r--test/unit/Makefile.am16
-rw-r--r--test/unit/test_c_api.cpp227
-rw-r--r--test/unit/test_datum.cpp12
-rw-r--r--test/unit/test_factory.cpp120
-rw-r--r--test/unit/test_io.cpp93
-rw-r--r--test/unit/test_operation.cpp16
7 files changed, 461 insertions, 36 deletions
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index a157f630..86e3484a 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -1,5 +1,16 @@
# CMake configuration for PROJ unit tests
+option(USE_EXTERNAL_GTEST "Compile against external GTest" OFF)
+
+if (USE_EXTERNAL_GTEST)
+
+message(STATUS "Using external GTest")
+find_package(GTest 1.8.0)
+
+else (USE_EXTERNAL_GTEST)
+
+message(STATUS "Using internal GTest")
+
# FIXME: Deal with our old-school CMakeLists.txt behaving badly
set(_save_c_flags "${CMAKE_C_FLAGS}")
set(_save_cxx_flags "${CMAKE_CXX_FLAGS}")
@@ -47,6 +58,8 @@ set(CMAKE_CXX_FLAGS "${_save_cxx_flags}")
unset(_save_c_flags)
unset(_save_cxx_flags)
+endif(USE_EXTERNAL_GTEST)
+
#
# Build PROJ unit tests
#
diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am
index 34624b0d..210bdc90 100644
--- a/test/unit/Makefile.am
+++ b/test/unit/Makefile.am
@@ -4,7 +4,7 @@ EXTRA_DIST = CMakeLists.txt
noinst_HEADERS = gtest_include.h
-AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_srcdir)/test -I$(top_srcdir)/test/googletest/include @SQLITE3_FLAGS@
+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
@@ -19,43 +19,43 @@ noinst_PROGRAMS += gie_self_tests
noinst_PROGRAMS += include_proj_h_from_c
pj_transform_test_SOURCES = pj_transform_test.cpp main.cpp
-pj_transform_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
+pj_transform_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
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
+pj_phi2_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
pj_phi2_test-check: pj_phi2_test
./pj_phi2_test
proj_errno_string_test_SOURCES = proj_errno_string_test.cpp main.cpp
-proj_errno_string_test_LDADD= ../../src/libproj.la ../../test/googletest/libgtest.la
+proj_errno_string_test_LDADD= ../../src/libproj.la @GTEST_LIBS@
proj_errno_string_test-check: proj_errno_string_test
./proj_errno_string_test
proj_angular_io_test_SOURCES = proj_angular_io_test.cpp main.cpp
-proj_angular_io_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
+proj_angular_io_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
proj_angular_io_test-check: proj_angular_io_test
./proj_angular_io_test
proj_context_test_SOURCES = proj_context_test.cpp main.cpp
-proj_context_test_LDADD = ../../src/libproj.la ../../test/googletest/libgtest.la
+proj_context_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
proj_context_test-check: proj_context_test
./proj_context_test
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_LDADD = ../../src/libproj.la @GTEST_LIBS@ @SQLITE3_LIBS@
test_cpp_api-check: test_cpp_api
PROJ_LIB=$(PROJ_LIB) ./test_cpp_api
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_LDADD = ../../src/libproj.la @GTEST_LIBS@ @SQLITE3_LIBS@
gie_self_tests-check: gie_self_tests
PROJ_LIB=$(PROJ_LIB) ./gie_self_tests
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index ff29185f..d535e412 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -507,36 +507,21 @@ TEST_F(CApi, proj_as_proj_string_incompatible_WKT1) {
// ---------------------------------------------------------------------------
-TEST_F(CApi, proj_as_proj_string_etmerc_option_yes) {
+TEST_F(CApi, proj_as_proj_string_approx_tmerc_option_yes) {
auto obj = proj_create(m_ctxt, "+proj=tmerc +type=crs");
ObjectKeeper keeper(obj);
ASSERT_NE(obj, nullptr);
- const char *options[] = {"USE_ETMERC=YES", nullptr};
+ const char *options[] = {"USE_APPROX_TMERC=YES", nullptr};
auto str = proj_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 "
+ std::string("+proj=tmerc +approx +lat_0=0 +lon_0=0 +k=1 +x_0=0 "
"+y_0=0 +datum=WGS84 +units=m +no_defs +type=crs"));
}
// ---------------------------------------------------------------------------
-TEST_F(CApi, proj_as_proj_string_etmerc_option_no) {
- auto obj = proj_create(m_ctxt, "+proj=utm +zone=31 +type=crs");
- ObjectKeeper keeper(obj);
- ASSERT_NE(obj, nullptr);
-
- const char *options[] = {"USE_ETMERC=NO", nullptr};
- auto str = proj_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 "
- "+no_defs +type=crs"));
-}
-
-// ---------------------------------------------------------------------------
-
TEST_F(CApi, proj_crs_create_bound_crs_to_WGS84) {
auto crs = proj_create_from_database(m_ctxt, "EPSG", "3844",
PJ_CATEGORY_CRS, false, nullptr);
@@ -3022,4 +3007,210 @@ TEST_F(CApi, proj_create_cartesian_2D_cs) {
}
}
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_get_crs_info_list_from_database) {
+ { proj_crs_info_list_destroy(nullptr); }
+
+ { proj_get_crs_list_parameters_destroy(nullptr); }
+
+ // All null parameters
+ {
+ auto list = proj_get_crs_info_list_from_database(nullptr, nullptr,
+ nullptr, nullptr);
+ ASSERT_NE(list, nullptr);
+ ASSERT_NE(list[0], nullptr);
+ EXPECT_NE(list[0]->auth_name, nullptr);
+ EXPECT_NE(list[0]->code, nullptr);
+ EXPECT_NE(list[0]->name, nullptr);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Default parameters
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ proj_get_crs_list_parameters_destroy(params);
+ ASSERT_NE(list, nullptr);
+ EXPECT_GT(result_count, 1);
+ EXPECT_EQ(list[result_count], nullptr);
+ bool found4326 = false;
+ bool found4978 = false;
+ bool found4979 = false;
+ bool found32631 = false;
+ bool found3855 = false;
+ bool found3901 = false;
+ for (int i = 0; i < result_count; i++) {
+ auto code = std::string(list[i]->code);
+ if (code == "4326") {
+ found4326 = true;
+ EXPECT_EQ(std::string(list[i]->auth_name), "EPSG");
+ EXPECT_EQ(std::string(list[i]->name), "WGS 84");
+ EXPECT_EQ(list[i]->type, PJ_TYPE_GEOGRAPHIC_2D_CRS);
+ EXPECT_EQ(list[i]->deprecated, 0);
+ EXPECT_EQ(list[i]->bbox_valid, 1);
+ EXPECT_EQ(list[i]->west_lon_degree, -180.0);
+ EXPECT_EQ(list[i]->south_lat_degree, -90.0);
+ EXPECT_EQ(list[i]->east_lon_degree, 180.0);
+ EXPECT_EQ(list[i]->north_lat_degree, 90.0);
+ EXPECT_EQ(std::string(list[i]->area_name), "World");
+ EXPECT_EQ(list[i]->projection_method_name, nullptr);
+ } else if (code == "4978") {
+ found4978 = true;
+ EXPECT_EQ(list[i]->type, PJ_TYPE_GEOCENTRIC_CRS);
+ } else if (code == "4979") {
+ found4979 = true;
+ EXPECT_EQ(list[i]->type, PJ_TYPE_GEOGRAPHIC_3D_CRS);
+ } else if (code == "32631") {
+ found32631 = true;
+ EXPECT_EQ(list[i]->type, PJ_TYPE_PROJECTED_CRS);
+ EXPECT_EQ(std::string(list[i]->projection_method_name),
+ "Transverse Mercator");
+ } else if (code == "3855") {
+ found3855 = true;
+ EXPECT_EQ(list[i]->type, PJ_TYPE_VERTICAL_CRS);
+ } else if (code == "3901") {
+ found3901 = true;
+ EXPECT_EQ(list[i]->type, PJ_TYPE_COMPOUND_CRS);
+ }
+ EXPECT_EQ(list[i]->deprecated, 0);
+ }
+ EXPECT_TRUE(found4326);
+ EXPECT_TRUE(found4978);
+ EXPECT_TRUE(found4979);
+ EXPECT_TRUE(found32631);
+ EXPECT_TRUE(found3855);
+ EXPECT_TRUE(found3901);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Filter on only geodetic crs
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ params->typesCount = 1;
+ auto type = PJ_TYPE_GEODETIC_CRS;
+ params->types = &type;
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ bool foundGeog2D = false;
+ bool foundGeog3D = false;
+ bool foundGeocentric = false;
+ for (int i = 0; i < result_count; i++) {
+ foundGeog2D |= list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS;
+ foundGeog3D |= list[i]->type == PJ_TYPE_GEOGRAPHIC_3D_CRS;
+ foundGeocentric |= list[i]->type == PJ_TYPE_GEOCENTRIC_CRS;
+ EXPECT_TRUE(list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS ||
+ list[i]->type == PJ_TYPE_GEOGRAPHIC_3D_CRS ||
+ list[i]->type == PJ_TYPE_GEOCENTRIC_CRS);
+ }
+ EXPECT_TRUE(foundGeog2D);
+ EXPECT_TRUE(foundGeog3D);
+ EXPECT_TRUE(foundGeocentric);
+ proj_get_crs_list_parameters_destroy(params);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Filter on only geographic crs
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ params->typesCount = 1;
+ auto type = PJ_TYPE_GEOGRAPHIC_CRS;
+ params->types = &type;
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ bool foundGeog2D = false;
+ bool foundGeog3D = false;
+ for (int i = 0; i < result_count; i++) {
+ foundGeog2D |= list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS;
+ foundGeog3D |= list[i]->type == PJ_TYPE_GEOGRAPHIC_3D_CRS;
+ EXPECT_TRUE(list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS ||
+ list[i]->type == PJ_TYPE_GEOGRAPHIC_3D_CRS);
+ }
+ EXPECT_TRUE(foundGeog2D);
+ EXPECT_TRUE(foundGeog3D);
+ proj_get_crs_list_parameters_destroy(params);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Filter on only geographic 2D crs and projected CRS
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ params->typesCount = 2;
+ const PJ_TYPE types[] = {PJ_TYPE_GEOGRAPHIC_2D_CRS,
+ PJ_TYPE_PROJECTED_CRS};
+ params->types = types;
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ bool foundGeog2D = false;
+ bool foundProjected = false;
+ for (int i = 0; i < result_count; i++) {
+ foundGeog2D |= list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS;
+ foundProjected |= list[i]->type == PJ_TYPE_PROJECTED_CRS;
+ EXPECT_TRUE(list[i]->type == PJ_TYPE_GEOGRAPHIC_2D_CRS ||
+ list[i]->type == PJ_TYPE_PROJECTED_CRS);
+ }
+ EXPECT_TRUE(foundGeog2D);
+ EXPECT_TRUE(foundProjected);
+ proj_get_crs_list_parameters_destroy(params);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Filter on bbox (inclusion)
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ params->bbox_valid = 1;
+ params->west_lon_degree = 2;
+ params->south_lat_degree = 49;
+ params->east_lon_degree = 2.1;
+ params->north_lat_degree = 49.1;
+ params->typesCount = 1;
+ auto type = PJ_TYPE_PROJECTED_CRS;
+ params->types = &type;
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ ASSERT_NE(list, nullptr);
+ EXPECT_GT(result_count, 1);
+ for (int i = 0; i < result_count; i++) {
+ EXPECT_LE(list[i]->west_lon_degree, params->west_lon_degree);
+ EXPECT_LE(list[i]->south_lat_degree, params->south_lat_degree);
+ EXPECT_GE(list[i]->east_lon_degree, params->east_lon_degree);
+ EXPECT_GE(list[i]->north_lat_degree, params->north_lat_degree);
+ }
+ proj_get_crs_list_parameters_destroy(params);
+ proj_crs_info_list_destroy(list);
+ }
+
+ // Filter on bbox (intersection)
+ {
+ int result_count = 0;
+ auto params = proj_get_crs_list_parameters_create();
+ params->bbox_valid = 1;
+ params->west_lon_degree = 2;
+ params->south_lat_degree = 49;
+ params->east_lon_degree = 2.1;
+ params->north_lat_degree = 49.1;
+ params->crs_area_of_use_contains_bbox = 0;
+ params->typesCount = 1;
+ auto type = PJ_TYPE_PROJECTED_CRS;
+ params->types = &type;
+ auto list = proj_get_crs_info_list_from_database(m_ctxt, "EPSG", params,
+ &result_count);
+ ASSERT_NE(list, nullptr);
+ EXPECT_GT(result_count, 1);
+ for (int i = 0; i < result_count; i++) {
+ EXPECT_LE(list[i]->west_lon_degree, params->east_lon_degree);
+ EXPECT_LE(list[i]->south_lat_degree, params->north_lat_degree);
+ EXPECT_GE(list[i]->east_lon_degree, params->west_lon_degree);
+ EXPECT_GE(list[i]->north_lat_degree, params->south_lat_degree);
+ }
+ proj_get_crs_list_parameters_destroy(params);
+ proj_crs_info_list_destroy(list);
+ }
+}
} // namespace
diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp
index 18cf244a..c6ccf5cf 100644
--- a/test/unit/test_datum.cpp
+++ b/test/unit/test_datum.cpp
@@ -127,6 +127,18 @@ TEST(datum, ellipsoid_from_inverse_flattening) {
// ---------------------------------------------------------------------------
+TEST(datum, ellipsoid_from_null_inverse_flattening) {
+
+ auto ellipsoid = Ellipsoid::createFlattenedSphere(
+ PropertyMap(), Length(6378137), Scale(0));
+ EXPECT_FALSE(ellipsoid->inverseFlattening().has_value());
+ EXPECT_FALSE(ellipsoid->semiMinorAxis().has_value());
+ EXPECT_FALSE(ellipsoid->semiMedianAxis().has_value());
+ EXPECT_TRUE(ellipsoid->isSphere());
+}
+
+// ---------------------------------------------------------------------------
+
TEST(datum, ellipsoid_from_semi_minor_axis) {
auto ellipsoid = Ellipsoid::createTwoAxis(PropertyMap(), Length(6378137),
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 81f745f5..ce019079 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -222,6 +222,16 @@ TEST(factory, AuthorityFactory_createExtent) {
// ---------------------------------------------------------------------------
+TEST(factory, AuthorityFactory_createExtent_no_bbox) {
+ auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto extent = factory->createExtent("1361"); // Sudan - south. Deprecated
+ EXPECT_EQ(*(extent->description()), "Sudan - south");
+ const auto &geogElts = extent->geographicElements();
+ EXPECT_TRUE(geogElts.empty());
+}
+
+// ---------------------------------------------------------------------------
+
TEST(factory, AuthorityFactory_createGeodeticDatum) {
auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG");
EXPECT_THROW(factory->createGeodeticDatum("-1"),
@@ -414,6 +424,17 @@ TEST(factory, AuthorityFactory_createGeodeticCRS_geographic2D) {
// ---------------------------------------------------------------------------
+TEST(factory, AuthorityFactory_createGeodeticCRS_geographic2D_area_no_bbox) {
+ auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto crs = factory->createGeodeticCRS("4296"); // Sudan - deprecated
+ auto domain = crs->domains()[0];
+ auto extent = domain->domainOfValidity();
+ ASSERT_TRUE(extent != nullptr);
+ EXPECT_TRUE(extent->isEquivalentTo(factory->createExtent("1361").get()));
+}
+
+// ---------------------------------------------------------------------------
+
TEST(factory, AuthorityFactory_createGeodeticCRS_geographic3D) {
auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG");
auto crs = factory->createGeodeticCRS("4979");
@@ -2789,4 +2810,103 @@ TEST(factory, listAreaOfUseFromName) {
}
}
+// ---------------------------------------------------------------------------
+
+TEST(factory, getCRSInfoList) {
+ auto ctxt = DatabaseContext::create();
+ {
+ auto factory = AuthorityFactory::create(ctxt, std::string());
+ auto list = factory->getCRSInfoList();
+ EXPECT_GT(list.size(), 1U);
+ bool foundEPSG = false;
+ bool foundIGNF = true;
+ bool found4326 = false;
+ for (const auto &info : list) {
+ foundEPSG |= info.authName == "EPSG";
+ foundIGNF |= info.authName == "IGNF";
+ if (info.authName == "EPSG" && info.code == "4326") {
+ found4326 = true;
+ }
+ }
+ EXPECT_TRUE(foundEPSG);
+ EXPECT_TRUE(foundIGNF);
+ EXPECT_TRUE(found4326);
+ }
+ {
+ auto factory = AuthorityFactory::create(ctxt, "EPSG");
+ auto list = factory->getCRSInfoList();
+ EXPECT_GT(list.size(), 1U);
+ bool found4326 = false;
+ bool found4978 = false;
+ bool found4979 = false;
+ bool found32631 = false;
+ bool found3855 = false;
+ bool found6871 = false;
+ for (const auto &info : list) {
+ EXPECT_EQ(info.authName, "EPSG");
+ if (info.code == "4326") {
+ EXPECT_EQ(info.name, "WGS 84");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS);
+ EXPECT_EQ(info.deprecated, false);
+ EXPECT_EQ(info.bbox_valid, true);
+ EXPECT_EQ(info.west_lon_degree, -180.0);
+ EXPECT_EQ(info.south_lat_degree, -90.0);
+ EXPECT_EQ(info.east_lon_degree, 180.0);
+ EXPECT_EQ(info.north_lat_degree, 90.0);
+ EXPECT_EQ(info.areaName, "World");
+ EXPECT_TRUE(info.projectionMethodName.empty());
+ found4326 = true;
+ } else if (info.code == "4296") { // Soudan - deprecated
+ EXPECT_EQ(info.bbox_valid, false);
+ EXPECT_EQ(info.west_lon_degree, 0.0);
+ EXPECT_EQ(info.south_lat_degree, 0.0);
+ EXPECT_EQ(info.east_lon_degree, 0.0);
+ EXPECT_EQ(info.north_lat_degree, 0.0);
+ } else if (info.code == "4978") {
+ EXPECT_EQ(info.name, "WGS 84");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::GEOCENTRIC_CRS);
+ found4978 = true;
+ } else if (info.code == "4979") {
+ EXPECT_EQ(info.name, "WGS 84");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS);
+ found4979 = true;
+ } else if (info.code == "32631") {
+ EXPECT_EQ(info.name, "WGS 84 / UTM zone 31N");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::PROJECTED_CRS);
+ EXPECT_EQ(info.deprecated, false);
+ EXPECT_EQ(info.bbox_valid, true);
+ EXPECT_EQ(info.west_lon_degree, 0.0);
+ EXPECT_EQ(info.south_lat_degree, 0.0);
+ EXPECT_EQ(info.east_lon_degree, 6.0);
+ EXPECT_EQ(info.north_lat_degree, 84.0);
+ EXPECT_EQ(info.areaName, "World - N hemisphere - 0\xC2\xB0"
+ "E to 6\xC2\xB0"
+ "E - by country");
+ EXPECT_EQ(info.projectionMethodName, "Transverse Mercator");
+ found32631 = true;
+ } else if (info.code == "3855") {
+ EXPECT_EQ(info.name, "EGM2008 height");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::VERTICAL_CRS);
+ found3855 = true;
+ } else if (info.code == "6871") {
+ EXPECT_EQ(info.name,
+ "WGS 84 / Pseudo-Mercator + EGM2008 geoid height");
+ EXPECT_EQ(info.type,
+ AuthorityFactory::ObjectType::COMPOUND_CRS);
+ found6871 = true;
+ }
+ }
+ EXPECT_TRUE(found4326);
+ EXPECT_TRUE(found4978);
+ EXPECT_TRUE(found4979);
+ EXPECT_TRUE(found32631);
+ EXPECT_TRUE(found3855);
+ EXPECT_TRUE(found6871);
+ }
+}
} // namespace
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 1bbedc03..3cb50352 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -7654,12 +7654,39 @@ TEST(io, projparse_etmerc) {
crs->exportToPROJString(
PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4)
.get()),
- "+proj=etmerc +lat_0=0 +lon_0=0 +k=1 +x_0=0 +y_0=0 "
+ "+proj=tmerc +lat_0=0 +lon_0=0 +k=1 +x_0=0 +y_0=0 "
"+datum=WGS84 +units=m +no_defs +type=crs");
auto wkt1 = crs->exportToWKT(
WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
- EXPECT_TRUE(wkt1.find("EXTENSION[\"PROJ4\",\"+proj=etmerc +lat_0=0 "
+ EXPECT_TRUE(wkt1.find("EXTENSION[\"PROJ4\"") == std::string::npos)
+ << wkt1;
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projparse_tmerc_approx) {
+ auto obj =
+ PROJStringParser().createFromPROJString("+proj=tmerc +approx +type=crs");
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+ auto wkt2 = crs->exportToWKT(
+ &WKTFormatter::create()->simulCurNodeHasId().setMultiLine(false));
+ EXPECT_TRUE(
+ wkt2.find("METHOD[\"Transverse Mercator\",ID[\"EPSG\",9807]]") !=
+ std::string::npos)
+ << wkt2;
+
+ EXPECT_EQ(
+ crs->exportToPROJString(
+ PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4)
+ .get()),
+ "+proj=tmerc +approx +lat_0=0 +lon_0=0 +k=1 +x_0=0 +y_0=0 "
+ "+datum=WGS84 +units=m +no_defs +type=crs");
+
+ auto wkt1 = crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get());
+ EXPECT_TRUE(wkt1.find("EXTENSION[\"PROJ4\",\"+proj=tmerc +approx +lat_0=0 "
"+lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m "
"+no_defs\"]") != std::string::npos)
<< wkt1;
@@ -8735,6 +8762,10 @@ TEST(io, projparse_errors) {
EXPECT_THROW(PROJStringParser().createFromPROJString(
"proj=pipeline step init=epsg:4326 init=epsg:4326"),
ParsingException);
+
+ EXPECT_THROW(
+ PROJStringParser().createFromPROJString("proj=\tinit= +type=crs"),
+ ParsingException);
}
// ---------------------------------------------------------------------------
@@ -8961,3 +8992,61 @@ TEST(wkt_export, precision) {
WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()),
wkt);
}
+
+// ---------------------------------------------------------------------------
+
+// Avoid division by zero
+
+TEST(wkt_export, invalid_linear_unit) {
+ auto wkt = "PROJCS[\"WGS 84 / UTM zone 31N\",\n"
+ " GEOGCS[\"WGS 84\",\n"
+ " DATUM[\"WGS_1984\",\n"
+ " SPHEROID[\"WGS 84\",6378137,298.257223563]],\n"
+ " PRIMEM[\"Greenwich\",0],\n"
+ " UNIT[\"degree\",0.0174532925199433]],\n"
+ " PROJECTION[\"Transverse_Mercator\"],\n"
+ " PARAMETER[\"latitude_of_origin\",0],\n"
+ " PARAMETER[\"central_meridian\",3],\n"
+ " PARAMETER[\"scale_factor\",0.9996],\n"
+ " PARAMETER[\"false_easting\",500000],\n"
+ " PARAMETER[\"false_northing\",0],\n"
+ " UNIT[\"foo\",0]]";
+
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ EXPECT_THROW(
+ crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()),
+ FormattingException);
+}
+
+// ---------------------------------------------------------------------------
+
+// Avoid division by zero
+
+TEST(wkt_export, invalid_angular_unit) {
+ auto wkt = "PROJCS[\"WGS 84 / UTM zone 31N\",\n"
+ " GEOGCS[\"WGS 84\",\n"
+ " DATUM[\"WGS_1984\",\n"
+ " SPHEROID[\"WGS 84\",6378137,298.257223563]],\n"
+ " PRIMEM[\"Greenwich\",0],\n"
+ " UNIT[\"foo\",0]],\n"
+ " PROJECTION[\"Transverse_Mercator\"],\n"
+ " PARAMETER[\"latitude_of_origin\",0],\n"
+ " PARAMETER[\"central_meridian\",3],\n"
+ " PARAMETER[\"scale_factor\",0.9996],\n"
+ " PARAMETER[\"false_easting\",500000],\n"
+ " PARAMETER[\"false_northing\",0],\n"
+ " UNIT[\"meter\",1]]";
+
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ EXPECT_THROW(
+ crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()),
+ FormattingException);
+}
diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp
index 6c1ecf1c..586226e2 100644
--- a/test/unit/test_operation.cpp
+++ b/test/unit/test_operation.cpp
@@ -1237,9 +1237,9 @@ TEST(operation, tmerc_export) {
{
auto formatter = PROJStringFormatter::create();
- formatter->setUseETMercForTMerc(true);
+ formatter->setUseApproxTMerc(true);
EXPECT_EQ(conv->exportToPROJString(formatter.get()),
- "+proj=etmerc +lat_0=1 +lon_0=2 +k=3 +x_0=4 +y_0=5");
+ "+proj=tmerc +approx +lat_0=1 +lon_0=2 +k=3 +x_0=4 +y_0=5");
}
EXPECT_EQ(conv->exportToWKT(WKTFormatter::create().get()),
@@ -6061,21 +6061,21 @@ TEST(operation, compoundCRS_to_compoundCRS_with_vertical_transform) {
"+ellps=WGS84");
{
auto formatter = PROJStringFormatter::create();
- formatter->setUseETMercForTMerc(true);
+ formatter->setUseApproxTMerc(true);
EXPECT_EQ(op->exportToPROJString(formatter.get()),
- "+proj=pipeline +step +inv +proj=etmerc +lat_0=1 +lon_0=2 "
+ "+proj=pipeline +step +inv +proj=tmerc +approx +lat_0=1 +lon_0=2 "
"+k=3 +x_0=4 +y_0=5 +ellps=WGS84 +step "
"+proj=vgridshift +grids=bla.gtx +multiplier=0.001 +step "
- "+proj=utm +zone=32 "
+ "+proj=utm +approx +zone=32 "
"+ellps=WGS84");
}
{
auto formatter = PROJStringFormatter::create();
- formatter->setUseETMercForTMerc(true);
+ formatter->setUseApproxTMerc(true);
EXPECT_EQ(op->inverse()->exportToPROJString(formatter.get()),
- "+proj=pipeline +step +inv +proj=utm +zone=32 +ellps=WGS84 "
+ "+proj=pipeline +step +inv +proj=utm +approx +zone=32 +ellps=WGS84 "
"+step +inv +proj=vgridshift +grids=bla.gtx "
- "+multiplier=0.001 +step +proj=etmerc +lat_0=1 +lon_0=2 "
+ "+multiplier=0.001 +step +proj=tmerc +approx +lat_0=1 +lon_0=2 "
"+k=3 +x_0=4 +y_0=5 +ellps=WGS84");
}