diff options
Diffstat (limited to 'test')
| -rwxr-xr-x | test/cli/testcct | 26 | ||||
| -rw-r--r-- | test/cli/testcct_out.dist | 14 | ||||
| -rwxr-xr-x | test/fuzzers/build.sh | 4 | ||||
| -rw-r--r-- | test/fuzzers/standard_fuzzer.cpp | 218 | ||||
| -rw-r--r-- | test/gie/builtins.gie | 124 | ||||
| -rw-r--r-- | test/unit/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | test/unit/Makefile.am | 10 | ||||
| -rw-r--r-- | test/unit/gie_self_tests.cpp | 2 | ||||
| -rw-r--r-- | test/unit/pj_phi2_test.cpp | 2 | ||||
| -rw-r--r-- | test/unit/pj_transform_test.cpp | 740 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 14 | ||||
| -rw-r--r-- | test/unit/test_factory.cpp | 6 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 103 |
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" |
