ADD: new track message, Entity class and Position class

This commit is contained in:
Henry Winkel
2022-12-20 17:20:35 +01:00
parent 469ecfb099
commit 98ebb563a8
2114 changed files with 482360 additions and 24 deletions

1
libs/geographiclib/tests/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.errs

View File

@@ -0,0 +1,892 @@
# Compile test programs
set (TESTPROGRAMS geodtest signtest polygontest)
if (GEOGRAPHICLIB_PRECISION GREATER 1)
add_custom_target (testprograms)
foreach (TESTPROGRAM ${TESTPROGRAMS})
add_executable (${TESTPROGRAM} ${TESTPROGRAM}.cpp)
add_dependencies (testprograms ${TESTPROGRAM})
target_link_libraries (${TESTPROGRAM} ${PROJECT_LIBRARIES}
${HIGHPREC_LIBRARIES})
add_test (NAME ${TESTPROGRAM} COMMAND ${TESTPROGRAM})
endforeach ()
# Put all the tests into a folder in the IDE
set_property (TARGET testprograms ${TESTPROGRAMS} PROPERTY FOLDER tests)
endif ()
# Here are the tests for GeographicLib
if (DEFINED ENV{GEOGRAPHICLIB_DATA})
set (_DATADIR "$ENV{GEOGRAPHICLIB_DATA}")
else ()
set (_DATADIR "${GEOGRAPHICLIB_DATA}")
endif ()
# The tests consist of calling the various tools with --input-string and
# matching the output against regular expressions.
add_test (NAME GeoConvert0 COMMAND GeoConvert
-p -3 -m --input-string "33.3 44.4")
set_tests_properties (GeoConvert0 PROPERTIES PASS_REGULAR_EXPRESSION
"38SMB4484")
# I/O for boost-quadmath has a bug where precision 0 is interpreted as
# printed all the digits of the number (instead of printing the integer
# portion). Problem reported on 2014-06-07:
# https://svn.boost.org/trac/boost/ticket/10103. GeographicLib 1.42
# includes a workaround for this bug.
add_test (NAME GeoConvert1 COMMAND GeoConvert -d --input-string "38smb")
set_tests_properties (GeoConvert1 PROPERTIES PASS_REGULAR_EXPRESSION
"32d59'14\\.1\"N 044d27'53\\.4\"E")
add_test (NAME GeoConvert2 COMMAND GeoConvert
-p -2 --input-string "30d30'30\" 30.50833")
set_tests_properties (GeoConvert2 PROPERTIES PASS_REGULAR_EXPRESSION
"30\\.508 30\\.508")
add_test (NAME GeoConvert3 COMMAND GeoConvert --junk)
set_tests_properties (GeoConvert3 PROPERTIES WILL_FAIL ON)
add_test (NAME GeoConvert4 COMMAND GeoConvert --input-string garbage)
set_tests_properties (GeoConvert4 PROPERTIES WILL_FAIL ON)
# Check fix for DMS::Decode bug fixed on 2011-03-22
add_test (NAME GeoConvert5 COMMAND GeoConvert --input-string "5d. 0")
set_tests_properties (GeoConvert5 PROPERTIES WILL_FAIL ON)
# Check fix for DMS::Decode double rounding bug fixed on 2012-11-15
# This test is known to fail for VC 11 and 12 bug reported 2013-01-10
# OK to skip this test for these compilers because this is a question
# of accuracy of the least significant bit. The bug is fixed in VC 14.
#
# N.B. 179.99999999999998578 = 180 - 0.50032 * 0.5^45 which (as a
# double) rounds to 180 - 0.5^45 = 179.9999999999999716
add_test (NAME GeoConvert6 COMMAND GeoConvert -p 9
--input-string "0 179.99999999999998578")
set_tests_properties (GeoConvert6 PROPERTIES PASS_REGULAR_EXPRESSION
"179\\.9999999999999[7-9]")
# This invokes MGRS::Check()
add_test (NAME GeoConvert7 COMMAND GeoConvert --version)
# Check fix to PolarStereographic es initialization blunder (2015-05-18)
add_test (NAME GeoConvert8 COMMAND GeoConvert -u -p 6 --input-string "86 0")
set_tests_properties (GeoConvert8 PROPERTIES PASS_REGULAR_EXPRESSION
"n 2000000\\.0* 1555731\\.570643")
# Check that integer(minutes) >= 60 and decimal(minutes) > 60 fail.
# Latter used to succeed; fixed 2015-06-11.
add_test (NAME GeoConvert9 COMMAND GeoConvert --input-string "5d70.0 10")
add_test (NAME GeoConvert10 COMMAND GeoConvert --input-string "5d60 10")
set_tests_properties (GeoConvert9 GeoConvert10 PROPERTIES WILL_FAIL ON)
# Check that integer(minutes) < 60 and decimal(minutes) <= 60 succeed.
# Latter used to fail with 60.; fixed 2015-06-11.
add_test (NAME GeoConvert11 COMMAND GeoConvert --input-string "5d59 10")
add_test (NAME GeoConvert12 COMMAND GeoConvert --input-string "5d60. 10")
add_test (NAME GeoConvert13 COMMAND GeoConvert --input-string "5d60.0 10")
# Check DMS::Encode does round ties to even. Fixed 2015-06-11.
if (NOT WIN32)
# DMS::Encode now uses standard library to format the number and
# sometimes this doesn't get the round to even rule right.
add_test (NAME GeoConvert14 COMMAND GeoConvert
-: -p -4 --input-string "5.25 5.75")
set_tests_properties (GeoConvert14
PROPERTIES PASS_REGULAR_EXPRESSION "05.2N 005.8E")
add_test (NAME GeoConvert15 COMMAND GeoConvert
-: -p -1 --input-string "5.03125 5.09375")
set_tests_properties (GeoConvert15
PROPERTIES PASS_REGULAR_EXPRESSION "05:01:52N 005:05:38E")
endif ()
# Check MGRS::Forward improved rounding fix, 2015-07-22
add_test (NAME GeoConvert16 COMMAND GeoConvert
-m -p 3 --input-string "38n 444140.6 3684706.3")
set_tests_properties (GeoConvert16
PROPERTIES PASS_REGULAR_EXPRESSION "38SMB4414060084706300")
# Check MGRS::Forward digit consistency fix, 2015-07-23
add_test (NAME GeoConvert17 COMMAND GeoConvert
-m -p 3 --input-string "38n 500000 63.811")
add_test (NAME GeoConvert18 COMMAND GeoConvert
-m -p 4 --input-string "38n 500000 63.811")
set_tests_properties (GeoConvert17
PROPERTIES PASS_REGULAR_EXPRESSION "38NNF0000000000063811")
set_tests_properties (GeoConvert18
PROPERTIES PASS_REGULAR_EXPRESSION "38NNF000000000000638110")
# Check prec = -6 for UPS (to check fix to Matlab mgrs_fwd, 2018-03-19)
add_test (NAME GeoConvert19 COMMAND GeoConvert
-m -p -6 --input-string "s 2746000 1515000")
add_test (NAME GeoConvert20 COMMAND GeoConvert
-m -p -5 --input-string "s 2746000 1515000")
add_test (NAME GeoConvert21 COMMAND GeoConvert
-m -p -4 --input-string "s 2746000 1515000")
set_tests_properties (GeoConvert19
PROPERTIES PASS_REGULAR_EXPRESSION "^B[\r\n]")
set_tests_properties (GeoConvert20
PROPERTIES PASS_REGULAR_EXPRESSION "^BKH[\r\n]")
set_tests_properties (GeoConvert21
PROPERTIES PASS_REGULAR_EXPRESSION "^BKH41[\r\n]")
# Check DMS::Encode round ties to even for whole degrees. Fixed 2022-05-13.
if (NOT WIN32)
# DMS::Encode now uses standard library to format the number and
# sometimes this doesn't get the round to even rule right.
add_test (NAME GeoConvert22 COMMAND GeoConvert
-p -5 --input-string "5.5 6.5")
set_tests_properties (GeoConvert22
PROPERTIES PASS_REGULAR_EXPRESSION "6 6")
add_test (NAME GeoConvert23 COMMAND GeoConvert
-p -5 -d --input-string "5.5 6.5")
set_tests_properties (GeoConvert23
PROPERTIES PASS_REGULAR_EXPRESSION "06N 006E")
endif ()
add_test (NAME GeodSolve0 COMMAND GeodSolve
-i -p 0 --input-string "40.6 -73.8 49d01'N 2d33'E")
set_tests_properties (GeodSolve0 PROPERTIES PASS_REGULAR_EXPRESSION
"53\\.47022 111\\.59367 5853226")
add_test (NAME GeodSolve1 COMMAND GeodSolve
-p 0 --input-string "40d38'23\"N 073d46'44\"W 53d30' 5850e3")
set_tests_properties (GeodSolve1 PROPERTIES PASS_REGULAR_EXPRESSION
"49\\.01467 2\\.56106 111\\.62947")
# Check fix for antipodal prolate bug found 2010-09-04
add_test (NAME GeodSolve2 COMMAND GeodSolve
-i -p 0 -e 6.4e6 -1/150 --input-string "0.07476 0 -0.07476 180")
set_tests_properties (GeodSolve2 PROPERTIES PASS_REGULAR_EXPRESSION
"90\\.00078 90\\.00078 20106193")
# Another check for similar bug
add_test (NAME GeodSolve3 COMMAND GeodSolve
-i -p 0 -e 6.4e6 -1/150 --input-string "0.1 0 -0.1 180")
set_tests_properties (GeodSolve3 PROPERTIES PASS_REGULAR_EXPRESSION
"90\\.00105 90\\.00105 20106193")
# Check fix for short line bug found 2010-05-21
add_test (NAME GeodSolve4 COMMAND GeodSolve
-i --input-string "36.493349428792 0 36.49334942879201 .0000008")
set_tests_properties (GeodSolve4 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 0\\.072")
# Check fix for point2=pole bug found 2010-05-03 (but only with long double)
add_test (NAME GeodSolve5 COMMAND GeodSolve
-p 0 --input-string "0.01777745589997 30 0 10e6")
set_tests_properties (GeodSolve5 PROPERTIES PASS_REGULAR_EXPRESSION
"90\\.00000 -150\\.00000 -?180\\.00000;90\\.00000 30\\.00000 0\\.00000")
# Check fix for volatile sbet12a bug found 2011-06-25 (gcc 4.4.4 x86 -O3)
# Found again on 2012-03-27 with tdm-mingw32 (g++ 4.6.1).
add_test (NAME GeodSolve6 COMMAND GeodSolve -i --input-string
"88.202499451857 0 -88.202499451857 179.981022032992859592")
add_test (NAME GeodSolve7 COMMAND GeodSolve -i --input-string
"89.262080389218 0 -89.262080389218 179.992207982775375662")
add_test (NAME GeodSolve8 COMMAND GeodSolve -i --input-string
"89.333123580033 0 -89.333123580032997687 179.99295812360148422")
set_tests_properties (GeodSolve6 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 20003898.214")
set_tests_properties (GeodSolve7 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 20003925.854")
set_tests_properties (GeodSolve8 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 20003926.881")
# Check fix for volatile x bug found 2011-06-25 (gcc 4.4.4 x86 -O3)
add_test (NAME GeodSolve9 COMMAND GeodSolve -i --input-string
"56.320923501171 0 -56.320923501171 179.664747671772880215")
set_tests_properties (GeodSolve9 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 19993558.287")
# Check fix for adjust tol1_ bug found 2011-06-25 (Visual Studio 10 rel
# + debug)
add_test (NAME GeodSolve10 COMMAND GeodSolve -i --input-string
"52.784459512564 0 -52.784459512563990912 179.634407464943777557")
set_tests_properties (GeodSolve10 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 19991596.095")
# Check fix for bet2 = -bet1 bug found 2011-06-25 (Visual Studio 10 rel
# + debug)
add_test (NAME GeodSolve11 COMMAND GeodSolve -i --input-string
"48.522876735459 0 -48.52287673545898293 179.599720456223079643")
set_tests_properties (GeodSolve11 PROPERTIES PASS_REGULAR_EXPRESSION
".* .* 19989144.774")
# Check fix for inverse geodesics on extreme prolate/oblate ellipsoids
# Reported 2012-08-29 Stefan Guenther <stefan.gunther@embl.de>; fixed
# 2012-10-07
add_test (NAME GeodSolve12 COMMAND GeodSolve
-i -e 89.8 -1.83 -p 1 --input-string "0 0 -10 160")
add_test (NAME GeodSolve13 COMMAND GeodSolve
-i -e 89.8 -1.83 -p 1 --input-string "0 0 -10 160" -E)
set_tests_properties (GeodSolve12 GeodSolve13
PROPERTIES PASS_REGULAR_EXPRESSION "120\\.27.* 105\\.15.* 266\\.7")
if (NOT (GEOGRAPHICLIB_PRECISION EQUAL 4 AND Boost_VERSION LESS 106000))
# mpfr (nan == 0 is true) and boost-quadmath (nan > 0 is true) have
# bugs in handling nans, so skip this test. Problems reported on
# 2015-03-31, https://svn.boost.org/trac/boost/ticket/11159 (this
# might be fixed in Boost 1.60).. MFPR C++ version 3.6.2 fixes its
# nan problem.
#
# Check fix for inverse ignoring lon12 = nan
add_test (NAME GeodSolve14 COMMAND GeodSolve -i --input-string "0 0 1 nan")
set_tests_properties (GeodSolve14 PROPERTIES PASS_REGULAR_EXPRESSION
"nan nan nan")
endif ()
# Initial implementation of Math::eatanhe was wrong for e^2 < 0. This
# checks that this is fixed.
add_test (NAME GeodSolve15 COMMAND GeodSolve
-e 6.4e6 -1/150 -f --input-string "1 2 3 4")
add_test (NAME GeodSolve16 COMMAND GeodSolve
-e 6.4e6 -1/150 -f --input-string "1 2 3 4" -E)
set_tests_properties (GeodSolve15 GeodSolve16
PROPERTIES PASS_REGULAR_EXPRESSION
"1\\..* 2\\..* 3\\..* 1\\..* 2\\..* 3\\..* 4\\..* 0\\..* 4\\..* 1\\..* 1\\..* 23700")
# Check fix for LONG_UNROLL bug found on 2015-05-07
add_test (NAME GeodSolve17 COMMAND GeodSolve
-u --input-string "40 -75 -10 2e7")
add_test (NAME GeodSolve18 COMMAND GeodSolve
-u --input-string "40 -75 -10 2e7" -E)
add_test (NAME GeodSolve19 COMMAND GeodSolve
-u -L 40 -75 -10 --input-string "2e7")
add_test (NAME GeodSolve20 COMMAND GeodSolve
-u -L 40 -75 -10 --input-string "2e7" -E)
set_tests_properties (GeodSolve17 GeodSolve18 GeodSolve19 GeodSolve20
PROPERTIES PASS_REGULAR_EXPRESSION
"-39\\.[0-9]* -254\\.[0-9]* -170\\.[0-9]*")
add_test (NAME GeodSolve21 COMMAND GeodSolve
--input-string "40 -75 -10 2e7")
add_test (NAME GeodSolve22 COMMAND GeodSolve
--input-string "40 -75 -10 2e7" -E)
add_test (NAME GeodSolve23 COMMAND GeodSolve
-L 40 -75 -10 --input-string "2e7")
add_test (NAME GeodSolve24 COMMAND GeodSolve
-L 40 -75 -10 --input-string "2e7" -E)
set_tests_properties (GeodSolve21 GeodSolve22 GeodSolve23 GeodSolve24
PROPERTIES PASS_REGULAR_EXPRESSION "-39\\.[0-9]* 105\\.[0-9]* -170\\.[0-9]*")
# Check fix for inaccurate rounding in DMS::Decode, e.g., verify that
# 7:33:36 = 7.56; fixed on 2015-06-11.
add_test (NAME GeodSolve25 COMMAND GeodSolve
-p 6 --input-string "0 0 7:33:36-7.56 10001965")
set_tests_properties (GeodSolve25 PROPERTIES PASS_REGULAR_EXPRESSION
"89\\.9[0-9]* 0\\.00000000000 0\\.00000000000")
# Check 0/0 problem with area calculation on sphere 2015-09-08
add_test (NAME GeodSolve26 COMMAND GeodSolve
-i -f -e 6.4e6 0 --input-string "1 2 3 4")
add_test (NAME GeodSolve27 COMMAND GeodSolve
-i -f -e 6.4e6 0 --input-string "1 2 3 4" -E)
set_tests_properties (GeodSolve26 GeodSolve27
PROPERTIES PASS_REGULAR_EXPRESSION " 49911046115")
# Check for bad placement of assignment of r.a12 with |f| > 0.01 (bug in
# Java implementation fixed on 2015-05-19).
add_test (NAME GeodSolve28 COMMAND GeodSolve
-f -e 6.4e6 0.1 -p 3 --input-string "1 2 10 5e6")
set_tests_properties (GeodSolve28 PROPERTIES PASS_REGULAR_EXPRESSION
" 48.55570690 ")
# Check longitude unrolling with inverse calculation 2015-09-16
add_test (NAME GeodSolve29 COMMAND GeodSolve
-i -f -p 0 --input-string "0 539 0 181")
add_test (NAME GeodSolve30 COMMAND GeodSolve
-i -f -p 0 --input-string "0 539 0 181" -E)
set_tests_properties (GeodSolve29 GeodSolve30
PROPERTIES PASS_REGULAR_EXPRESSION
"0\\..* 179\\..* 90\\..* 0\\..* -179\\..* 90\\..* 222639 ")
add_test (NAME GeodSolve31 COMMAND GeodSolve
-i -f -p 0 --input-string "0 539 0 181" -u)
add_test (NAME GeodSolve32 COMMAND GeodSolve
-i -f -p 0 --input-string "0 539 0 181" -u -E)
set_tests_properties (GeodSolve31 GeodSolve32
PROPERTIES PASS_REGULAR_EXPRESSION
"0\\..* 539\\..* 90\\..* 0\\..* 541\\..* 90\\..* 222639 ")
# Check max(-0.0,+0.0) issues 2015-08-22 (triggered by bugs in Octave --
# sind(-0.0) = +0.0 -- and in some version of Visual Studio --
# fmod(-0.0, 360.0) = +0.0.
add_test (NAME GeodSolve33 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179")
add_test (NAME GeodSolve34 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179" -E)
add_test (NAME GeodSolve35 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179.5")
add_test (NAME GeodSolve36 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179.5" -E)
add_test (NAME GeodSolve37 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180")
add_test (NAME GeodSolve38 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180" -E)
add_test (NAME GeodSolve39 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180")
add_test (NAME GeodSolve40 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180" -E)
add_test (NAME GeodSolve41 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179" -e 6.4e6 0)
add_test (NAME GeodSolve42 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179" -e 6.4e6 0 -E)
add_test (NAME GeodSolve43 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180" -e 6.4e6 0)
add_test (NAME GeodSolve44 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180" -e 6.4e6 0 -E)
add_test (NAME GeodSolve45 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180" -e 6.4e6 0)
add_test (NAME GeodSolve46 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180" -e 6.4e6 0 -E)
add_test (NAME GeodSolve47 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179" -e 6.4e6 -1/300)
add_test (NAME GeodSolve48 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 179" -e 6.4e6 -1/300 -E)
add_test (NAME GeodSolve49 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180" -e 6.4e6 -1/300)
add_test (NAME GeodSolve50 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0 180" -e 6.4e6 -1/300 -E)
add_test (NAME GeodSolve51 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0.5 180" -e 6.4e6 -1/300)
add_test (NAME GeodSolve52 COMMAND GeodSolve
-i -p 0 --input-string "0 0 0.5 180" -e 6.4e6 -1/300 -E)
add_test (NAME GeodSolve53 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180" -e 6.4e6 -1/300)
add_test (NAME GeodSolve54 COMMAND GeodSolve
-i -p 0 --input-string "0 0 1 180" -e 6.4e6 -1/300 -E)
set_tests_properties (GeodSolve33 GeodSolve34
PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00000 90\\.00000 19926189")
set_tests_properties (GeodSolve35 GeodSolve36
PROPERTIES PASS_REGULAR_EXPRESSION "55\\.96650 124\\.03350 19980862")
set_tests_properties (GeodSolve37 GeodSolve38
PROPERTIES PASS_REGULAR_EXPRESSION "0\\.00000 -?180\\.00000 20003931")
set_tests_properties (GeodSolve39 GeodSolve40
PROPERTIES PASS_REGULAR_EXPRESSION "0\\.00000 -?180\\.00000 19893357")
set_tests_properties (GeodSolve41 GeodSolve42
PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00000 90\\.00000 19994492")
set_tests_properties (GeodSolve43 GeodSolve44
PROPERTIES PASS_REGULAR_EXPRESSION "0\\.00000 -?180\\.00000 20106193")
set_tests_properties (GeodSolve45 GeodSolve46
PROPERTIES PASS_REGULAR_EXPRESSION "0\\.00000 -?180\\.00000 19994492")
set_tests_properties (GeodSolve47 GeodSolve48
PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00000 90\\.00000 19994492")
set_tests_properties (GeodSolve49 GeodSolve50
PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00000 90\\.00000 20106193")
set_tests_properties (GeodSolve51 GeodSolve52
PROPERTIES PASS_REGULAR_EXPRESSION "33\\.02493 146\\.97364 20082617")
set_tests_properties (GeodSolve53 GeodSolve54
PROPERTIES PASS_REGULAR_EXPRESSION "0\\.00000 -?180\\.00000 20027270")
if (NOT (GEOGRAPHICLIB_PRECISION EQUAL 4 AND Boost_VERSION LESS 106000))
# Check fix for nan + point on equator or pole not returning all nans in
# Geodesic::Inverse, found 2015-09-23.
add_test (NAME GeodSolve55 COMMAND GeodSolve -i --input-string "nan 0 0 90")
add_test (NAME GeodSolve56 COMMAND GeodSolve
-i --input-string "nan 0 0 90" -E)
add_test (NAME GeodSolve57 COMMAND GeodSolve -i --input-string "nan 0 90 9")
add_test (NAME GeodSolve58 COMMAND GeodSolve
-i --input-string "nan 0 90 9" -E)
set_tests_properties (GeodSolve55 GeodSolve56 GeodSolve57 GeodSolve58
PROPERTIES PASS_REGULAR_EXPRESSION "nan nan nan")
endif ()
# Check for points close with longitudes close to 180 deg apart.
add_test (NAME GeodSolve59 COMMAND GeodSolve
-i -p 9 --input-string "5 0.00000000000001 10 180")
add_test (NAME GeodSolve60 COMMAND GeodSolve
-i -p 9 --input-string "5 0.00000000000001 10 180" -E)
set_tests_properties (GeodSolve59 GeodSolve60
PROPERTIES PASS_REGULAR_EXPRESSION
# Correct values: 0.000000000000037 179.999999999999963 18345191.1743327133
"0\\.0000000000000[34] 179\\.9999999999999[5-7] 18345191\\.17433271[2-6]")
# Make sure small negative azimuths are west-going
add_test (NAME GeodSolve61 COMMAND GeodSolve
-u -p 0 --input-string "45 0 -0.000000000000000003 1e7")
add_test (NAME GeodSolve62 COMMAND GeodSolve
-u -p 0 -I 45 0 80 -0.000000000000000003 --input-string 1e7)
add_test (NAME GeodSolve63 COMMAND GeodSolve
-u -p 0 --input-string "45 0 -0.000000000000000003 1e7" -E)
add_test (NAME GeodSolve64 COMMAND GeodSolve
-u -p 0 -I 45 0 80 -0.000000000000000003 --input-string 1e7 -E)
set_tests_properties (GeodSolve61 GeodSolve62 GeodSolve63 GeodSolve64
PROPERTIES PASS_REGULAR_EXPRESSION "45\\.30632 -180\\.00000 -?180\\.00000")
# Check for bug in east-going check in GeodesicLine (needed to check for
# sign of 0) and sign error in area calculation due to a bogus override
# of the code for alp12. Found/fixed on 2015-12-19.
add_test (NAME GeodSolve65 COMMAND GeodSolve
-I 30 -0.000000000000000001 -31 180 -f -u -p 0 --input-string "1e7;2e7")
add_test (NAME GeodSolve66 COMMAND GeodSolve
-I 30 -0.000000000000000001 -31 180 -f -u -p 0 --input-string "1e7;2e7" -E)
set_tests_properties (GeodSolve65 GeodSolve66
PROPERTIES PASS_REGULAR_EXPRESSION
"30\\.00000 -0\\.00000 -?180\\.00000 -60\\.23169 -0\\.00000 -?180\\.00000 10000000 90\\.06544 6363636 -0\\.0012834 0\\.0013749 0[\r\n]+30\\.00000 -0\\.00000 -?180\\.00000 -30\\.03547 -180\\.00000 -0\\.00000 20000000 179\\.96459 54342 -1\\.0045592 -0\\.9954339 127516405431022")
# Check for InverseLine if line is slightly west of S and that s13 is
# correctly set.
add_test (NAME GeodSolve67 COMMAND GeodSolve
-u -p 0 -I -5 -0.000000000000002 -10 180 --input-string 2e7)
add_test (NAME GeodSolve68 COMMAND GeodSolve
-u -p 0 -I -5 -0.000000000000002 -10 180 --input-string 2e7 -E)
set_tests_properties (GeodSolve67 GeodSolve68
PROPERTIES PASS_REGULAR_EXPRESSION "4\\.96445 -180\\.00000 -0\\.00000")
add_test (NAME GeodSolve69 COMMAND GeodSolve
-u -p 0 -I -5 -0.000000000000002 -10 180 --input-string 0.5 -F)
add_test (NAME GeodSolve70 COMMAND GeodSolve
-u -p 0 -I -5 -0.000000000000002 -10 180 --input-string 0.5 -F -E)
set_tests_properties (GeodSolve69 GeodSolve70
PROPERTIES PASS_REGULAR_EXPRESSION "-87\\.52461 -0\\.00000 -180\\.00000")
# Check that DirectLine sets s13.
add_test (NAME GeodSolve71 COMMAND GeodSolve
-D 1 2 45 1e7 -p 0 --input-string 0.5 -F)
add_test (NAME GeodSolve72 COMMAND GeodSolve
-D 1 2 45 1e7 -p 0 --input-string 0.5 -F)
set_tests_properties (GeodSolve71 GeodSolve72
PROPERTIES PASS_REGULAR_EXPRESSION "30\\.92625 37\\.54640 55\\.43104")
# Check for backwards from the pole bug reported by Anon on 2016-02-13.
# This only affected the Java implementation. It was introduced in Java
# version 1.44 and fixed in 1.46-SNAPSHOT on 2016-01-17.
# Also the + sign on azi2 is a check on the normalizing of azimuths
# (converting -0.0 to +0.0).
add_test (NAME GeodSolve73 COMMAND GeodSolve
-p 0 --input-string "90 10 180 -1e6")
set_tests_properties (GeodSolve73
PROPERTIES PASS_REGULAR_EXPRESSION "81\\.04623 -170\\.00000 0\\.00000")
# Check fix for inaccurate areas, bug introduced in v1.46, fixed
# 2015-10-16.
add_test (NAME GeodSolve74 COMMAND GeodSolve
-i -p 10 -f --input-string "54.1589 15.3872 54.1591 15.3877")
set_tests_properties (GeodSolve74
PROPERTIES PASS_REGULAR_EXPRESSION
# Exact area is 286698586.30197
"54.* 15.* 55\\.72311035.* 54.* 15.* 55\\.72351567.* 39\\.52768638.* 0\\.00035549.* 39\\.52768638.* 0\\.99999999.* 0\\.99999999.* 286698586\\.302")
add_test (NAME GeodSolve75 COMMAND GeodSolve
-i -p 10 -f --input-string "54.1589 15.3872 54.1591 15.3877" -E)
set_tests_properties (GeodSolve75
PROPERTIES PASS_REGULAR_EXPRESSION
# Exact area is 286698586.30197, but -E calculation is less accurate
"54.* 15.* 55\\.72311035.* 54.* 15.* 55\\.72351567.* 39\\.52768638.* 0\\.00035549.* 39\\.52768638.* 0\\.99999999.* 0\\.99999999.* 286698586\\.(29[89]|30[0-5])")
# The distance from Wellington and Salamanca (a classic failure of Vincenty)
add_test (NAME GeodSolve76 COMMAND GeodSolve
-i -p 6 --input-string "41:19S 174:49E 40:58N 5:30W")
add_test (NAME GeodSolve77 COMMAND GeodSolve
-i -p 6 --input-string "41:19S 174:49E 40:58N 5:30W" -E)
set_tests_properties (GeodSolve76 GeodSolve77
PROPERTIES PASS_REGULAR_EXPRESSION
"160\\.39137649664 19\\.50042925176 19960543\\.857179")
# An example where the NGS calculator fails to converge
add_test (NAME GeodSolve78 COMMAND GeodSolve
-i -p 6 --input-string "27.2 0 -27.1 179.5")
add_test (NAME GeodSolve79 COMMAND GeodSolve
-i -p 6 --input-string "27.2 0 -27.1 179.5" -E)
set_tests_properties (GeodSolve78 GeodSolve79
PROPERTIES PASS_REGULAR_EXPRESSION
"45\\.82468716758 134\\.22776532670 19974354\\.765767")
# Some tests to add code coverage: computing scale in special cases
add_test (NAME GeodSolve80 COMMAND GeodSolve
-i --input-string "0 0 0 90" -f)
set_tests_properties (GeodSolve80 PROPERTIES PASS_REGULAR_EXPRESSION
" -0\\.0052842753 -0\\.0052842753 ")
add_test (NAME GeodSolve81 COMMAND GeodSolve
-i --input-string "0 0 0.000001 0.000001" -f)
set_tests_properties (GeodSolve81 PROPERTIES PASS_REGULAR_EXPRESSION
" 0\\.157 1\\.0000000000 1\\.0000000000 0")
# Tests to add code coverage: zero length geodesics
add_test (NAME GeodSolve82 COMMAND GeodSolve
-i --input-string "20.001 0 20.001 0" -f)
set_tests_properties (GeodSolve82 PROPERTIES PASS_REGULAR_EXPRESSION
"20\\.0010* 0\\.0* 180\\.0* 20\\.0010* 0\\.0* 180\\.0* 0\\.0* 0\\.0* 0\\.0* 1\\.0* 1\\.0* -?0")
add_test (NAME GeodSolve83 COMMAND GeodSolve
-i --input-string "90 0 90 180" -f)
set_tests_properties (GeodSolve83 PROPERTIES PASS_REGULAR_EXPRESSION
"90\\.0* 0\\.0* 0\\.0* 90\\.0* 180\\.0* 180\\.0* 0\\.0* 0\\.0* 0\\.0* 1\\.0* 1\\.0* 127516405431022")
# Tests for python implementation to check fix for range errors with
# {fmod,sin,cos}(inf).
add_test (NAME GeodSolve84 COMMAND GeodSolve
--input-string "0 0 90 inf")
add_test (NAME GeodSolve85 COMMAND GeodSolve
--input-string "0 0 90 nan")
add_test (NAME GeodSolve86 COMMAND GeodSolve
--input-string "0 0 inf 1000")
add_test (NAME GeodSolve87 COMMAND GeodSolve
--input-string "0 0 nan 1000")
add_test (NAME GeodSolve88 COMMAND GeodSolve
--input-string "0 inf 90 1000")
add_test (NAME GeodSolve89 COMMAND GeodSolve
--input-string "0 nan 90 1000")
add_test (NAME GeodSolve90 COMMAND GeodSolve
--input-string "inf 0 90 1000")
add_test (NAME GeodSolve91 COMMAND GeodSolve
--input-string "nan 0 90 1000")
set_tests_properties (GeodSolve84 GeodSolve85 GeodSolve86 GeodSolve87
GeodSolve91 PROPERTIES PASS_REGULAR_EXPRESSION "nan nan nan")
set_tests_properties (GeodSolve88 GeodSolve89 PROPERTIES PASS_REGULAR_EXPRESSION
"0\\.0* nan 90\\.0*")
set_tests_properties (GeodSolve90 PROPERTIES WILL_FAIL ON)
# Check fix for inaccurate hypot with python 3.[89]. Problem reported
# by agdhruv https://github.com/geopy/geopy/issues/466 ; see
# https://bugs.python.org/issue43088
add_test (NAME GeodSolve92 COMMAND GeodSolve
-i --input-string "37.757540000000006 -122.47018 37.75754 -122.470177")
add_test (NAME GeodSolve93 COMMAND GeodSolve
-i --input-string "37.757540000000006 -122.47018 37.75754 -122.470177" -E)
set_tests_properties (GeodSolve92 GeodSolve93 PROPERTIES PASS_REGULAR_EXPRESSION
"89\\.9999992. 90\\.000001[01]. 0\\.264")
# Check fix for lat2 = nan being treated as lat2 = 0 (bug found 2021-07-26)
add_test (NAME GeodSolve94 COMMAND GeodSolve
-i --input-string "0 0 nan 90")
add_test (NAME GeodSolve95 COMMAND GeodSolve
-i --input-string "0 0 nan 90" -E)
set_tests_properties (GeodSolve94 GeodSolve95 PROPERTIES PASS_REGULAR_EXPRESSION
"nan nan nan")
# Failure with long doubles found with test case from Nowak + Nowak Da
# Costa (2022). Problem was using somg12 > 1 as a test that it needed
# to be set when roundoff could result in somg12 slightly bigger that 1.
# Found + fixed 2022-03-30.
add_test (NAME GeodSolve96 COMMAND GeodSolve
-i -f -e 6378137 1/298.257222101
--input-string "0 0 60.0832522871723 89.8492185074635")
add_test (NAME GeodSolve97 COMMAND GeodSolve
-i -f -e 6378137 1/298.257222101
--input-string "0 0 60.0832522871723 89.8492185074635")
set_tests_properties (GeodSolve96 GeodSolve97 PROPERTIES PASS_REGULAR_EXPRESSION
".* 42426932221845")
# Area of on high eccentricity n = 0.94 ellipsoid. This is the most
# oblate case that Nowak + Nowak Da Costa (2022) treats (convergence
# with kmax = 18504). High precision result is 5910062452739.93899501;
# Accept xxx.930 thru xxx.949
add_test (NAME GeodSolve98 COMMAND GeodSolve
-E -a -u -f -e 6.4e6 188/194 -p 10 --input-string "0 0 45 90")
set_tests_properties (GeodSolve98 PROPERTIES PASS_REGULAR_EXPRESSION
".* 5910062452739\\.9[34].")
# Check fix for pole-encircling bug found 2011-03-16
add_test (NAME Planimeter0 COMMAND Planimeter
--input-string "89 0;89 90;89 180;89 270")
add_test (NAME Planimeter1 COMMAND Planimeter
-r --input-string "-89 0;-89 90;-89 180;-89 270")
add_test (NAME Planimeter2 COMMAND Planimeter
--input-string "0 -1;-1 0;0 1;1 0")
add_test (NAME Planimeter3 COMMAND Planimeter --input-string "90 0; 0 0; 0 90")
add_test (NAME Planimeter4 COMMAND Planimeter
-l --input-string "90 0; 0 0; 0 90")
set_tests_properties (Planimeter0 Planimeter1
PROPERTIES PASS_REGULAR_EXPRESSION
"4 631819\\.8745[0-9]+ 2495230567[78]\\.[0-9]+")
set_tests_properties (Planimeter2 PROPERTIES PASS_REGULAR_EXPRESSION
"4 627598\\.2731[0-9]+ 24619419146.[0-9]+")
set_tests_properties (Planimeter3 PROPERTIES PASS_REGULAR_EXPRESSION
"3 30022685\\.[0-9]+ 63758202715511\\.[0-9]+")
set_tests_properties (Planimeter4 PROPERTIES PASS_REGULAR_EXPRESSION
"3 20020719\\.[0-9]+")
# Check fix for Planimeter pole crossing bug found 2011-06-24
add_test (NAME Planimeter5 COMMAND Planimeter
--input-string "89 0.1;89 90.1;89 -179.9")
set_tests_properties (Planimeter5 PROPERTIES PASS_REGULAR_EXPRESSION
"3 539297\\.[0-9]+ 1247615283[89]\\.[0-9]+")
# Check fix for Planimeter lon12 rounding bug found 2012-12-03
add_test (NAME Planimeter6 COMMAND Planimeter
-p 8 --input-string "9 -0.00000000000001;9 180;9 0")
add_test (NAME Planimeter7 COMMAND Planimeter
-p 8 --input-string "9 0.00000000000001;9 0;9 180")
add_test (NAME Planimeter8 COMMAND Planimeter
-p 8 --input-string "9 0.00000000000001;9 180;9 0")
add_test (NAME Planimeter9 COMMAND Planimeter
-p 8 --input-string "9 -0.00000000000001;9 0;9 180")
set_tests_properties (Planimeter6 Planimeter7 Planimeter8 Planimeter9
PROPERTIES PASS_REGULAR_EXPRESSION "3 36026861\\.[0-9]+ -?0.0[0-9]+")
# Area of Wyoming
add_test (NAME Planimeter10 COMMAND Planimeter -R
--input-string "41N 111:3W; 41N 104:3W; 45N 104:3W; 45N 111:3W")
set_tests_properties (Planimeter10 PROPERTIES PASS_REGULAR_EXPRESSION
"4 2029616\\.[0-9]+ 2535883763..\\.")
# Area of arctic circle
add_test (NAME Planimeter11 COMMAND Planimeter
-R --input-string "66:33:44 0; 66:33:44 180; 66:33:44 360")
set_tests_properties (Planimeter11 PROPERTIES PASS_REGULAR_EXPRESSION
"3 15985058\\.[0-9]+ 212084182523..\\.")
add_test (NAME Planimeter12 COMMAND Planimeter
--input-string "66:33:44 0; 66:33:44 180; 66:33:44 360")
set_tests_properties (Planimeter12 PROPERTIES PASS_REGULAR_EXPRESSION
"3 10465729\\.[0-9]+ -?0.0")
# Reverse area of arctic circle
add_test (NAME Planimeter11r COMMAND Planimeter
-R --input-string "66:33:44 -0; 66:33:44 -180; 66:33:44 -360")
set_tests_properties (Planimeter11r PROPERTIES PASS_REGULAR_EXPRESSION
"3 15985058\\.[0-9]+ -212084182523..\\.")
add_test (NAME Planimeter12r COMMAND Planimeter
--input-string "66:33:44 -0; 66:33:44 -180; 66:33:44 -360")
set_tests_properties (Planimeter12r PROPERTIES PASS_REGULAR_EXPRESSION
"3 10465729\\.[0-9]+ -?0.0")
# Check encircling pole twice
add_test (NAME Planimeter13 COMMAND Planimeter
--input-string "89 -360; 89 -240; 89 -120; 89 0; 89 120; 89 240")
# Check -w fix for Planimeter (bug found/fixed 2016-01-19)
add_test (NAME Planimeter14 COMMAND Planimeter
--input-string "-360 89;-240 89;-120 89;0 89;120 89;240 89" -w)
set_tests_properties (Planimeter13 Planimeter14
PROPERTIES PASS_REGULAR_EXPRESSION "6 1160741\\..* 32415230256\\.")
# Some tests to add code coverage: all combinations of -r and -s
add_test (NAME Planimeter15 COMMAND Planimeter
--input-string "2 1;1 2;3 3")
add_test (NAME Planimeter16 COMMAND Planimeter
--input-string "2 1;1 2;3 3" -s)
add_test (NAME Planimeter17 COMMAND Planimeter
--input-string "2 1;1 2;3 3" -r)
add_test (NAME Planimeter18 COMMAND Planimeter
--input-string "2 1;1 2;3 3" -r -s)
set_tests_properties (Planimeter15 Planimeter16
PROPERTIES PASS_REGULAR_EXPRESSION
" 18454562325\\.5") # more digits 18454562325.45119
set_tests_properties (Planimeter17 PROPERTIES PASS_REGULAR_EXPRESSION
" -18454562325\\.5")
set_tests_properties (Planimeter18 PROPERTIES PASS_REGULAR_EXPRESSION
" 510047167161763\\.[01]") # 510065621724088.5093-18454562325.45119
# Some tests to add code coverage: degerate polygons
add_test (NAME Planimeter19 COMMAND Planimeter --input-string "1 1")
set_tests_properties (Planimeter19 PROPERTIES PASS_REGULAR_EXPRESSION
"1 0\\.0* 0\\.0")
add_test (NAME Planimeter20 COMMAND Planimeter --input-string "1 1" -l)
set_tests_properties (Planimeter20 PROPERTIES PASS_REGULAR_EXPRESSION
"1 0\\.0*")
# Some tests to add code coverage: multiple circlings of pole
set (_t "45 60;45 180;45 -60")
# r = 39433884866571.4277 = Area for one circuit
# a0 = 510065621724088.5093 = Ellipsoid area
add_test (NAME Planimeter21 COMMAND Planimeter
--input-string "${_t};${_t};${_t}")
add_test (NAME Planimeter22 COMMAND Planimeter
--input-string "${_t};${_t};${_t}" -s)
add_test (NAME Planimeter23 COMMAND Planimeter
--input-string "${_t};${_t};${_t}" -r)
add_test (NAME Planimeter24 COMMAND Planimeter
--input-string "${_t};${_t};${_t}" -r -s)
set_tests_properties (Planimeter21 Planimeter22 PROPERTIES
PASS_REGULAR_EXPRESSION " 118301654599714\\.[2-5]") # 3*r
set_tests_properties (Planimeter23 PROPERTIES
PASS_REGULAR_EXPRESSION " -118301654599714\\.[2-5]") # -3*r
set_tests_properties (Planimeter24 PROPERTIES
PASS_REGULAR_EXPRESSION " 391763967124374\\.[0-3]") # -3*r+a0
add_test (NAME Planimeter25 COMMAND Planimeter
--input-string "${_t};${_t};${_t};${_t}")
add_test (NAME Planimeter26 COMMAND Planimeter
--input-string "${_t};${_t};${_t};${_t}" -s)
add_test (NAME Planimeter27 COMMAND Planimeter
--input-string "${_t};${_t};${_t};${_t}" -r)
add_test (NAME Planimeter28 COMMAND Planimeter
--input-string "${_t};${_t};${_t};${_t}" -r -s)
# BUG (found 2018-02-32)! In version 1.49, Planimeter2[56] and
# Planimeter27 returned 4*r-a0 and -4*r+a0, resp. Fixed in 1.50 to
# return +/-4*r
set_tests_properties (Planimeter25 Planimeter26 PROPERTIES
PASS_REGULAR_EXPRESSION " 157735539466285\\.[6-9]") # 4*r
set_tests_properties (Planimeter27 PROPERTIES
PASS_REGULAR_EXPRESSION " -157735539466285\\.[6-9]") # -4*r
set_tests_properties (Planimeter28 PROPERTIES
PASS_REGULAR_EXPRESSION " 352330082257802\\.[5-9]") # -4*r+a0
# Placeholder to implement check on AddEdge bug: AddPoint(0,0) +
# AddEdge(90, 1000) + AddEdge(0, 1000) + AddEdge(-90, 0). The area
# should be 1e6. Prior to the fix it was 1e6 - A/2, where A = ellipsoid
# area. This is now implemented in polygontest.cpp.
# add_test (NAME Planimeter29 COMMAND Planimeter ...)
# Check fix for AlbersEqualArea::Reverse bug found 2011-05-01
add_test (NAME ConicProj0 COMMAND ConicProj
-a 40d58 39d56 -l 77d45W -r --input-string "220e3 -52e3")
set_tests_properties (ConicProj0 PROPERTIES PASS_REGULAR_EXPRESSION
"39\\.95[0-9]+ -75\\.17[0-9]+ 1\\.67[0-9]+ 0\\.99[0-9]+")
# Check fix for AlbersEqualArea prolate bug found 2012-05-15
add_test (NAME ConicProj1 COMMAND ConicProj
-a 0 0 -e 6.4e6 -0.5 -r --input-string "0 8605508")
set_tests_properties (ConicProj1 PROPERTIES PASS_REGULAR_EXPRESSION
"^85\\.00")
# Check fix for LambertConformalConic::Forward bug found 2012-07-14
add_test (NAME ConicProj2 COMMAND ConicProj -c -30 -30 --input-string "-30 0")
set_tests_properties (ConicProj2 PROPERTIES PASS_REGULAR_EXPRESSION
"^-?0\\.0+ -?0\\.0+ -?0\\.0+ 1\\.0+")
# Check fixes for LambertConformalConic::Reverse overflow bugs found 2012-07-14
add_test (NAME ConicProj3 COMMAND ConicProj
-r -c 0 0 --input-string "1113195 -1e10")
set_tests_properties (ConicProj3 PROPERTIES PASS_REGULAR_EXPRESSION
"^-90\\.0+ 10\\.00[0-9]+ ")
add_test (NAME ConicProj4 COMMAND ConicProj
-r -c 0 0 --input-string "1113195 inf")
set_tests_properties (ConicProj4 PROPERTIES PASS_REGULAR_EXPRESSION
"^90\\.0+ 10\\.00[0-9]+ ")
add_test (NAME ConicProj5 COMMAND ConicProj
-r -c 45 45 --input-string "0 -1e100")
set_tests_properties (ConicProj5 PROPERTIES PASS_REGULAR_EXPRESSION
"^-90\\.0+ -?0\\.00[0-9]+ ")
add_test (NAME ConicProj6 COMMAND ConicProj
-r -c 45 45 --input-string "0 -inf")
set_tests_properties (ConicProj6 PROPERTIES PASS_REGULAR_EXPRESSION
"^-90\\.0+ -?0\\.00[0-9]+ ")
add_test (NAME ConicProj7 COMMAND ConicProj
-r -c 90 90 --input-string "0 -1e150")
set_tests_properties (ConicProj7 PROPERTIES PASS_REGULAR_EXPRESSION
"^-90\\.0+ -?0\\.00[0-9]+ ")
add_test (NAME ConicProj8 COMMAND ConicProj
-r -c 90 90 --input-string "0 -inf")
set_tests_properties (ConicProj8 PROPERTIES PASS_REGULAR_EXPRESSION
"^-90\\.0+ -?0\\.00[0-9]+ ")
# Check fix to infinite loop in AlbersEqualArea with e^2 < -1 (f < 1-sqrt(2))
# Fixed 2021-02-22.
add_test (NAME ConicProj9 COMMAND ConicProj
-a -10 40 -e 6.4e6 -0.5 -p 0 --input-string "85 10")
set_tests_properties (ConicProj9 PROPERTIES TIMEOUT 3
PASS_REGULAR_EXPRESSION "^609861 7566522 ")
add_test (NAME CartConvert0 COMMAND CartConvert
-e 6.4e6 1/100 -r --input-string "10e3 0 1e3")
add_test (NAME CartConvert1 COMMAND CartConvert
-e 6.4e6 -1/100 -r --input-string "1e3 0 10e3")
set_tests_properties (CartConvert0 PROPERTIES PASS_REGULAR_EXPRESSION
"85\\.57[0-9]+ 0\\.0[0]+ -6334614\\.[0-9]+")
set_tests_properties (CartConvert1 PROPERTIES PASS_REGULAR_EXPRESSION
"4\\.42[0-9]+ 0\\.0[0]+ -6398614\\.[0-9]+")
# Test fix to bad meridian convergence at pole with
# TransverseMercatorExact found 2013-06-26
add_test (NAME TransverseMercatorProj0 COMMAND TransverseMercatorProj
-k 1 --input-string "90 75")
add_test (NAME TransverseMercatorProj1 COMMAND TransverseMercatorProj
-k 1 --input-string "90 75" -s)
set_tests_properties (TransverseMercatorProj0 TransverseMercatorProj1
PROPERTIES PASS_REGULAR_EXPRESSION
"^0\\.0+ 10001965\\.7293[0-9]+ 75\\.0+ 1\\.0+")
# Test fix to bad scale at pole with TransverseMercatorExact
# found 2013-06-30 (quarter meridian = 10001965.7293127228128889202m)
add_test (NAME TransverseMercatorProj2 COMMAND TransverseMercatorProj
-k 1 -r --input-string "0 10001965.7293127228")
add_test (NAME TransverseMercatorProj3 COMMAND TransverseMercatorProj
-k 1 -r --input-string "0 10001965.7293127228" -s)
set_tests_properties (TransverseMercatorProj2 TransverseMercatorProj3
PROPERTIES PASS_REGULAR_EXPRESSION
"(90\\.0+ 0\\.0+ 0\\.0+|(90\\.0+|89\\.99999999999[0-9]+) -?180\\.0+ -?180\\.0+) (1\\.0000+|0\\.9999+)")
# Generic tests for transverse Mercator added 2017-04-15 to check use of
# complex arithmetic to do Clenshaw sum.
add_test (NAME TransverseMercatorProj4 COMMAND TransverseMercatorProj
-e 6.4e6 1/150 --input-string "20 30")
add_test (NAME TransverseMercatorProj5 COMMAND TransverseMercatorProj
-e 6.4e6 1/150 --input-string "20 30" -s)
set_tests_properties (TransverseMercatorProj4 TransverseMercatorProj5
PROPERTIES PASS_REGULAR_EXPRESSION
"3266035\\.453860 2518371\\.552676 11\\.207356502141 1\\.134138960741")
add_test (NAME TransverseMercatorProj6 COMMAND TransverseMercatorProj
-e 6.4e6 1/150 --input-string "3.3e6 2.5e6" -r)
add_test (NAME TransverseMercatorProj7 COMMAND TransverseMercatorProj
-e 6.4e6 1/150 --input-string "3.3e6 2.5e6" -r -s)
set_tests_properties (TransverseMercatorProj6 TransverseMercatorProj7
PROPERTIES PASS_REGULAR_EXPRESSION
"19\\.80370996793 30\\.24919702282 11\\.214378172893 1\\.137025775759")
# Test fix to bad handling of pole by RhumbSolve -i
# Reported 2015-02-24 by Thomas Murray <thomas.murray56@gmail.com>
# Supplement with tests of fix to bad areas (nan or inf) for this case
# Reported 2018-02-08 by Natalia Sabourova <natalia.sabourova@ltu.se>
add_test (NAME RhumbSolve0 COMMAND RhumbSolve
-p 3 -i --input-string "0 0 90 0")
add_test (NAME RhumbSolve1 COMMAND RhumbSolve
-p 3 -i --input-string "0 0 90 0" -s)
# Treatment of the pole depends on the precision, so only check the area
# for doubles
if (GEOGRAPHICLIB_PRECISION EQUAL 2)
set_tests_properties (RhumbSolve0 RhumbSolve1
PROPERTIES PASS_REGULAR_EXPRESSION "^0\\.0+ 10001965\\.729 0[\r\n]")
add_test (NAME RhumbSolve2 COMMAND RhumbSolve
-p 3 -i --input-string "0 0 90 30")
add_test (NAME RhumbSolve3 COMMAND RhumbSolve
-p 3 -i --input-string "0 0 90 30" -s)
set_tests_properties (RhumbSolve2 RhumbSolve3
PROPERTIES PASS_REGULAR_EXPRESSION
"^0.41222947 10002224.609 21050634712282[\r\n]")
else ()
set_tests_properties (RhumbSolve0 RhumbSolve1
PROPERTIES PASS_REGULAR_EXPRESSION "^0\\.0+ 10001965\\.729 ")
endif ()
# Test fix to CassiniSoldner::Forward bug found 2015-06-20
add_test (NAME GeodesicProj0 COMMAND GeodesicProj
-c 0 0 -p 3 --input-string "90 80")
set_tests_properties (GeodesicProj0 PROPERTIES PASS_REGULAR_EXPRESSION
"^-?0\\.0+ [0-9]+\\.[0-9]+ 170\\.0+ ")
if (EXISTS "${_DATADIR}/geoids/egm96-5.pgm")
# Check fix for single-cell cache bug found 2010-11-23
add_test (NAME GeoidEval0 COMMAND GeoidEval
-n egm96-5 --input-string "0d1 0d1;0d4 0d4")
set_tests_properties (GeoidEval0 PROPERTIES PASS_REGULAR_EXPRESSION
"^17\\.1[56]..\n17\\.1[45]..")
endif ()
if (EXISTS "${_DATADIR}/magnetic/wmm2010.wmm")
# Test case from WMM2010_Report.pdf, Sec 1.5, pp 14-15:
# t = 2012.5, lat = -80, lon = 240, h = 100e3
add_test (NAME MagneticField0 COMMAND MagneticField
-n wmm2010 -p 10 -r --input-string "2012.5 -80 240 100e3")
add_test (NAME MagneticField1 COMMAND MagneticField
-n wmm2010 -p 10 -r -t 2012.5 --input-string "-80 240 100e3")
add_test (NAME MagneticField2 COMMAND MagneticField
-n wmm2010 -p 10 -r -c 2012.5 -80 100e3 --input-string "240")
# In third number, allow a final digit 5 (instead of correct 4) to
# accommodate Visual Studio 12 and 14. The relative difference is
# "only" 2e-15; on the other hand, this might be a lurking bug in
# these compilers. (Visual Studio 10 and 11 are OK.)
set_tests_properties (MagneticField0 MagneticField1 MagneticField2
PROPERTIES PASS_REGULAR_EXPRESSION
" 5535\\.5249148687 14765\\.3703243050 -50625\\.930547879[45] .*\n.* 20\\.4904268023 1\\.0272592716 83\\.5313962281 ")
endif ()
if (EXISTS "${_DATADIR}/magnetic/emm2015.wmm")
# Tests from EMM2015_TEST_VALUES.txt including cases of linear
# interpolation and extrapolation.
add_test (NAME MagneticField3 COMMAND MagneticField
-n emm2015 -r --input-string "2009.2 -85.9 -116.5 0")
add_test (NAME MagneticField4 COMMAND MagneticField
-n emm2015 -r -c 2009.2 -85.9 0 --input-string -116.5)
add_test (NAME MagneticField5 COMMAND MagneticField
-n emm2015 -r --input-string "2015.7 78.3 123.7 100e3")
add_test (NAME MagneticField6 COMMAND MagneticField
-n emm2015 -r -c 2015.7 78.3 100e3 --input-string 123.7)
set_tests_properties (MagneticField3 MagneticField4
PROPERTIES PASS_REGULAR_EXPRESSION
"79\\.70 -72\\.74 16532\\.1 2956\\.1 16265\\.7 -53210\\.7 55719\\.7\n-0\\.1. 0\\.0. 13\\.1 34\\.1 7\\.1 81\\.7 -74\\.1")
set_tests_properties (MagneticField5 MagneticField6
PROPERTIES PASS_REGULAR_EXPRESSION
"-8\\.73 86\\.82 3128\\.9 3092\\.6 -474\\.7 56338\\.9 56425\\.8\n-0\\.2. 0\\.0. -20\\.7 -22\\.3 -9\\.2 26\\.5 25\\.3")
endif ()
if (EXISTS "${_DATADIR}/gravity/egm2008.egm")
# Verify no overflow at poles with high degree model
add_test (NAME Gravity0 COMMAND Gravity
-n egm2008 -p 6 --input-string "90 110 0")
set_tests_properties (Gravity0 PROPERTIES PASS_REGULAR_EXPRESSION
"-0\\.000146 0\\.000078 -9\\.832294")
# Check fix for invR bug in GravityCircle found by Mathieu Peyrega on
# 2013-04-09
add_test (NAME Gravity1 COMMAND Gravity
-n egm2008 -A -c -18 4000 --input-string "-86")
set_tests_properties (Gravity1 PROPERTIES PASS_REGULAR_EXPRESSION
"-7\\.438 1\\.305 -1\\.563")
add_test (NAME Gravity2 COMMAND Gravity
-n egm2008 -D -c -18 4000 --input-string "-86")
set_tests_properties (Gravity2 PROPERTIES PASS_REGULAR_EXPRESSION
"7\\.404 -6\\.168 7\\.616")
endif ()
if (EXISTS "${_DATADIR}/gravity/grs80.egm")
# Check close to zero gravity in geostationary orbit
add_test (NAME Gravity3 COMMAND Gravity
-p 3 -n grs80 --input-string "0 123 35786e3")
set_tests_properties (Gravity3 PROPERTIES PASS_REGULAR_EXPRESSION
"^-?0\\.000 -?0\\.000 -?0.000")
endif ()

View File

@@ -0,0 +1,8 @@
#
# Makefile.am
#
# Copyright (C) 2022, Charles Karney <charles@karney.com>
TEST_FILES = geodtest.cpp signtest.cpp polygontest.cpp
EXTRA_DIST = CMakeLists.txt $(TEST_FILES)

View File

@@ -0,0 +1,221 @@
/**
* \file geodtest.cpp
* \brief Test random geodesic problems
*
* Copyright (c) Charles Karney (2022) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
**********************************************************************/
#include <iostream>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicExact.hpp>
using namespace std;
using namespace GeographicLib;
typedef Math::real T;
static int checkEquals(T x, T y, T d) {
if (fabs(x - y) <= d)
return 0;
cout << "checkEquals fails: " << x << " != " << y << " +/- " << d << "\n";
return 1;
}
static const int ncases = 20;
static const T testcases[ncases][12] = {
{35.60777, -139.44815, 111.098748429560326,
-11.17491, -69.95921, 129.289270889708762,
8935244.5604818305, 80.50729714281974, 6273170.2055303837,
0.16606318447386067, 0.16479116945612937, 12841384694976.432},
{55.52454, 106.05087, 22.020059880982801,
77.03196, 197.18234, 109.112041110671519,
4105086.1713924406, 36.892740690445894, 3828869.3344387607,
0.80076349608092607, 0.80101006984201008, 61674961290615.615},
{-21.97856, 142.59065, -32.44456876433189,
41.84138, 98.56635, -41.84359951440466,
8394328.894657671, 75.62930491011522, 6161154.5773110616,
0.24816339233950381, 0.24930251203627892, -6637997720646.717},
{-66.99028, 112.2363, 173.73491240878403,
-12.70631, 285.90344, 2.512956620913668,
11150344.2312080241, 100.278634181155759, 6289939.5670446687,
-0.17199490274700385, -0.17722569526345708, -121287239862139.744},
{-17.42761, 173.34268, -159.033557661192928,
-15.84784, 5.93557, -20.787484651536988,
16076603.1631180673, 144.640108810286253, 3732902.1583877189,
-0.81273638700070476, -0.81299800519154474, 97825992354058.708},
{32.84994, 48.28919, 150.492927788121982,
-56.28556, 202.29132, 48.113449399816759,
16727068.9438164461, 150.565799985466607, 3147838.1910180939,
-0.87334918086923126, -0.86505036767110637, -72445258525585.010},
{6.96833, 52.74123, 92.581585386317712,
-7.39675, 206.17291, 90.721692165923907,
17102477.2496958388, 154.147366239113561, 2772035.6169917581,
-0.89991282520302447, -0.89986892177110739, -1311796973197.995},
{-50.56724, -16.30485, -105.439679907590164,
-33.56571, -94.97412, -47.348547835650331,
6455670.5118668696, 58.083719495371259, 5409150.7979815838,
0.53053508035997263, 0.52988722644436602, 41071447902810.047},
{-58.93002, -8.90775, 140.965397902500679,
-8.91104, 133.13503, 19.255429433416599,
11756066.0219864627, 105.755691241406877, 6151101.2270708536,
-0.26548622269867183, -0.27068483874510741, -86143460552774.735},
{-68.82867, -74.28391, 93.774347763114881,
-50.63005, -8.36685, 34.65564085411343,
3956936.926063544, 35.572254987389284, 3708890.9544062657,
0.81443963736383502, 0.81420859815358342, -41845309450093.787},
{-10.62672, -32.0898, -86.426713286747751,
5.883, -134.31681, -80.473780971034875,
11470869.3864563009, 103.387395634504061, 6184411.6622659713,
-0.23138683500430237, -0.23155097622286792, 4198803992123.548},
{-21.76221, 166.90563, 29.319421206936428,
48.72884, 213.97627, 43.508671946410168,
9098627.3986554915, 81.963476716121964, 6299240.9166992283,
0.13965943368590333, 0.14152969707656796, 10024709850277.476},
{-19.79938, -174.47484, 71.167275780171533,
-11.99349, -154.35109, 65.589099775199228,
2319004.8601169389, 20.896611684802389, 2267960.8703918325,
0.93427001867125849, 0.93424887135032789, -3935477535005.785},
{-11.95887, -116.94513, 92.712619830452549,
4.57352, 7.16501, 78.64960934409585,
13834722.5801401374, 124.688684161089762, 5228093.177931598,
-0.56879356755666463, -0.56918731952397221, -9919582785894.853},
{-87.85331, 85.66836, -65.120313040242748,
66.48646, 16.09921, -4.888658719272296,
17286615.3147144645, 155.58592449699137, 2635887.4729110181,
-0.90697975771398578, -0.91095608883042767, 42667211366919.534},
{1.74708, 128.32011, -101.584843631173858,
-11.16617, 11.87109, -86.325793296437476,
12942901.1241347408, 116.650512484301857, 5682744.8413270572,
-0.44857868222697644, -0.44824490340007729, 10763055294345.653},
{-25.72959, -144.90758, -153.647468693117198,
-57.70581, -269.17879, -48.343983158876487,
9413446.7452453107, 84.664533838404295, 6356176.6898881281,
0.09492245755254703, 0.09737058264766572, 74515122850712.444},
{-41.22777, 122.32875, 14.285113402275739,
-7.57291, 130.37946, 10.805303085187369,
3812686.035106021, 34.34330804743883, 3588703.8812128856,
0.82605222593217889, 0.82572158200920196, -2456961531057.857},
{11.01307, 138.25278, 79.43682622782374,
6.62726, 247.05981, 103.708090215522657,
11911190.819018408, 107.341669954114577, 6070904.722786735,
-0.29767608923657404, -0.29785143390252321, 17121631423099.696},
{-29.47124, 95.14681, -163.779130441688382,
-27.46601, -69.15955, -15.909335945554969,
13487015.8381145492, 121.294026715742277, 5481428.9945736388,
-0.51527225545373252, -0.51556587964721788, 104679964020340.318}};
template <class G>
static int testinverse(T f = 1) {
T lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12;
T azi1a, azi2a, s12a, a12a, m12a, M12a, M21a, S12a;
const G& g = G::WGS84();
int result = 0;
for (int i = 0; i < ncases; ++i) {
int k = 0;
lat1 = testcases[i][0]; lon1 = testcases[i][1]; azi1 = testcases[i][2];
lat2 = testcases[i][3]; lon2 = testcases[i][4]; azi2 = testcases[i][5];
s12 = testcases[i][6]; a12 = testcases[i][7]; m12 = testcases[i][8];
M12 = testcases[i][9]; M21 = testcases[i][10]; S12 = testcases[i][11];
a12a = g.GenInverse(lat1, lon1, lat2, lon2, G::ALL,
s12a, azi1a, azi2a, m12a, M12a, M21a, S12a);
k += checkEquals(azi1, azi1a, 1e-13 * f);
k += checkEquals(azi2, azi2a, 1e-13 * f);
k += checkEquals(s12, s12a, 1e-8 * f);
k += checkEquals(a12, a12a, 1e-13 * f);
k += checkEquals(m12, m12a, 1e-8 * f);
k += checkEquals(M12, M12a, 1e-15 * f);
k += checkEquals(M21, M21a, 1e-15 * f);
k += checkEquals(S12, S12a, 0.1 * f);
if (k) cout << "testinverse failure: case " << i << "\n";
result += k;
}
return result;
}
template <class G>
static int testdirect(T f = 1) {
T lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12;
T lat2a, lon2a, azi2a, s12a, a12a, m12a, M12a, M21a, S12a;
const G& g = G::WGS84();
int result = 0;
for (int i = 0; i < ncases; ++i) {
int k = 0;
lat1 = testcases[i][0]; lon1 = testcases[i][1]; azi1 = testcases[i][2];
lat2 = testcases[i][3]; lon2 = testcases[i][4]; azi2 = testcases[i][5];
s12 = testcases[i][6]; a12 = testcases[i][7]; m12 = testcases[i][8];
M12 = testcases[i][9]; M21 = testcases[i][10]; S12 = testcases[i][11];
a12a = g.GenDirect(lat1, lon1, azi1, false, s12, G::ALL | G::LONG_UNROLL,
lat2a, lon2a, azi2a, s12a, m12a, M12a, M21a, S12a);
k += checkEquals(lat2, lat2a, 1e-13 * f);
k += checkEquals(lon2, lon2a, 1e-13 * f);
k += checkEquals(azi2, azi2a, 1e-13 * f);
k += checkEquals(s12, s12a, 0 * f);
k += checkEquals(a12, a12a, 1e-13 * f);
k += checkEquals(m12, m12a, 1e-8 * f);
k += checkEquals(M12, M12a, 1e-15 * f);
k += checkEquals(M21, M21a, 1e-15 * f);
k += checkEquals(S12, S12a, 0.1 * f);
if (k) cout << "testdirect failure: case " << i << "\n";
result += k;
}
return result;
}
template <class G>
static int testarcdirect(T f = 1) {
T lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12;
T lat2a, lon2a, azi2a, s12a, a12a, m12a, M12a, M21a, S12a;
const G& g = G::WGS84();
int result = 0;
for (int i = 0; i < ncases; ++i) {
int k = 0;
lat1 = testcases[i][0]; lon1 = testcases[i][1]; azi1 = testcases[i][2];
lat2 = testcases[i][3]; lon2 = testcases[i][4]; azi2 = testcases[i][5];
s12 = testcases[i][6]; a12 = testcases[i][7]; m12 = testcases[i][8];
M12 = testcases[i][9]; M21 = testcases[i][10]; S12 = testcases[i][11];
a12a = g.GenDirect(lat1, lon1, azi1, true, a12, G::ALL | G::LONG_UNROLL,
lat2a, lon2a, azi2a, s12a, m12a, M12a, M21a, S12a);
k += checkEquals(lat2, lat2a, 1e-13 * f);
k += checkEquals(lon2, lon2a, 1e-13 * f);
k += checkEquals(azi2, azi2a, 1e-13 * f);
k += checkEquals(s12, s12a, 1e-8 * f);
k += checkEquals(a12, a12a, 0 * f);
k += checkEquals(m12, m12a, 1e-8 * f);
k += checkEquals(M12, M12a, 1e-15 * f);
k += checkEquals(M21, M21a, 1e-15 * f);
k += checkEquals(S12, S12a, 0.1 * f);
if (k) cout << "testarcdirect failure: case " << i << "\n";
result += k;
}
return result;
}
int main() {
int n = 0, i;
i = testinverse<Geodesic>(); n += i;
if (i) cout << "testinverse<Geodesic> failure\n";
i = testdirect<Geodesic>(); n += i;
if (i) cout << "testdirect<Geodesic> failure\n";
i = testarcdirect<Geodesic>(); n += i;
if (i) cout << "testarcdirect<Geodesic> failure\n";
// Allow 2x error with GeodesicExact calcuations (for WGS84)
i = testinverse<GeodesicExact>(2); n += i;
if (i) cout << "testinverse<GeodesicExact> failure\n";
i = testdirect<GeodesicExact>(4); n += i;
if (i) cout << "testdirect<GeodesicExact> failure\n";
i = testarcdirect<GeodesicExact>(2); n += i;
if (i) cout << "testarcdirect<GeodesicExact> failure\n";
if (n) {
cout << n << " failure" << (n > 1 ? "s" : "") << "\n";
return 1;
}
}

View File

@@ -0,0 +1,209 @@
/**
* \file polygontest.cpp
* \brief Test treatment of +/-0 and +/-180
*
* Copyright (c) Charles Karney (2022) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
**********************************************************************/
#include <iostream>
#include <limits>
#include <string>
#include <GeographicLib/Math.hpp>
#include <GeographicLib/Utility.hpp>
#include <GeographicLib/DMS.hpp>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicExact.hpp>
#include <GeographicLib/UTMUPS.hpp>
#include <GeographicLib/MGRS.hpp>
#include <GeographicLib/PolygonArea.hpp>
using namespace std;
using namespace GeographicLib;
typedef Math::real T;
static int checkEquals(T x, T y, T d) {
if (fabs(x - y) <= d)
return 0;
cout << "checkEquals fails: " << x << " != " << y << " +/- " << d << "\n";
return 1;
}
static int checkNaN(T x) {
using std::isnan; // Needed for Centos 7, ubuntu 14
if (isnan(x))
return 0;
cout << "checkNaN fails\n";
return 1;
}
static int Planimeter15() {
// Coverage tests, includes Planimeter15 - Planimeter18 (combinations of
// reverse and sign) + calls to testpoint, testedge, geod_polygonarea.
const Geodesic& g = Geodesic::WGS84();
PolygonArea polygon(g);
T lat[] = {2, 1, 3}, lon[] = {1, 2, 3};
T perim, area, s12, azi1, azi2;
T r = 18454562325.45119,
a0 = 510065621724088.5093; // ellipsoid area
int result = 0;
polygon.AddPoint(lat[0], lon[0]);
polygon.AddPoint(lat[1], lon[1]);
polygon.TestPoint(lat[2], lon[2], false, true, perim, area);
result += checkEquals(area, r, 0.5);
polygon.TestPoint(lat[2], lon[2], false, false, perim, area);
result += checkEquals(area, r, 0.5);
polygon.TestPoint(lat[2], lon[2], true, true, perim, area);
result += checkEquals(area, -r, 0.5);
polygon.TestPoint(lat[2], lon[2], true, false, perim, area);
result += checkEquals(area, a0-r, 0.5);
g.Inverse(lat[1], lon[1], lat[2], lon[2], s12, azi1, azi2);
polygon.TestEdge(azi1, s12, false, true, perim, area);
result += checkEquals(area, r, 0.5);
polygon.TestEdge(azi1, s12, false, false, perim, area);
result += checkEquals(area, r, 0.5);
polygon.TestEdge(azi1, s12, true, true, perim, area);
result += checkEquals(area, -r, 0.5);
polygon.TestEdge(azi1, s12, true, false, perim, area);
result += checkEquals(area, a0-r, 0.5);
polygon.AddPoint(lat[2], lon[2]);
polygon.Compute(false, true, perim, area);
result += checkEquals(area, r, 0.5);
polygon.Compute(false, false, perim, area);
result += checkEquals(area, r, 0.5);
polygon.Compute(true, true, perim, area);
result += checkEquals(area, -r, 0.5);
polygon.Compute(true, false, perim, area);
result += checkEquals(area, a0-r, 0.5);
return result;
}
static int Planimeter19() {
// Coverage tests, includes Planimeter19 - Planimeter20 (degenerate
// polygons) + extra cases.
const Geodesic& g = Geodesic::WGS84();
PolygonArea polygon(g, false);
PolygonArea polyline(g, true);
T perim, area;
int result = 0;
polygon.Compute(false, true, perim, area);
result += checkEquals(area, 0, 0);
result += checkEquals(perim, 0, 0);
polygon.TestPoint(1, 1, false, true, perim, area);
result += checkEquals(area, 0, 0);
result += checkEquals(perim, 0, 0);
polygon.TestEdge(90, 1000, false, true, perim, area);
result += checkNaN(area);
result += checkNaN(perim);
polygon.AddPoint(1, 1);
polygon.Compute(false, true, perim, area);
result += checkEquals(area, 0, 0);
result += checkEquals(perim, 0, 0);
polyline.Compute(false, true, perim, area);
result += checkEquals(perim, 0, 0);
polyline.TestPoint(1, 1, false, true, perim, area);
result += checkEquals(perim, 0, 0);
polyline.TestEdge(90, 1000, false, true, perim, area);
result += checkNaN(perim);
polyline.AddPoint(1, 1);
polyline.Compute(false, true, perim, area);
result += checkEquals(perim, 0, 0);
polyline.AddPoint(1, 1);
polyline.TestEdge(90, 1000, false, true, perim, area);
result += checkEquals(perim, 1000, 1e-10);
polyline.TestPoint(2, 2, false, true, perim, area);
result += checkEquals(perim, 156876.149, 0.5e-3);
return result;
}
static int Planimeter21() {
// Some test to add code coverage: multiple circlings of pole (includes
// Planimeter21 - Planimeter28) + invocations via testpoint and testedge.
const Geodesic& g = Geodesic::WGS84();
PolygonArea polygon(g);
T perim, area, lat = 45,
a = 39.2144607176828184218, s = 8420705.40957178156285,
r = 39433884866571.4277, // Area for one circuit
a0 = 510065621724088.5093; // Ellipsoid area
int result = 0, i;
polygon.AddPoint(lat, 60);
polygon.AddPoint(lat, 180);
polygon.AddPoint(lat, -60);
polygon.AddPoint(lat, 60);
polygon.AddPoint(lat, 180);
polygon.AddPoint(lat, -60);
for (i = 3; i <= 4; ++i) {
polygon.AddPoint(lat, 60);
polygon.AddPoint(lat, 180);
polygon.TestPoint(lat, -60, false, true, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.TestPoint(lat, -60, false, false, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.TestPoint(lat, -60, true, true, perim, area);
result += checkEquals(area, -i*r, 0.5);
polygon.TestPoint(lat, -60, true, false, perim, area);
result += checkEquals(area, -i*r + a0, 0.5);
polygon.TestEdge(a, s, false, true, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.TestEdge(a, s, false, false, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.TestEdge(a, s, true, true, perim, area);
result += checkEquals(area, -i*r, 0.5);
polygon.TestEdge(a, s, true, false, perim, area);
result += checkEquals(area, -i*r + a0, 0.5);
polygon.AddPoint(lat, -60);
polygon.Compute(false, true, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.Compute(false, false, perim, area);
result += checkEquals(area, i*r, 0.5);
polygon.Compute(true, true, perim, area);
result += checkEquals(area, -i*r, 0.5);
polygon.Compute(true, false, perim, area);
result += checkEquals(area, -i*r + a0, 0.5);
}
return result;
}
static int Planimeter29() {
// Check fix to transitdirect vs transit zero handling inconsistency
const Geodesic& g = Geodesic::WGS84();
PolygonArea polygon(g);
T perim, area;
int result = 0;
polygon.AddPoint(0, 0);
polygon.AddEdge( 90, 1000);
polygon.AddEdge( 0, 1000);
polygon.AddEdge(-90, 1000);
polygon.Compute(false, true, perim, area);
// The area should be 1e6. Prior to the fix it was 1e6 - A/2, where
// A = ellipsoid area.
result += checkEquals(area, 1000000.0, 0.01);
return result;
}
int main() {
int n = 0, i;
i = Planimeter15(); n += i;
if (i)
cout << "Planimeter15 failure\n";
i = Planimeter19(); n += i;
if (i)
cout << "Planimeter19 failure\n";
i = Planimeter21(); n += i;
if (i)
cout << "Planimeter21 failure\n";
i = Planimeter29(); n += i;
if (i)
cout << "Planimeter29 failure\n";
if (n) {
cout << n << " failure" << (n > 1 ? "s" : "") << "\n";
return 1;
}
}

View File

@@ -0,0 +1,602 @@
/**
* \file signtest.cpp
* \brief Test treatment of +/-0 and +/-180
*
* Copyright (c) Charles Karney (2022) <charles@karney.com> and licensed
* under the MIT/X11 License. For more information, see
* https://geographiclib.sourceforge.io/
**********************************************************************/
#include <iostream>
#include <limits>
#include <string>
#include <GeographicLib/Math.hpp>
#include <GeographicLib/Utility.hpp>
#include <GeographicLib/DMS.hpp>
#include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicExact.hpp>
#include <GeographicLib/UTMUPS.hpp>
#include <GeographicLib/MGRS.hpp>
#include <GeographicLib/PolygonArea.hpp>
// On Centos 7, remquo(810.0, 90.0 &q) returns 90.0 with q=8. Rather than
// lousing up Math.cpp with this problem we just skip the failing tests.
#if defined(__GNUG__) && __GNUG__ < 11
# define BUGGY_REMQUO 1
#else
# define BUGGY_REMQUO 0
#endif
// Visual Studio C++ does not implement round to even, see
// https://developercommunity.visualstudio.com/t/stdfixed-output-does-not-implement-round-to-even/1671088
// reported on 2022-02-20. Problem can't be reproduced at Microsoft, probably
// this is some issue with the runtime library.
//
// Broken on my Windows desktop system vc14 thru vc16
// Fixed on my Windows laptop system vc16 and vc17
// Broken on build-open machines, vc14 and vc15+win32
// Fixed on build-open machines, vc15+x64 and vc16
// Let's assume that it's OK for vc16 and later
#if defined(_MSC_VER) && _MSC_VER < 1920
# define BUGGY_ROUNDING 1
#else
# define BUGGY_ROUNDING 0
#endif
// use "do { } while (false)" idiom so it can be punctuated like a statement.
#define REMQUO_CHECK(CMD) do { if (!BUGGY_REMQUO) { CMD; } } while (false)
#define ROUNDING_CHECK(CMD) do { if (!BUGGY_ROUNDING) { CMD; } } while (false)
using namespace std;
using namespace GeographicLib;
typedef Math::real T;
static int equiv(T x, T y) {
using std::isnan; // Needed for Centos 7, ubuntu 14
return ( (isnan(x) && isnan(y)) || (x == y && signbit(x) == signbit(y)) ) ?
0 : 1;
}
static int checkEquals(T x, T y, T d) {
if (fabs(x - y) <= d)
return 0;
cout << "checkEquals fails: " << x << " != " << y << " +/- " << d << "\n";
return 1;
}
#define check(expr, r) do { \
T s = T(r), t = expr; \
if (equiv(s, t)) { \
cout << "Line " << __LINE__ << ": " << #expr \
<< " != " << #r << " (" << t << ")\n"; \
++n; \
} \
} while (false)
#define checksincosd(x, s, c) do { \
T sx, cx; \
Math::sincosd(x, sx, cx); \
if (equiv(s, sx)) { \
cout << "Line " << __LINE__ << ": sin(" << x \
<< ") != " << s << " (" << sx << ")\n"; \
++n; \
} \
if (equiv(c, cx)) { \
cout << "Line " << __LINE__ << ": cos(" << x \
<< ") != " << c << " (" << cx << ")\n"; \
++n; \
} \
} while (false)
#define strcheck(expr, r) do { \
string s = string(r), ss = expr; \
if (!(s == ss)) { \
cout << "Line " << __LINE__ << ": " << #expr \
<< " != " << #r << " (" << ss << ")\n"; \
++n; \
} \
} while (false)
int main() {
T inf = Math::infinity(),
nan = Math::NaN(),
eps = numeric_limits<T>::epsilon(),
ovf = 1 / Math::sq(eps),
e;
int n = 0;
check( Math::AngRound(-eps/32), -eps/32);
check( Math::AngRound(-eps/64), -0.0 );
check( Math::AngRound(- T(0)), -0.0 );
check( Math::AngRound( T(0)), +0.0 );
check( Math::AngRound( eps/64), +0.0 );
check( Math::AngRound( eps/32), +eps/32);
check( Math::AngRound((1-2*eps)/64), (1-2*eps)/64);
check( Math::AngRound((1-eps )/64), T(1) /64);
check( Math::AngRound((1-eps/2)/64), T(1) /64);
check( Math::AngRound((1-eps/4)/64), T(1) /64);
check( Math::AngRound( T(1) /64), T(1) /64);
check( Math::AngRound((1+eps/2)/64), T(1) /64);
check( Math::AngRound((1+eps )/64), T(1) /64);
check( Math::AngRound((1+2*eps)/64), (1+2*eps)/64);
check( Math::AngRound((1-eps )/32), (1-eps )/32);
check( Math::AngRound((1-eps/2)/32), T(1) /32);
check( Math::AngRound((1-eps/4)/32), T(1) /32);
check( Math::AngRound( T(1) /32), T(1) /32);
check( Math::AngRound((1+eps/2)/32), T(1) /32);
check( Math::AngRound((1+eps )/32), (1+eps )/32);
check( Math::AngRound((1-eps )/16), (1-eps )/16);
check( Math::AngRound((1-eps/2)/16), (1-eps/2)/16);
check( Math::AngRound((1-eps/4)/16), T(1) /16);
check( Math::AngRound( T(1) /16), T(1) /16);
check( Math::AngRound((1+eps/4)/16), T(1) /16);
check( Math::AngRound((1+eps/2)/16), T(1) /16);
check( Math::AngRound((1+eps )/16), (1+eps )/16);
check( Math::AngRound((1-eps )/ 8), (1-eps )/ 8);
check( Math::AngRound((1-eps/2)/ 8), (1-eps/2)/ 8);
check( Math::AngRound((1-eps/4)/ 8), T(1) / 8);
check( Math::AngRound((1+eps/2)/ 8), T(1) / 8);
check( Math::AngRound((1+eps )/ 8), (1+eps )/ 8);
check( Math::AngRound( 1-eps ), 1-eps );
check( Math::AngRound( 1-eps/2 ), 1-eps/2 );
check( Math::AngRound( 1-eps/4 ), 1 );
check( Math::AngRound( T(1) ), 1 );
check( Math::AngRound( 1+eps/4 ), 1 );
check( Math::AngRound( 1+eps/2 ), 1 );
check( Math::AngRound( 1+eps ), 1+ eps );
check( Math::AngRound(T(90)-64*eps), 90-64*eps );
check( Math::AngRound(T(90)-32*eps), 90 );
check( Math::AngRound(T(90) ), 90 );
checksincosd(- inf , nan, nan);
REMQUO_CHECK( checksincosd(-T(810), -1.0, +0.0) );
checksincosd(-T(720), -0.0, +1.0);
checksincosd(-T(630), +1.0, +0.0);
checksincosd(-T(540), -0.0, -1.0);
checksincosd(-T(450), -1.0, +0.0);
checksincosd(-T(360), -0.0, +1.0);
checksincosd(-T(270), +1.0, +0.0);
checksincosd(-T(180), -0.0, -1.0);
checksincosd(-T( 90), -1.0, +0.0);
checksincosd(-T( 0), -0.0, +1.0);
checksincosd(+T( 0), +0.0, +1.0);
checksincosd(+T( 90), +1.0, +0.0);
checksincosd(+T(180), +0.0, -1.0);
checksincosd(+T(270), -1.0, +0.0);
checksincosd(+T(360), +0.0, +1.0);
checksincosd(+T(450), +1.0, +0.0);
checksincosd(+T(540), +0.0, -1.0);
checksincosd(+T(630), -1.0, +0.0);
checksincosd(+T(720), +0.0, +1.0);
REMQUO_CHECK( checksincosd(+T(810), +1.0, +0.0) );
checksincosd(+ inf , nan, nan);
checksincosd( nan , nan, nan);
{
T s1, c1, s2, c2, s3, c3;
Math::sincosd(T( 9), s1, c1);
Math::sincosd(T( 81), s2, c2);
Math::sincosd(T(-123456789), s3, c3);
int j = equiv(s1, c2) + equiv(c1, s2);
REMQUO_CHECK( j += equiv(s1, s3) + equiv(c1, -c3) );
if (j) {
cout << "Line " << __LINE__ << " : sincos accuracy fail\n";
++n;
}
}
check( Math::sind(- inf ), nan);
check( Math::sind(-T(720)), -0.0);
check( Math::sind(-T(540)), -0.0);
check( Math::sind(-T(360)), -0.0);
check( Math::sind(-T(180)), -0.0);
check( Math::sind(-T( 0)), -0.0);
check( Math::sind(+T( 0)), +0.0);
check( Math::sind(+T(180)), +0.0);
check( Math::sind(+T(360)), +0.0);
check( Math::sind(+T(540)), +0.0);
check( Math::sind(+T(720)), +0.0);
check( Math::sind(+ inf ), nan);
check( Math::cosd(- inf ), nan);
REMQUO_CHECK( check( Math::cosd(-T(810)), +0.0) );
check( Math::cosd(-T(630)), +0.0);
check( Math::cosd(-T(450)), +0.0);
check( Math::cosd(-T(270)), +0.0);
check( Math::cosd(-T( 90)), +0.0);
check( Math::cosd(+T( 90)), +0.0);
check( Math::cosd(+T(270)), +0.0);
check( Math::cosd(+T(450)), +0.0);
check( Math::cosd(+T(630)), +0.0);
REMQUO_CHECK( check( Math::cosd(+T(810)), +0.0) );
check( Math::cosd(+ inf ), nan);
#if !(defined(_MSC_VER) && _MSC_VER <= 1900)
check( Math::tand(- inf ), nan);
#endif
REMQUO_CHECK( check( Math::tand(-T(810)), -ovf) );
check( Math::tand(-T(720)), -0.0);
check( Math::tand(-T(630)), +ovf);
check( Math::tand(-T(540)), +0.0);
check( Math::tand(-T(450)), -ovf);
check( Math::tand(-T(360)), -0.0);
check( Math::tand(-T(270)), +ovf);
check( Math::tand(-T(180)), +0.0);
check( Math::tand(-T( 90)), -ovf);
check( Math::tand(-T( 0)), -0.0);
check( Math::tand(+T( 0)), +0.0);
check( Math::tand(+T( 90)), +ovf);
check( Math::tand(+T(180)), -0.0);
check( Math::tand(+T(270)), -ovf);
check( Math::tand(+T(360)), +0.0);
check( Math::tand(+T(450)), +ovf);
check( Math::tand(+T(540)), -0.0);
check( Math::tand(+T(630)), -ovf);
check( Math::tand(+T(720)), +0.0);
REMQUO_CHECK( check( Math::tand(+T(810)), +ovf) );
#if !(defined(_MSC_VER) && _MSC_VER <= 1900)
check( Math::tand(+ inf ), nan);
#endif
check( Math::atan2d(+T(0), -T(0)), +180 );
check( Math::atan2d(-T(0), -T(0)), -180 );
check( Math::atan2d(+T(0), +T(0)), +0.0 );
check( Math::atan2d(-T(0), +T(0)), -0.0 );
check( Math::atan2d(+T(0), -T(1)), +180 );
check( Math::atan2d(-T(0), -T(1)), -180 );
check( Math::atan2d(+T(0), +T(1)), +0.0 );
check( Math::atan2d(-T(0), +T(1)), -0.0 );
check( Math::atan2d(-T(1), +T(0)), -90 );
check( Math::atan2d(-T(1), -T(0)), -90 );
check( Math::atan2d(+T(1), +T(0)), +90 );
check( Math::atan2d(+T(1), -T(0)), +90 );
check( Math::atan2d(+T(1), -inf), +180 );
check( Math::atan2d(-T(1), -inf), -180 );
check( Math::atan2d(+T(1), +inf), +0.0 );
check( Math::atan2d(-T(1), +inf), -0.0 );
check( Math::atan2d( +inf, +T(1)), +90 );
check( Math::atan2d( +inf, -T(1)), +90 );
check( Math::atan2d( -inf, +T(1)), -90 );
check( Math::atan2d( -inf, -T(1)), -90 );
check( Math::atan2d( +inf, -inf), +135 );
check( Math::atan2d( -inf, -inf), -135 );
check( Math::atan2d( +inf, +inf), +45 );
check( Math::atan2d( -inf, +inf), -45 );
check( Math::atan2d( nan, +T(1)), nan );
check( Math::atan2d(+T(1), nan), nan );
{
T s = 7e-16;
if ( equiv( Math::atan2d(s, -T(1)), 180 - Math::atan2d(s, T(1)) ) ) {
cout << "Line " << __LINE__ << " : atan2d accuracy fail\n";
++n;
}
}
check( Math::sum(+T(9), -T(9), e), +0.0 );
check( Math::sum(-T(9), +T(9), e), +0.0 );
check( Math::sum(-T(0), +T(0), e), +0.0 );
check( Math::sum(+T(0), -T(0), e), +0.0 );
check( Math::sum(-T(0), -T(0), e), -0.0 );
check( Math::sum(+T(0), +T(0), e), +0.0 );
check( Math::AngNormalize(-T(900)), -180 );
check( Math::AngNormalize(-T(720)), -0.0 );
check( Math::AngNormalize(-T(540)), -180 );
check( Math::AngNormalize(-T(360)), -0.0 );
check( Math::AngNormalize(-T(180)), -180 );
check( Math::AngNormalize( -T(0)), -0.0 );
check( Math::AngNormalize( +T(0)), +0.0 );
check( Math::AngNormalize( T(180)), +180 );
check( Math::AngNormalize( T(360)), +0.0 );
check( Math::AngNormalize( T(540)), +180 );
check( Math::AngNormalize( T(720)), +0.0 );
check( Math::AngNormalize( T(900)), +180 );
check( Math::AngDiff(+T( 0), +T( 0), e), +0.0 );
check( Math::AngDiff(+T( 0), -T( 0), e), -0.0 );
check( Math::AngDiff(-T( 0), +T( 0), e), +0.0 );
check( Math::AngDiff(-T( 0), -T( 0), e), +0.0 );
check( Math::AngDiff(+T( 5), +T(365), e), +0.0 );
check( Math::AngDiff(+T(365), +T( 5), e), -0.0 );
check( Math::AngDiff(+T( 5), +T(185), e), +180.0 );
check( Math::AngDiff(+T(185), +T( 5), e), -180.0 );
check( Math::AngDiff( +eps , +T(180), e), +180.0 );
check( Math::AngDiff( -eps , +T(180), e), -180.0 );
check( Math::AngDiff( +eps , -T(180), e), +180.0 );
check( Math::AngDiff( -eps , -T(180), e), -180.0 );
{
T x = 138 + 128 * eps, y = -164;
if ( equiv( Math::AngDiff(x, y), 58 - 128 * eps ) ) {
cout << "Line " << __LINE__ << " : AngDiff accuracy fail\n";
++n;
}
}
check( Utility::val<T>("+0"), +0.0 );
check( Utility::val<T>("-0"), -0.0 );
check( Utility::val<T>("nan"), nan );
check( Utility::val<T>("+inf"), +inf );
check( Utility::val<T>( "inf"), +inf );
check( Utility::val<T>("-inf"), -inf );
strcheck( Utility::str<T>( nan, 0), "nan" );
strcheck( Utility::str<T>(-inf, 0), "-inf" );
strcheck( Utility::str<T>(+inf, 0), "inf" );
strcheck( Utility::str<T>(-T(3.5), 0), "-4" );
ROUNDING_CHECK( strcheck( Utility::str<T>(-T(2.5), 0), "-2" ) );
strcheck( Utility::str<T>(-T(1.5), 0), "-2" );
ROUNDING_CHECK( strcheck( Utility::str<T>(-T(0.5), 0), "-0" ) );
strcheck( Utility::str<T>(-T(0 ), 0), "-0" );
strcheck( Utility::str<T>(+T(0 ), 0), "0" );
ROUNDING_CHECK( strcheck( Utility::str<T>(+T(0.5), 0), "0" ) );
strcheck( Utility::str<T>(+T(1.5), 0), "2" );
ROUNDING_CHECK( strcheck( Utility::str<T>(+T(2.5), 0), "2" ) );
strcheck( Utility::str<T>(+T(3.5), 0), "4" );
strcheck( Utility::str<T>(-T(1.75), 1), "-1.8");
ROUNDING_CHECK( strcheck( Utility::str<T>(-T(1.25), 1), "-1.2") );
strcheck( Utility::str<T>(-T(0.75), 1), "-0.8");
ROUNDING_CHECK( strcheck( Utility::str<T>(-T(0.25), 1), "-0.2") );
strcheck( Utility::str<T>(-T(0 ), 1), "-0.0");
strcheck( Utility::str<T>(+T(0 ), 1), "0.0");
ROUNDING_CHECK( strcheck( Utility::str<T>(+T(0.25), 1), "0.2") );
strcheck( Utility::str<T>(+T(0.75), 1), "0.8");
ROUNDING_CHECK( strcheck( Utility::str<T>(+T(1.25), 1), "1.2") );
strcheck( Utility::str<T>(+T(1.75), 1), "1.8");
strcheck( DMS::Encode( nan, DMS::DEGREE, 0), "nan" );
strcheck( DMS::Encode(-inf, DMS::DEGREE, 0), "-inf" );
strcheck( DMS::Encode(+inf, DMS::DEGREE, 0), "inf" );
strcheck( DMS::Encode(-T(3.5), DMS::DEGREE, 0), "-4" );
ROUNDING_CHECK( strcheck( DMS::Encode(-T(2.5), DMS::DEGREE, 0), "-2" ) );
strcheck( DMS::Encode(-T(1.5), DMS::DEGREE, 0), "-2" );
ROUNDING_CHECK( strcheck( DMS::Encode(-T(0.5), DMS::DEGREE, 0), "-0" ) );
strcheck( DMS::Encode(-T(0 ), DMS::DEGREE, 0), "-0" );
strcheck( DMS::Encode(+T(0 ), DMS::DEGREE, 0), "0" );
ROUNDING_CHECK( strcheck( DMS::Encode(+T(0.5), DMS::DEGREE, 0), "0" ) );
strcheck( DMS::Encode(+T(1.5), DMS::DEGREE, 0), "2" );
ROUNDING_CHECK( strcheck( DMS::Encode(+T(2.5), DMS::DEGREE, 0), "2" ) );
strcheck( DMS::Encode(+T(3.5), DMS::DEGREE, 0), "4" );
strcheck( DMS::Encode(-T(1.75), DMS::DEGREE, 1), "-1.8");
ROUNDING_CHECK( strcheck( DMS::Encode(-T(1.25), DMS::DEGREE, 1), "-1.2") );
strcheck( DMS::Encode(-T(0.75), DMS::DEGREE, 1), "-0.8");
ROUNDING_CHECK( strcheck( DMS::Encode(-T(0.25), DMS::DEGREE, 1), "-0.2") );
strcheck( DMS::Encode(-T(0 ), DMS::DEGREE, 1), "-0.0");
strcheck( DMS::Encode(+T(0 ), DMS::DEGREE, 1), "0.0");
ROUNDING_CHECK( strcheck( DMS::Encode(+T(0.25), DMS::DEGREE, 1), "0.2") );
strcheck( DMS::Encode(+T(0.75), DMS::DEGREE, 1), "0.8");
ROUNDING_CHECK( strcheck( DMS::Encode(+T(1.25), DMS::DEGREE, 1), "1.2") );
strcheck( DMS::Encode(+T(1.75), DMS::DEGREE, 1), "1.8");
strcheck( DMS::Encode( T(1e20), DMS::DEGREE, 0), "100000000000000000000");
strcheck( DMS::Encode( T(1e21), DMS::DEGREE, 0), "1000000000000000000000");
{
T t = -(1 + 2/T(60) + T(2.99)/3600);
strcheck( DMS::Encode( t,DMS::DEGREE,0,DMS::NONE ), "-1" );
strcheck( DMS::Encode( t,DMS::DEGREE,0,DMS::LATITUDE ), "01S" );
strcheck( DMS::Encode( t,DMS::DEGREE,0,DMS::LONGITUDE),"001W" );
strcheck( DMS::Encode(-t,DMS::DEGREE,0,DMS::AZIMUTH ),"001" );
strcheck( DMS::Encode( t,DMS::DEGREE,1,DMS::NONE ), "-1.0" );
strcheck( DMS::Encode( t,DMS::DEGREE,1,DMS::LATITUDE ), "01.0S" );
strcheck( DMS::Encode( t,DMS::DEGREE,1,DMS::LONGITUDE),"001.0W" );
strcheck( DMS::Encode(-t,DMS::DEGREE,1,DMS::AZIMUTH ),"001.0" );
strcheck( DMS::Encode( t,DMS::MINUTE,0,DMS::NONE ), "-1d02'" );
strcheck( DMS::Encode( t,DMS::MINUTE,0,DMS::LATITUDE ), "01d02'S" );
strcheck( DMS::Encode( t,DMS::MINUTE,0,DMS::LONGITUDE),"001d02'W" );
strcheck( DMS::Encode(-t,DMS::MINUTE,0,DMS::AZIMUTH ),"001d02'" );
strcheck( DMS::Encode( t,DMS::MINUTE,1,DMS::NONE ), "-1d02.0'" );
strcheck( DMS::Encode( t,DMS::MINUTE,1,DMS::LATITUDE ), "01d02.0'S" );
strcheck( DMS::Encode( t,DMS::MINUTE,1,DMS::LONGITUDE),"001d02.0'W" );
strcheck( DMS::Encode(-t,DMS::MINUTE,1,DMS::AZIMUTH ),"001d02.0'" );
strcheck( DMS::Encode( t,DMS::SECOND,0,DMS::NONE ), "-1d02'03\"" );
strcheck( DMS::Encode( t,DMS::SECOND,0,DMS::LATITUDE ), "01d02'03\"S" );
strcheck( DMS::Encode( t,DMS::SECOND,0,DMS::LONGITUDE),"001d02'03\"W" );
strcheck( DMS::Encode(-t,DMS::SECOND,0,DMS::AZIMUTH ),"001d02'03\"" );
strcheck( DMS::Encode( t,DMS::SECOND,1,DMS::NONE ), "-1d02'03.0\"");
strcheck( DMS::Encode( t,DMS::SECOND,1,DMS::LATITUDE ), "01d02'03.0\"S");
strcheck( DMS::Encode( t,DMS::SECOND,1,DMS::LONGITUDE),"001d02'03.0\"W");
strcheck( DMS::Encode(-t,DMS::SECOND,1,DMS::AZIMUTH ),"001d02'03.0\"" );
}
DMS::flag ind;
check( DMS::Decode(" +0 ", ind), +0.0 );
check( DMS::Decode("-0 ", ind), -0.0 );
check( DMS::Decode(" nan", ind), nan );
check( DMS::Decode("+inf", ind), +inf );
check( DMS::Decode(" inf", ind), +inf );
check( DMS::Decode("-inf", ind), -inf );
check( DMS::Decode(" +0N", ind), +0.0 );
check( DMS::Decode("-0N ", ind), -0.0 );
check( DMS::Decode("+0S ", ind), -0.0 );
check( DMS::Decode(" -0S", ind), +0.0 );
{
// azimuth of geodesic line with points on equator determined by signs of
// latitude
// lat1 lat2 azi1/2
T C[2][3] = {
{ +T(0), -T(0), 180 },
{ -T(0), +T(0), 0 }
};
const Geodesic& g = Geodesic::WGS84();
const GeodesicExact& ge = GeodesicExact::WGS84();
T azi1, azi2;
int i = 0;
for (int k = 0; k < 2; ++k) {
g.Inverse(C[k][0], T(0), C[k][1], T(0), azi1, azi2);
if ( equiv(azi1, C[k][2]) + equiv(azi2, C[k][2]) ) ++i;
ge.Inverse(C[k][0], T(0), C[k][1], T(0), azi1, azi2);
if ( equiv(azi1, C[k][2]) + equiv(azi2, C[k][2]) ) ++i;
}
if (i) {
cout << "Line " << __LINE__
<< ": Geodesic::Inverse coincident points on equator fail\n";
++n;
}
}
{
// Does the nearly antipodal equatorial solution go north or south?
// lat1 lat2 azi1 azi2
T C[2][4] = {
{ +T(0), +T(0), 56, 124},
{ -T(0), -T(0), 124, 56}
};
const Geodesic& g = Geodesic::WGS84();
const GeodesicExact& ge = GeodesicExact::WGS84();
T azi1, azi2;
int i = 0;
for (int k = 0; k < 2; ++k) {
g.Inverse(C[k][0], T(0), C[k][1], T(179.5), azi1, azi2);
i += checkEquals(azi1, C[k][2], 1) + checkEquals(azi2, C[k][3], 1);
ge.Inverse(C[k][0], T(0), C[k][1], T(179.5), azi1, azi2);
i += checkEquals(azi1, C[k][2], 1) + checkEquals(azi2, C[k][3], 1);
}
if (i) {
cout << "Line " << __LINE__
<< ": Geodesic::Inverse nearly antipodal points on equator fail\n";
++n;
}
}
{
// How does the exact antipodal equatorial path go N/S + E/W
// lat1 lat2 lon2 azi1 azi2
T C[4][5] = {
{ +T(0), +T(0), +180, +T(0), +180},
{ -T(0), -T(0), +180, +180, +T(0)},
{ +T(0), +T(0), -180, -T(0), -180},
{ -T(0), -T(0), -180, -180, -T(0)}
};
const Geodesic& g = Geodesic::WGS84();
const GeodesicExact& ge = GeodesicExact::WGS84();
T azi1, azi2;
int i = 0;
for (int k = 0; k < 4; ++k) {
g.Inverse(C[k][0], T(0), C[k][1], C[k][2], azi1, azi2);
if ( equiv(azi1, C[k][3]) + equiv(azi2, C[k][4]) ) ++i;
ge.Inverse(C[k][0], T(0), C[k][1], C[k][2], azi1, azi2);
if ( equiv(azi1, C[k][3]) + equiv(azi2, C[k][4]) ) ++i;
}
if (i) {
cout << "Line " << __LINE__
<< ": Geodesic::Inverse antipodal points on equator fail\n";
++n;
}
}
{
// Antipodal points on the equator with prolate ellipsoid
// lon2 azi1/2
T C[2][2] = {
{ +180, +90 },
{ -180, -90 }
};
const Geodesic g(T(6.4e6), -1/T(300));
const GeodesicExact ge(T(6.4e6), -1/T(300));
T azi1, azi2;
int i = 0;
for (int k = 0; k < 2; ++k) {
g.Inverse(T(0), T(0), T(0), C[k][0], azi1, azi2);
if ( equiv(azi1, C[k][1]) + equiv(azi2, C[k][1]) ) ++i;
ge.Inverse(T(0), T(0), T(0), C[k][0], azi1, azi2);
if ( equiv(azi1, C[k][1]) + equiv(azi2, C[k][1]) ) ++i;
}
if (i) {
cout << "Line " << __LINE__
<< ": Geodesic::Inverse antipodal points on equator, prolate, fail\n";
++n;
}
}
{
// azimuths = +/-0 and +/-180 for the direct problem
// azi1, lon2, azi2
T C[4][3] = {
{ +T(0), +180, +180 },
{ -T(0), -180, -180 },
{ +180 , +180, +T(0) },
{ -180 , -180, -T(0) }
};
const Geodesic& g = Geodesic::WGS84();
const GeodesicExact& ge = GeodesicExact::WGS84();
T lon2, azi2;
int i = 0;
for (int k = 0; k < 4; ++k) {
T t;
g.GenDirect(T(0), T(0), C[k][0], false, T(15e6),
Geodesic::LONGITUDE | Geodesic::AZIMUTH |
Geodesic::LONG_UNROLL,
t, lon2, azi2,
t, t, t, t, t);
if ( equiv(lon2, C[k][1]) + equiv(azi2, C[k][2]) ) ++i;
ge.GenDirect(T(0), T(0), C[k][0], false, T(15e6),
Geodesic::LONGITUDE | Geodesic::AZIMUTH |
Geodesic::LONG_UNROLL,
t, lon2, azi2,
t, t, t, t, t);
if ( equiv(lon2, C[k][1]) + equiv(azi2, C[k][2]) ) ++i;
}
if (i) {
cout << "Line " << __LINE__
<< ": Geodesic::Direct azi1 = +/-0 +/-180, fail\n";
++n;
}
}
{
// lat = +/-0 in UTMUPS::Forward
// lat y northp
T C[2][3] = {
{ +T(0), T(0), 1 },
{ -T(0), 10e6, 0 }
};
int i = 0;
bool northp; int zone; T x, y; string mgrs;
for (int k = 0; k < 2; ++k) {
UTMUPS::Forward(C[k][0], T(3), zone, northp, x, y);
if ( equiv(y, C[k][1]) + (northp == (C[k][2] > 0) ? 0 : 1) ) ++i;
MGRS::Forward(zone, northp, x, y, 2, mgrs);
if (!( mgrs == (k == 0 ? "31NEA0000" : "31MEV0099") )) ++i;
MGRS::Forward(zone, northp, x, y, +T(0), 2, mgrs);
if (!( mgrs == (k == 0 ? "31NEA0000" : "31MEV0099") )) ++i;
MGRS::Forward(zone, northp, x, y, -T(0), 2, mgrs);
if (!( mgrs == (k == 0 ? "31NEA0000" : "31MEV0099") )) ++i;
}
if (i) {
cout << "Line " << __LINE__
<< ": UTMUPS/MGRS::Forward lat = +/-0, fail\n";
++n;
}
}
{
// Implement check on AddEdge bug: AddPoint(0,0) +
// AddEdge(90, 1000) + AddEdge(0, 1000) + AddEdge(-90, 0). The area
// should be 1e6. Prior to the fix it was 1e6 - A/2, where A = ellipsoid
// area.
// add_test (NAME Planimeter29 COMMAND Planimeter ...)
const Geodesic& g = Geodesic::WGS84();
PolygonArea polygon(g);
polygon.AddPoint(0, 0);
polygon.AddEdge( 90, 1000);
polygon.AddEdge( 0, 1000);
polygon.AddEdge(-90, 1000);
T perim, area;
// The area should be 1e6. Prior to the fix it was 1e6 - A/2, where
// A = ellipsoid area.
polygon.Compute(false, true, perim, area);
int i = checkEquals(area, 1000000, 0.01);
if (i) {
cout << "Line " << __LINE__
<< ": Planimeter29 fail\n";
++n;
}
}
if (n) {
cout << n << " failure" << (n > 1 ? "s" : "") << "\n";
return 1;
}
}