aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/cli/testcct26
-rw-r--r--test/cli/testcct_out.dist14
-rwxr-xr-xtest/fuzzers/build.sh4
-rw-r--r--test/fuzzers/standard_fuzzer.cpp218
-rw-r--r--test/gie/builtins.gie124
-rw-r--r--test/unit/CMakeLists.txt11
-rw-r--r--test/unit/Makefile.am10
-rw-r--r--test/unit/gie_self_tests.cpp2
-rw-r--r--test/unit/pj_phi2_test.cpp2
-rw-r--r--test/unit/pj_transform_test.cpp740
-rw-r--r--test/unit/test_crs.cpp14
-rw-r--r--test/unit/test_factory.cpp6
-rw-r--r--test/unit/test_io.cpp103
13 files changed, 289 insertions, 985 deletions
diff --git a/test/cli/testcct b/test/cli/testcct
index db7c70a9..686931ea 100755
--- a/test/cli/testcct
+++ b/test/cli/testcct
@@ -32,6 +32,28 @@ echo "Testing cct -d 8 +proj=merc +R=1" >> ${OUT}
echo "90 45" 0 | $EXE -d 8 +proj=merc +R=1 >>${OUT}
echo "" >>${OUT}
+# tests without specifying the number of decimals (by default: 10 for radians and degrees, 4 for meters)
+echo "Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad" >> ${OUT}
+echo 0.5 2 | $EXE -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad >> ${OUT}
+
+echo "Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg" >> ${OUT}
+echo 0.5 2 | $EXE -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg >> ${OUT}
+
+echo "Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km" >> ${OUT}
+echo 0.5 2 | $EXE -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km >> ${OUT}
+echo "" >> ${OUT}
+
+# tests for which the number of decimals has been specified (-d 6)
+echo "Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad" >> ${OUT}
+echo 0.5 2 | $EXE -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad >> ${OUT}
+
+echo "Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg" >> ${OUT}
+echo 0.5 2 | $EXE -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg >> ${OUT}
+
+echo "Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km" >> ${OUT}
+echo 0.5 2 | $EXE -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km >> ${OUT}
+echo "" >> ${OUT}
+
echo "Test cct with object code initialization" >> ${OUT}
echo "3541657.3778 948984.2343 5201383.5231 2020.5" | $EXE EPSG:8366 >>${OUT}
@@ -39,8 +61,8 @@ echo "Test cct with object name initialization" >> ${OUT}
echo "3541657.3778 948984.2343 5201383.5231 2020.5" | $EXE "ITRF2014 to ETRF2014 (1)" >>${OUT}
echo "Test cct with object code initialization and file input" >> ${OUT}
-echo "3541657.3778 948984.2343 5201383.5231 2020.5" >> a
-echo "3541658.0000 948985.0000 5201384.0000 2020.5" >> b
+echo "3541657.3778 948984.2343 5201383.5231 2020.5" > a
+echo "3541658.0000 948985.0000 5201384.0000 2020.5" > b
$EXE EPSG:8366 a b >>${OUT}
/bin/rm a b
diff --git a/test/cli/testcct_out.dist b/test/cli/testcct_out.dist
index 353deb17..7762ace7 100644
--- a/test/cli/testcct_out.dist
+++ b/test/cli/testcct_out.dist
@@ -1,6 +1,20 @@
Testing cct -d 8 +proj=merc +R=1
1.57079633 0.88137359 0.00000000 inf
+Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad
+ 0.5000000000 2.0000000000 0.0000 0.0000
+Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg
+ 0.5000000000 2.0000000000 0.0000 0.0000
+Testing echo 0.5 2 | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km
+ 0.0005 0.0020 0.0000 0.0000
+
+Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad
+ 0.500000 2.000000 0.000000 0.0000
+Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg
+ 0.500000 2.000000 0.000000 0.0000
+Testing echo 0.5 2 | cct -d 6 -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=m +xy_out=km
+ 0.000500 0.002000 0.000000 0.0000
+
Test cct with object code initialization
3541657.9112 948983.7503 5201383.2482 2020.5000
Test cct with object name initialization
diff --git a/test/fuzzers/build.sh b/test/fuzzers/build.sh
index 1b2bf79c..37a207e0 100755
--- a/test/fuzzers/build.sh
+++ b/test/fuzzers/build.sh
@@ -69,12 +69,8 @@ build_fuzzer()
$LIB_FUZZING_ENGINE src/.libs/libproj.a $EXTRA_LIBS
}
-build_fuzzer standard_fuzzer test/fuzzers/standard_fuzzer.cpp
build_fuzzer proj_crs_to_crs_fuzzer test/fuzzers/proj_crs_to_crs_fuzzer.cpp
-echo "[libfuzzer]" > $OUT/standard_fuzzer.options
-echo "max_len = 10000" >> $OUT/standard_fuzzer.options
-
echo "[libfuzzer]" > $OUT/proj_crs_to_crs_fuzzer.options
echo "max_len = 10000" >> $OUT/proj_crs_to_crs_fuzzer.options
diff --git a/test/fuzzers/standard_fuzzer.cpp b/test/fuzzers/standard_fuzzer.cpp
deleted file mode 100644
index 468e8cbb..00000000
--- a/test/fuzzers/standard_fuzzer.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/******************************************************************************
- *
- * Project: proj.4
- * Purpose: Fuzzer
- * Author: Even Rouault, even.rouault at spatialys.com
- *
- ******************************************************************************
- * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ****************************************************************************/
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-#include "proj.h"
-#include "proj_api.h"
-
-/* Standalone build:
-g++ -g -std=c++11 standard_fuzzer.cpp -o standard_fuzzer -fvisibility=hidden -DSTANDALONE ../../src/.libs/libproj.a -lpthread -lsqlite3 -I../../src -I../../include
-*/
-
-extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv);
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len);
-
-int LLVMFuzzerInitialize(int* /*argc*/, char*** argv)
-{
- const char* argv0 = (*argv)[0];
- char* path = pj_strdup(argv0);
- char* lastslash = strrchr(path, '/');
- if( lastslash )
- {
- *lastslash = '\0';
- setenv("PROJ_LIB", path, 1);
- }
- else
- {
- setenv("PROJ_LIB", ".", 1);
- }
- free(path);
- return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
-{
- if( len > 1000 )
- {
-#ifdef STANDALONE
- fprintf(stderr, "Input too large\n");
-#endif
- return 0;
- }
-
- /* We expect the blob to be 3 lines: */
- /* source proj string\ndestination proj string\nx y */
- char* buf_dup = (char*)malloc(len+1);
- memcpy(buf_dup, buf, len);
- buf_dup[len] = 0;
- char* first_line = buf_dup;
- char* first_newline = strchr(first_line, '\n');
- if( !first_newline )
- {
- free(buf_dup);
- return 0;
- }
- first_newline[0] = 0;
- char* second_line = first_newline + 1;
- char* second_newline = strchr(second_line, '\n');
- if( !second_newline )
- {
- free(buf_dup);
- return 0;
- }
- second_newline[0] = 0;
- char* third_line = second_newline + 1;
- projPJ pj_src = pj_init_plus(first_line);
- if( !pj_src )
- {
- free(buf_dup);
- return 0;
- }
- projPJ pj_dst = pj_init_plus(second_line);
- if( !pj_dst )
- {
- free(buf_dup);
- pj_free(pj_src);
- proj_cleanup();
- return 0;
- }
- double x = 0, y = 0, z = 9;
- bool from_binary = false;
- bool has_z = false;
- if( strncmp(third_line, "BINARY_2D:", strlen("BINARY_2D:")) == 0 &&
- third_line - first_line + strlen("BINARY_2D:") + 2 * sizeof(double) <= len )
- {
- from_binary = true;
- memcpy(&x, third_line + strlen("BINARY_2D:"), sizeof(double));
- memcpy(&y, third_line + strlen("BINARY_2D:") + sizeof(double), sizeof(double));
- }
- else if( strncmp(third_line, "BINARY_3D:", strlen("BINARY_3D:")) == 0 &&
- third_line - first_line + strlen("BINARY_3D:") + 3 * sizeof(double) <= len )
- {
- from_binary = true;
- has_z = true;
- memcpy(&x, third_line + strlen("BINARY_3D:"), sizeof(double));
- memcpy(&y, third_line + strlen("BINARY_3D:") + sizeof(double), sizeof(double));
- memcpy(&z, third_line + strlen("BINARY_3D:") + 2 * sizeof(double), sizeof(double));
- }
- else if( sscanf(third_line, "%lf %lf", &x, &y) != 2 )
- {
- free(buf_dup);
- pj_free(pj_src);
- pj_free(pj_dst);
- proj_cleanup();
- return 0;
- }
-#ifdef STANDALONE
- fprintf(stderr, "src=%s\n", first_line);
- fprintf(stderr, "dst=%s\n", second_line);
- if( from_binary )
- {
- if( has_z )
- fprintf(stderr, "coord (from binary)=%.18g %.18g %.18g\n", x, y, z);
- else
- fprintf(stderr, "coord (from binary)=%.18g %.18g\n", x, y);
- }
- else
- fprintf(stderr, "coord=%s\n", third_line);
-#endif
- if( has_z )
- pj_transform( pj_src, pj_dst, 1, 0, &x, &y, &z );
- else
- pj_transform( pj_src, pj_dst, 1, 0, &x, &y, NULL );
- free(buf_dup);
- pj_free(pj_src);
- pj_free(pj_dst);
- proj_cleanup();
- return 0;
-}
-
-#ifdef STANDALONE
-
-int main(int argc, char* argv[])
-{
- if( argc < 2 )
- {
- const char str[] =
- "+proj=longlat +datum=WGS84 +nodefs\n+proj=longlat +datum=WGS84 +nodefs\n2 49";
- int ret = LLVMFuzzerTestOneInput((const uint8_t*)(str), sizeof(str) - 1);
- if( ret )
- return ret;
-
- const char str2[] =
- "+proj=longlat +datum=WGS84 +nodefs\n+proj=longlat +datum=WGS84 +nodefs\nBINARY_2D:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF";
- ret = LLVMFuzzerTestOneInput((const uint8_t*)(str2), sizeof(str2) - 1);
- if( ret )
- return ret;
-
- const char str3[] =
- "+proj=longlat +datum=WGS84 +nodefs\n+proj=longlat +datum=WGS84 +nodefs\nBINARY_3D:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00";
- ret = LLVMFuzzerTestOneInput((const uint8_t*)(str3), sizeof(str3) - 1);
- if( ret )
- return ret;
-
- return 0;
- }
- else
- {
- int nRet = 0;
- void* buf = NULL;
- int nLen = 0;
- FILE* f = fopen(argv[1], "rb");
- if( !f )
- {
- fprintf(stderr, "%s does not exist.\n", argv[1]);
- exit(1);
- }
- fseek(f, 0, SEEK_END);
- nLen = (int)ftell(f);
- fseek(f, 0, SEEK_SET);
- buf = malloc(nLen);
- if( !buf )
- {
- fprintf(stderr, "malloc failed.\n");
- fclose(f);
- exit(1);
- }
- fread(buf, nLen, 1, f);
- fclose(f);
- nRet = LLVMFuzzerTestOneInput((const uint8_t*)(buf), nLen);
- free(buf);
- return nRet;
- }
-}
-
-#endif // STANDALONE
diff --git a/test/gie/builtins.gie b/test/gie/builtins.gie
index add5d925..0f86bed2 100644
--- a/test/gie/builtins.gie
+++ b/test/gie/builtins.gie
@@ -5782,6 +5782,130 @@ accept -200 -100
expect -0.001790493 -0.000895247
-------------------------------------------------------------------------------
+# Approx tmerc on a almost spherical ellipsoid, lat_0 north hemisphere
+
+operation +proj=tmerc +a=6400000 +rf=1e12 +k=0.9 +lat_0=40 +approx
+-------------------------------------------------------------------------------
+tolerance 0.1 mm
+
+accept 0 -30
+expect 0 -7037167.5440
+roundtrip 1
+
+accept 1 -30
+expect 87064.5795 -7037547.4590
+roundtrip 1
+
+accept -1 -30
+expect -87064.5795 -7037547.4590
+roundtrip 1
+
+accept 0 30
+expect 0 -1005309.6491
+roundtrip 1
+
+accept 0 40
+expect 0 0
+roundtrip 1
+
+accept 1 41
+expect 75872.2182 100965.3718
+roundtrip 1
+
+-------------------------------------------------------------------------------
+# Approx tmerc on a sphere, lat_0 north hemisphere
+
+operation +proj=tmerc +R=6400000 +k=0.9 +lat_0=40
+-------------------------------------------------------------------------------
+tolerance 0.1 mm
+
+accept 0 -30
+expect 0 -7037167.5440
+roundtrip 1
+
+accept 1 -30
+expect 87064.5795 -7037547.4590
+roundtrip 1
+
+accept -1 -30
+expect -87064.5795 -7037547.4590
+roundtrip 1
+
+accept 0 30
+expect 0 -1005309.6491
+roundtrip 1
+
+accept 0 40
+expect 0 0
+roundtrip 1
+
+accept 1 41
+expect 75872.2182 100965.3718
+roundtrip 1
+
+-------------------------------------------------------------------------------
+# Approx tmerc on a almost spherical ellipsoid, lat_0 south hemisphere
+
+operation +proj=tmerc +a=6400000 +rf=1e12 +k=0.9 +lat_0=-40 +approx
+-------------------------------------------------------------------------------
+tolerance 0.1 mm
+
+accept 0 -30
+expect 0 1005309.6491
+roundtrip 1
+
+accept 1 -30
+expect 87064.5795 1004929.7341
+roundtrip 1
+
+accept -1 -30
+expect -87064.5795 1004929.7341
+roundtrip 1
+
+accept 0 30
+expect 0 7037167.5440
+roundtrip 1
+
+accept 0 -40
+expect 0 0
+roundtrip 1
+
+accept 1 -41
+expect 75872.2182 -100965.3718
+roundtrip 1
+
+-------------------------------------------------------------------------------
+# Approx tmerc on a sphere, lat_0 south hemisphere
+
+operation +proj=tmerc +R=6400000 +k=0.9 +lat_0=-40
+-------------------------------------------------------------------------------
+tolerance 0.1 mm
+
+accept 0 -30
+expect 0 1005309.6491
+roundtrip 1
+
+accept 1 -30
+expect 87064.5795 1004929.7341
+roundtrip 1
+
+accept -1 -30
+expect -87064.5795 1004929.7341
+roundtrip 1
+
+accept 0 30
+expect 0 7037167.5440
+roundtrip 1
+
+accept 0 -40
+expect 0 0
+roundtrip 1
+
+accept 1 -41
+expect 75872.2182 -100965.3718
+roundtrip 1
+
+-------------------------------------------------------------------------------
operation +proj=tmerc +R=1
-------------------------------------------------------------------------------
direction inverse
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 2c0c19a9..3924f47d 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -69,17 +69,6 @@ set(PROJ_TEST_ENVIRONMENT
"PROJ_SOURCE_DATA=${PROJ_SOURCE_DIR}/data"
)
-add_executable(proj_pj_transform_test
- main.cpp
- pj_transform_test.cpp)
-target_link_libraries(proj_pj_transform_test
- GTest::gtest
- ${PROJ_LIBRARIES})
-add_test(NAME proj_pj_transform_test COMMAND proj_pj_transform_test)
-set_property(TEST proj_pj_transform_test
- PROPERTY ENVIRONMENT ${PROJ_TEST_ENVIRONMENT})
-
-
add_executable(proj_errno_string_test
main.cpp
proj_errno_string_test.cpp)
diff --git a/test/unit/Makefile.am b/test/unit/Makefile.am
index 483cb0bd..4e931c2b 100644
--- a/test/unit/Makefile.am
+++ b/test/unit/Makefile.am
@@ -9,8 +9,7 @@ AM_CXXFLAGS = @CXX_WFLAGS@ @NO_ZERO_AS_NULL_POINTER_CONSTANT_FLAG@
PROJ_LIB ?= ../../data/for_tests
-noinst_PROGRAMS = pj_transform_test
-noinst_PROGRAMS += pj_phi2_test
+noinst_PROGRAMS = pj_phi2_test
noinst_PROGRAMS += proj_errno_string_test
noinst_PROGRAMS += proj_angular_io_test
noinst_PROGRAMS += proj_context_test
@@ -21,11 +20,6 @@ noinst_PROGRAMS += test_network
noinst_PROGRAMS += test_defmodel
noinst_PROGRAMS += test_tinshift
-pj_transform_test_SOURCES = pj_transform_test.cpp main.cpp
-pj_transform_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
-
-pj_transform_test-check: pj_transform_test
- PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY=YES PROJ_LIB=$(PROJ_LIB) ./pj_transform_test
pj_phi2_test_SOURCES = pj_phi2_test.cpp main.cpp
pj_phi2_test_LDADD = ../../src/libproj.la @GTEST_LIBS@
@@ -84,6 +78,6 @@ test_tinshift_LDADD = ../../src/libproj.la @GTEST_LIBS@
test_tinshift-check: test_tinshift
PROJ_LIB=$(PROJ_LIB) ./test_tinshift
-check-local: pj_transform_test-check pj_phi2_test-check proj_errno_string_test-check \
+check-local: pj_phi2_test-check proj_errno_string_test-check \
proj_angular_io_test-check proj_context_test-check test_cpp_api-check \
gie_self_tests-check test_network-check test_defmodel-check test_tinshift-check
diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp
index 6f1b3c32..f9252137 100644
--- a/test/unit/gie_self_tests.cpp
+++ b/test/unit/gie_self_tests.cpp
@@ -548,7 +548,7 @@ static void test_time(const char *args, double tol, double t_in, double t_exp) {
out = proj_trans(P, PJ_INV, out);
EXPECT_NEAR(out.xyzt.t, t_in, tol);
- pj_free(P);
+ proj_destroy(P);
proj_log_level(NULL, PJ_LOG_NONE);
}
diff --git a/test/unit/pj_phi2_test.cpp b/test/unit/pj_phi2_test.cpp
index b4e6b68f..7ccbb01c 100644
--- a/test/unit/pj_phi2_test.cpp
+++ b/test/unit/pj_phi2_test.cpp
@@ -37,7 +37,7 @@
namespace {
TEST(PjPhi2Test, Basic) {
- projCtx ctx = pj_get_default_ctx();
+ PJ_CONTEXT *ctx = pj_get_default_ctx();
// Expectation is that only sane values of e (and nan is here reckoned to
// be sane) are passed to pj_phi2. Thus the return value with other values
diff --git a/test/unit/pj_transform_test.cpp b/test/unit/pj_transform_test.cpp
deleted file mode 100644
index ddb054f0..00000000
--- a/test/unit/pj_transform_test.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-/******************************************************************************
- *
- * Project: PROJ
- * Purpose: Test pj_transform() legacy interface
- * Author: Even Rouault <even dot rouault at spatialys dot com>
- *
- ******************************************************************************
- * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ****************************************************************************/
-
-#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H
-
-#include "gtest_include.h"
-#include <memory>
-
-// PROJ include order is sensitive
-// clang-format off
-#include <proj.h>
-#include "proj_internal.h"
-#include <proj_api.h>
-// clang-format on
-
-namespace {
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_longlat) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_EQ(x, 2 * DEG_TO_RAD);
- EXPECT_EQ(y, 49 * DEG_TO_RAD);
-
- x = 182 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_EQ(x, 182 * DEG_TO_RAD);
- EXPECT_EQ(y, 49 * DEG_TO_RAD);
-
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_proj) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
- double x = 3 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 500000, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_proj_tometer) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84 +to_meter=1000");
- double x = 3 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 500, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, proj_to_longlat) {
- auto src = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 500000;
- double y = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 3 * DEG_TO_RAD, 1e-12);
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, proj_to_proj) {
- auto src = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
- auto dst = pj_init_plus("+proj=utm +zone=31 +datum=WGS84");
- double x = 500000;
- double y = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 500000, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_geocent) {
- auto src = pj_init_plus("+proj=longlat +R=2");
- auto dst = pj_init_plus("+proj=geocent +R=2");
- double x = 0;
- double y = 0;
- double z = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- EXPECT_NEAR(z, 0, 1e-8);
-
- x = 90 * DEG_TO_RAD;
- y = 0;
- z = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 0, 1e-8);
- EXPECT_NEAR(y, 2, 1e-8);
- EXPECT_NEAR(z, 0, 1e-8);
-
- x = 0;
- y = 90 * DEG_TO_RAD;
- z = 0.1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 0, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- EXPECT_NEAR(z, 2 + 0.1, 1e-8);
-
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_geocent_to_meter) {
- auto src = pj_init_plus("+proj=longlat +R=2");
- auto dst = pj_init_plus("+proj=geocent +R=2 +to_meter=1000");
- double x = 0;
- double y = 0;
- double z = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2e-3, 1e-8);
- EXPECT_NEAR(y, 0, 1e-8);
- EXPECT_NEAR(z, 0, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, geocent_to_longlat) {
- auto src = pj_init_plus("+proj=geocent +R=2");
- auto dst = pj_init_plus("+proj=longlat +R=2");
- double x = 0;
- double y = 2;
- double z = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 0, 1e-12);
-
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, geocent_to_meter_to_longlat) {
- auto src = pj_init_plus("+proj=geocent +to_meter=1000 +R=2");
- auto dst = pj_init_plus("+proj=longlat +R=2");
- double x = 0;
- double y = 2e-3;
- double z = 0;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 0, 1e-12);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, pm) {
- auto src = pj_init_plus("+proj=longlat +pm=3 +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +pm=1 +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, (2 + 3 - 1) * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_EQ(y, 49 * DEG_TO_RAD) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_geoc_to_longlat) {
- auto src = pj_init_plus("+proj=longlat +geoc +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 48.809360314691766 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_to_longlat_geoc) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +geoc +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 48.809360314691766 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, ellps_to_ellps_noop) {
- auto src = pj_init_plus("+proj=longlat +ellps=clrk66");
- auto dst = pj_init_plus("+proj=longlat +ellps=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, towgs84_3param_noop) {
- auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3");
- auto dst = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 10;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, towgs84_7param_noop) {
- auto src =
- pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7");
- auto dst =
- pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 10;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_towgs84_3param_to_datum) {
- auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 90 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- double z = 10;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10 + 1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_towgs84_3param_to_datum_no_z) {
- auto src = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 90 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_towgs84_7param_to_datum) {
- auto src =
- pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0,0,0,0,0.5");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 90 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- double z = 10;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 14.189073500223458, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, datum_to_longlat_towgs84_3param) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0");
- double x = 90 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- double z = 10 + 1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, datum_to_longlat_towgs84_7param) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst =
- pj_init_plus("+proj=longlat +ellps=WGS84 +towgs84=0,1,0,0,0,0,0.5");
- double x = 90 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- double z = 14.189073500223458;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 90 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, ellps_grs80_towgs84_to_datum_wgs84) {
- auto src = pj_init_plus("+proj=longlat +ellps=GRS80 +towgs84=0,0,0");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 10;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-15) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-15) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, longlat_nadgrids_to_datum) {
- auto src = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
- auto dst = pj_init_plus("+proj=longlat +datum=NAD83");
- double x = -100 * DEG_TO_RAD;
- double y = 40 * DEG_TO_RAD;
- double z = 10;
- int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
- EXPECT_TRUE(ret == 0 || ret == PJD_ERR_FAILED_TO_LOAD_GRID);
- if (ret == 0) {
- EXPECT_NEAR(x, -100.00040583667015 * DEG_TO_RAD, 1e-12)
- << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 40.000005895651363 * DEG_TO_RAD, 1e-12)
- << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10.000043224543333, 1e-8);
- }
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, nadgrids_noop) {
- auto src = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
- auto dst = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
- double x = -100 * DEG_TO_RAD;
- double y = 40 * DEG_TO_RAD;
- double z = 10;
- int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
- EXPECT_TRUE(ret == 0);
- if (ret == 0) {
- EXPECT_NEAR(x, -100 * DEG_TO_RAD, 1e-15) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 40 * DEG_TO_RAD, 1e-15) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- }
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, datum_to_longlat_nadgrids) {
- auto src = pj_init_plus("+proj=longlat +datum=NAD83");
- auto dst = pj_init_plus("+proj=longlat +ellps=clrk66 +nadgrids=conus");
- double x = -100.00040583667015 * DEG_TO_RAD;
- double y = 40.000005895651363 * DEG_TO_RAD;
- double z = 10.000043224543333;
- int ret = pj_transform(src, dst, 1, 0, &x, &y, &z);
- EXPECT_TRUE(ret == 0 || ret == PJD_ERR_FAILED_TO_LOAD_GRID);
- if (ret == 0) {
- EXPECT_NEAR(x, -100 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 40 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 10, 1e-8);
- }
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, long_wrap) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +lon_wrap=180");
- double x = -1 * DEG_TO_RAD;
- double y = 0 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 359 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 0 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, src_vto_meter) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84 +vto_meter=1000");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 1000, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, dest_vto_meter) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +vto_meter=1000");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 1000;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, src_axis_neu_with_z) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 49 * DEG_TO_RAD;
- double y = 2 * DEG_TO_RAD;
- double z = 1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, src_axis_neu_without_z) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 49 * DEG_TO_RAD;
- double y = 2 * DEG_TO_RAD;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, nullptr), 0);
- EXPECT_NEAR(x, 2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, src_axis_swd) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84 +axis=swd");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84");
- double x = 49 * DEG_TO_RAD;
- double y = 2 * DEG_TO_RAD;
- double z = -1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, -2 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, -49 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, dst_axis_neu) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +axis=neu");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, 49 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, 2 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, 1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, dst_axis_swd) {
- auto src = pj_init_plus("+proj=longlat +datum=WGS84");
- auto dst = pj_init_plus("+proj=longlat +datum=WGS84 +axis=swd");
- double x = 2 * DEG_TO_RAD;
- double y = 49 * DEG_TO_RAD;
- double z = 1;
- EXPECT_EQ(pj_transform(src, dst, 1, 0, &x, &y, &z), 0);
- EXPECT_NEAR(x, -49 * DEG_TO_RAD, 1e-12) << x / DEG_TO_RAD;
- EXPECT_NEAR(y, -2 * DEG_TO_RAD, 1e-12) << y / DEG_TO_RAD;
- EXPECT_NEAR(z, -1, 1e-8);
- pj_free(src);
- pj_free(dst);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(pj_transform_test, init_epsg) {
- auto src = pj_init_plus("+init=epsg:4326");
- ASSERT_TRUE(src != nullptr);
- auto dst = pj_init_plus("+init=epsg:32631");
- ASSERT_TRUE(dst != nullptr);
- 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(proj_api_h, pj_set_searchpath) {
-
- const char *path = "/i_do/not/exit";
- pj_set_searchpath(1, &path);
- {
- auto info = proj_info();
- EXPECT_EQ(info.path_count, 1U);
- ASSERT_NE(info.paths, nullptr);
- ASSERT_NE(info.paths[0], nullptr);
- EXPECT_EQ(std::string(info.paths[0]), path);
- }
-
- pj_set_searchpath(0, nullptr);
- {
- auto info = proj_info();
- EXPECT_EQ(info.path_count, 0U);
- EXPECT_EQ(info.paths, nullptr);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(proj_api_h, pj_set_finder) {
-
- const auto myfinder = [](const char *) -> const char * { return nullptr; };
- pj_set_finder(myfinder);
-
- pj_set_finder(nullptr);
-}
-
-// ---------------------------------------------------------------------------
-
-TEST(proj_api_h, default_fileapi) {
- auto ctx = pj_ctx_alloc();
- auto fid = pj_open_lib(ctx, "proj.db", "rb");
- ASSERT_NE(fid, nullptr);
- char header[6];
- ASSERT_EQ(pj_ctx_fread(ctx, header, 1, 6, fid), 6U);
- ASSERT_TRUE(memcmp(header, "SQLite", 6) == 0);
- ASSERT_EQ(pj_ctx_ftell(ctx, fid), 6);
- ASSERT_EQ(pj_ctx_fseek(ctx, fid, 0, SEEK_SET), 0);
- ASSERT_EQ(pj_ctx_ftell(ctx, fid), 0);
- pj_ctx_fclose(ctx, fid);
- pj_ctx_free(ctx);
-}
-
-// ---------------------------------------------------------------------------
-
-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;
- bool gotInMyFSeek = false;
- bool gotInMyFTell = false;
- bool gotInMyFClose = false;
-};
-
-struct MyFile {
- FILE *fp;
- Spy *spy;
-};
-
-static PAFile myFOpen(projCtx ctx, const char *filename, const char *access) {
- FILE *fp = fopen(filename, access);
- if (!fp)
- return nullptr;
- MyFile *myF = new MyFile;
- myF->spy = (Spy *)pj_ctx_get_app_data(ctx);
- myF->spy->gotInMyFOpen = true;
- myF->fp = fp;
- return reinterpret_cast<PAFile>(myF);
-}
-
-static size_t myFRead(void *buffer, size_t size, size_t nmemb, PAFile file) {
- MyFile *myF = reinterpret_cast<MyFile *>(file);
- myF->spy->gotInMyFRead = true;
- return fread(buffer, size, nmemb, myF->fp);
-}
-
-static int myFSeek(PAFile file, long offset, int whence) {
- MyFile *myF = reinterpret_cast<MyFile *>(file);
- myF->spy->gotInMyFSeek = true;
- return fseek(myF->fp, offset, whence);
-}
-
-static long myFTell(PAFile file) {
- MyFile *myF = reinterpret_cast<MyFile *>(file);
- myF->spy->gotInMyFTell = true;
- return ftell(myF->fp);
-}
-
-static void myFClose(PAFile file) {
- MyFile *myF = reinterpret_cast<MyFile *>(file);
- myF->spy->gotInMyFClose = true;
- fclose(myF->fp);
- delete myF;
-}
-
-TEST(proj_api_h, custom_fileapi) {
- auto ctx = pj_ctx_alloc();
- Spy spy;
- pj_ctx_set_app_data(ctx, &spy);
- projFileAPI myAPI = {myFOpen, myFRead, myFSeek, myFTell, myFClose};
- pj_ctx_set_fileapi(ctx, &myAPI);
- EXPECT_EQ(pj_ctx_get_fileapi(ctx), &myAPI);
- auto fid = pj_open_lib(ctx, "proj.db", "rb");
- ASSERT_NE(fid, nullptr);
- char header[6];
- ASSERT_EQ(pj_ctx_fread(ctx, header, 1, 6, fid), 6U);
- ASSERT_TRUE(memcmp(header, "SQLite", 6) == 0);
- ASSERT_EQ(pj_ctx_ftell(ctx, fid), 6);
- ASSERT_EQ(pj_ctx_fseek(ctx, fid, 0, SEEK_SET), 0);
- ASSERT_EQ(pj_ctx_ftell(ctx, fid), 0);
- pj_ctx_fclose(ctx, fid);
- pj_ctx_free(ctx);
- EXPECT_TRUE(spy.gotInMyFOpen);
- EXPECT_TRUE(spy.gotInMyFRead);
- EXPECT_TRUE(spy.gotInMyFSeek);
- EXPECT_TRUE(spy.gotInMyFTell);
- 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_crs.cpp b/test/unit/test_crs.cpp
index 9c81d0cb..cea5ff6c 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -414,6 +414,20 @@ TEST(crs, EPSG_4326_as_WKT1_ESRI_with_database) {
// ---------------------------------------------------------------------------
+TEST(crs, EPSG_4901_as_WKT1_ESRI_with_PRIMEM_unit_name_morphing) {
+ auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto crs = factory->createCoordinateReferenceSystem("4901");
+ WKTFormatterNNPtr f(WKTFormatter::create(
+ WKTFormatter::Convention::WKT1_ESRI, DatabaseContext::create()));
+ EXPECT_EQ(crs->exportToWKT(f.get()),
+ "GEOGCS[\"GCS_ATF_Paris\",DATUM[\"D_ATF\","
+ "SPHEROID[\"Plessis_1817\",6376523.0,308.64]],"
+ "PRIMEM[\"Paris_RGS\",2.33720833333333],"
+ "UNIT[\"Grad\",0.0157079632679489]]");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(crs, EPSG_4326_as_WKT1_ESRI_without_database) {
auto crs = GeographicCRS::EPSG_4326;
WKTFormatterNNPtr f(
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 8e9b7ab6..ff86c4d3 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -3082,6 +3082,12 @@ TEST(factory, createObjectsFromName) {
.size(),
1U);
+ // Exact name, but with other CRS that have an aliases to it ==> should
+ // match only the CRS with the given name, not those other CRS.
+ EXPECT_EQ(factory->createObjectsFromName("ETRS89 / UTM zone 32N", {}, false)
+ .size(),
+ 1U);
+
// Prime meridian
EXPECT_EQ(factoryEPSG->createObjectsFromName("Paris", {}, false, 2).size(),
1U);
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 81894fb0..5463adc3 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -488,6 +488,62 @@ TEST(wkt_parse, wkt1_EPSG_4807_grad_mess) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_esri_EPSG_4901_grad) {
+ auto obj =
+ WKTParser()
+ .attachDatabaseContext(DatabaseContext::create())
+ .createFromWKT("GEOGCS[\"GCS_ATF_Paris\",DATUM[\"D_ATF\","
+ "SPHEROID[\"Plessis_1817\",6376523.0,308.64]],"
+ "PRIMEM[\"Paris_RGS\",2.33720833333333],"
+ "UNIT[\"Grad\",0.0157079632679489]]");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ auto primem = datum->primeMeridian();
+ EXPECT_EQ(primem->nameStr(), "Paris RGS");
+ // The PRIMEM is really in degree
+ EXPECT_EQ(primem->longitude().unit(), UnitOfMeasure::DEGREE);
+ EXPECT_NEAR(primem->longitude().value(), 2.33720833333333, 1e-14);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(wkt_parse, wkt2_epsg_org_EPSG_4901_PRIMEM_weird_sexagesimal_DMS) {
+ // Current epsg.org output may use the EPSG:9110 "sexagesimal DMS"
+ // unit and a DD.MMSSsss value, but this will likely be changed to
+ // use decimal degree.
+ auto obj = WKTParser().createFromWKT(
+ "GEOGCRS[\"ATF (Paris)\","
+ " DATUM[\"Ancienne Triangulation Francaise (Paris)\","
+ " ELLIPSOID[\"Plessis 1817\",6376523,308.64,"
+ " LENGTHUNIT[\"metre\",1,ID[\"EPSG\",9001]],"
+ " ID[\"EPSG\",7027]],"
+ " ID[\"EPSG\",6901]],"
+ " PRIMEM[\"Paris RGS\",2.201395,"
+ " ANGLEUNIT[\"sexagesimal DMS\",1,ID[\"EPSG\",9110]],"
+ " ID[\"EPSG\",8914]],"
+ " CS[ellipsoidal,2,"
+ " ID[\"EPSG\",6403]],"
+ " AXIS[\"Geodetic latitude (Lat)\",north,"
+ " ORDER[1]],"
+ " AXIS[\"Geodetic longitude (Lon)\",east,"
+ " ORDER[2]],"
+ " ANGLEUNIT[\"grad\",0.015707963267949,ID[\"EPSG\",9105]],"
+ " USAGE[SCOPE[\"Geodesy.\"],AREA[\"France - mainland onshore.\"],"
+ " BBOX[42.33,-4.87,51.14,8.23]],"
+ "ID[\"EPSG\",4901]]");
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ auto primem = datum->primeMeridian();
+ EXPECT_EQ(primem->longitude().unit(), UnitOfMeasure::DEGREE);
+ EXPECT_NEAR(primem->longitude().value(), 2.33720833333333, 1e-14);
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, wkt1_geographic_old_datum_name_from_EPSG_code) {
auto wkt =
"GEOGCS[\"S-JTSK (Ferro)\",\n"
@@ -619,6 +675,53 @@ TEST(wkt_parse, wkt1_geographic_with_PROJ4_extension) {
// ---------------------------------------------------------------------------
+TEST(wkt_parse, wkt1_geographic_epsg_org_api_4326) {
+ // Output from
+ // https://apps.epsg.org/api/v1/CoordRefSystem/4326/export/?format=wkt&formatVersion=1
+ // using a datum ensemble name
+ auto wkt =
+ "GEOGCS[\"WGS 84\",DATUM[\"World Geodetic System 1984 ensemble\","
+ "SPHEROID[\"WGS 84\",6378137,298.257223563,"
+ "AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree (supplier to define representation)\","
+ "0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],"
+ "AXIS[\"Lat\",north],AXIS[\"Lon\",east],"
+ "AUTHORITY[\"EPSG\",\"4326\"]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ EXPECT_EQ(datum->nameStr(), "World Geodetic System 1984");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(wkt_parse, wkt1_geographic_epsg_org_api_4258) {
+ // Output from
+ // https://apps.epsg.org/api/v1/CoordRefSystem/4258/export/?format=wkt&formatVersion=1
+ // using a datum ensemble name
+ auto wkt =
+ "GEOGCS[\"ETRS89\","
+ "DATUM[\"European Terrestrial Reference System 1989 ensemble\","
+ "SPHEROID[\"GRS 1980\",6378137,298.257222101,"
+ "AUTHORITY[\"EPSG\",\"7019\"]],AUTHORITY[\"EPSG\",\"6258\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree (supplier to define representation)\","
+ "0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],"
+ "AXIS[\"Lat\",north],AXIS[\"Lon\",east],"
+ "AUTHORITY[\"EPSG\",\"4258\"]]";
+ auto obj = WKTParser().createFromWKT(wkt);
+ auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj);
+ ASSERT_TRUE(crs != nullptr);
+
+ auto datum = crs->datum();
+ EXPECT_EQ(datum->nameStr(), "European Terrestrial Reference System 1989");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(wkt_parse, wkt1_geocentric_with_PROJ4_extension) {
auto wkt = "GEOCCS[\"WGS 84\",\n"
" DATUM[\"unknown\",\n"