Skip to content

Commit 42394cf

Browse files
committed
add meson, correct ecef2geodetic negative altitude
1 parent 8ed616e commit 42394cf

8 files changed

Lines changed: 67 additions & 38 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ if(NOT realbits)
1010
set(realbits 64)
1111
endif()
1212

13-
if(NOT WIN32)
14-
option(BUILD_SHARED_LIBS "Shared libraries .so. Feel free to turn off." ON)
15-
endif()
16-
1713
# --- Maptran library
1814
add_library(maptran src/maptran.F90 src/vallado.F90)
1915
target_compile_options(maptran PRIVATE ${FFLAGS})

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Similar to Python
88

99
## Install
1010

11-
Requires Fortran 2003+ compiler, such as `gfortran`, `ifort`, PGI, `nagfor`, `flang`, etc.
11+
Requires Fortran 2008 compiler, such as `gfortran`, `ifort`, PGI, `nagfor`, `flang`, Cray, IBM XL, etc.
1212

1313
```sh
1414
cd bin

cmake/compilers.cmake

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ endif()
66

77
if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel)
88

9-
list(APPEND FFLAGS -traceback -warn)
9+
list(APPEND FFLAGS -traceback -warn -implicitnone)
1010
if(CMAKE_BUILD_TYPE STREQUAL Debug)
1111
list(APPEND FFLAGS -check all -debug extended)
1212
endif()
@@ -16,15 +16,14 @@ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
1616
list(APPEND FFLAGS -std=f2018)
1717
endif()
1818

19-
list(APPEND FFLAGS -march=native -Wall -Wextra -Wpedantic -Warray-bounds)# -Wfatal-errors)
19+
list(APPEND FFLAGS -fimplicit-none -march=native -Wall -Wextra -Wpedantic -Warray-bounds)# -Wfatal-errors)
2020
if(CMAKE_BUILD_TYPE STREQUAL Debug)
21-
list(APPEND FFLAGS -ffpe-trap=zero,overflow)
21+
list(APPEND FFLAGS -ffpe-trap=overflow)
2222
endif()
2323
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL PGI)
2424

2525
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL Flang)
2626
list(APPEND FFLAGS -Mallocatable=03)
27-
list(APPEND FLIBS -static-flang-libs)
2827
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL NAG)
2928
list(APPEND FFLAGS -f2008 -C -colour -gline -nan -info -u)
3029
endif()

meson.build

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
project('MapTran', 'fortran', default_options : ['default_library=static'])
2+
3+
REALBITS = '-DREALBITS='+get_option('realbits')
4+
5+
fc = meson.get_compiler('fortran')
6+
if fc.get_id() == 'gcc'
7+
add_global_arguments('-fimplicit-none', '-Wall', '-Wextra', '-Wpedantic', language : 'fortran')
8+
endif
9+
10+
# --- Maptran library
11+
maptran = library('maptran', 'src/maptran.F90', 'src/vallado.F90',
12+
fortran_args : REALBITS)
13+
14+
# --- testing
15+
mtexe = executable('testmaptran', 'tests/test_mod.f90', 'src/assert.F90',
16+
link_with : maptran,
17+
fortran_args : [REALBITS, '-DF08=1'])
18+
19+
test('Maptran', mtexe)

meson_options.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
option('realbits', type : 'string', value : '64')

src/assert.F90

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ elemental logical function isclose(actual, desired, rtol, atol, equal_nan)
4040

4141
real(wp) :: r,a
4242
logical :: n
43-
! this is appropriate INSTEAD OF merge(), since non present values aren't defined.
43+
44+
isclose = .false. !< ensure it's defined
45+
46+
!> INSTEAD OF merge(), since non present values aren't defined.
4447
r = 1e-5_wp
4548
a = 0._wp
4649
n = .false.
@@ -56,8 +59,10 @@ elemental logical function isclose(actual, desired, rtol, atol, equal_nan)
5659
!isclose = (actual == desired)
5760
!if (isclose) return
5861
!--- equal nan
59-
isclose = n.and.(ieee_is_nan(actual).and.ieee_is_nan(desired))
60-
if (isclose) return
62+
if (n) then ! fortran is NOT short circuit logic in general
63+
isclose = (ieee_is_nan(actual) .and. ieee_is_nan(desired))
64+
if (isclose) return
65+
endif
6166
!--- Inf /= -Inf, unequal NaN
6267
if (.not.ieee_is_finite(actual) .or. .not.ieee_is_finite(desired)) return
6368
!--- floating point closeness check

src/maptran.F90

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ impure elemental subroutine lookAtSpheroid(lat0, lon0, h0, az, tilt, lat, lon, s
5858

5959
nan = ieee_value(0._wp, ieee_quiet_nan)
6060

61-
if (present(spheroid)) then
62-
ell = spheroid
63-
else
64-
ell = wgs84Ellipsoid
65-
endif
61+
ell = wgs84Ellipsoid
62+
if (present(spheroid)) ell = spheroid
6663

6764
d=.true.
6865
if (present(deg)) d = deg
@@ -119,13 +116,10 @@ elemental subroutine ecef2geodetic(x, y, z, lat, lon, alt, spheroid, deg)
119116

120117
real(wp) :: ea, eb, r, E, u, Q, huE, Beta, eps
121118
type(Ellipsoid) :: ell
122-
logical :: d
119+
logical :: d, inside
123120

124-
if (present(spheroid)) then
125-
ell = spheroid
126-
else
127-
ell = wgs84Ellipsoid
128-
endif
121+
ell = wgs84Ellipsoid
122+
if (present(spheroid)) ell = spheroid
129123

130124
ea = ell%SemimajorAxis
131125
eb = ell%SemiminorAxis
@@ -142,7 +136,7 @@ elemental subroutine ecef2geodetic(x, y, z, lat, lon, alt, spheroid, deg)
142136
huE = hypot(u, E)
143137

144138
! eqn. 4b
145-
Beta = atan(huE / u * z / hypot(x, y))
139+
Beta = atan(huE / u * z, hypot(x, y))
146140

147141
! eqn. 13
148142
eps = ((eb * u - ea * huE + E**2) * sin(Beta)) / (ea * huE * 1 / cos(Beta) - E**2 * cos(Beta))
@@ -151,11 +145,18 @@ elemental subroutine ecef2geodetic(x, y, z, lat, lon, alt, spheroid, deg)
151145
! final output
152146
lat = atan(ea / eb * tan(Beta))
153147

154-
lon = atan(y/x)
148+
lon = atan(y, x)
155149

156150
! eqn. 7
157-
if (present(alt)) alt = sqrt((z - eb * sin(Beta))**2 + (Q - ea * cos(Beta))**2)
158-
151+
if (present(alt)) then
152+
alt = hypot(z - eb * sin(Beta), Q - ea * cos(Beta))
153+
154+
!> inside ellipsoid?
155+
inside = x**2 / ea**2 + y**2 / ea**2 + z**2 / eb**2 < 1._wp
156+
if (inside) alt = -alt
157+
endif
158+
159+
159160
d=.true.
160161
if (present(deg)) d = deg
161162

@@ -193,11 +194,8 @@ elemental subroutine geodetic2ecef(lat,lon,alt, x,y,z, spheroid, deg)
193194
d = .true. ! not merge, Flang gives segfault
194195
if (present(deg)) d = deg
195196

196-
if (present(spheroid)) then
197-
ell = spheroid
198-
else
199-
ell = wgs84Ellipsoid
200-
endif
197+
ell = wgs84Ellipsoid
198+
if (present(spheroid)) ell = spheroid
201199

202200
if (d) then
203201
lat = radians(lat)
@@ -468,8 +466,8 @@ elemental subroutine enu2aer(east, north, up, az, elev, slantRange, deg)
468466
r = hypot(east, north)
469467
slantRange = hypot(r, up)
470468
! radians
471-
elev = atan2(up, r)
472-
az = modulo(atan2(east, north), 2._wp * atan2(0._wp, -1._wp))
469+
elev = atan(up, r)
470+
az = modulo(atan(east, north), 2._wp * atan(0._wp, -1._wp))
473471

474472
d=.true.
475473
if (present(deg)) d = deg

tests/test_mod.f90

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ program Test
77

88
implicit none
99

10-
!type(Ellipsoid), parameter :: spheroid = wgs84Ellipsoid
10+
type(Ellipsoid), parameter :: spheroid = wgs84Ellipsoid
1111

1212
real(wp), parameter :: lat = 42, lon= -82, alt = 200, &
1313
az = 33, el=70, rng= 1e3_wp, &
@@ -45,8 +45,6 @@ program Test
4545

4646
nan = ieee_value(0._wp, ieee_quiet_nan)
4747

48-
!print*,'Default WGS84 Ellipsoid:',spheroid
49-
5048
! --------- scalar degrees
5149
az5 = [0._wp, 10._wp, 125._wp];
5250
tilt = [30, 45, 90];
@@ -64,7 +62,7 @@ program Test
6462
call assert_allclose(rng5, [230.9413173_wp, 282.84715651_wp, nan], rtol=0.01_wp, equal_nan=.true.)
6563

6664

67-
!-------
65+
!! Scalar degrees
6866

6967
call geodetic2ecef(lat,lon,alt, x1,y1,z1)
7068
call assert_allclose([x1,y1,z1],[x0,y0,z0], &
@@ -76,10 +74,23 @@ program Test
7674
call aer2ecef(az,el,rng,lat,lon,alt,x2,y2,z2)
7775
call assert_allclose([x2,y2,z2],[xl,yl,zl])
7876

77+
!> ECEF2GEODETIC tests
7978
call ecef2geodetic(x1,y1,z1,lat2,lon2,alt2)
8079
call assert_allclose([lat2,lon2,alt2],[lat,lon,alt], &
8180
rtol=0.01_wp, err_msg='ecef2geodetic-degrees')
8281

82+
call ecef2geodetic(spheroid%SemimajorAxis-1._wp, 0._wp, 0._wp, lat2, lon2, alt2)
83+
call assert_allclose([lat2,lon2,alt2],[0._wp, 0._wp, -1._wp], &
84+
rtol=0.01_wp, err_msg='ecef2geodetic-degrees')
85+
86+
call ecef2geodetic(0._wp, spheroid%SemimajorAxis-1._wp, 0._wp, lat2, lon2, alt2)
87+
call assert_allclose([lat2,lon2,alt2],[0._wp, 90._wp, -1._wp], &
88+
rtol=0.01_wp, err_msg='ecef2geodetic-degrees')
89+
90+
call ecef2geodetic(0._wp, 0._wp, spheroid%SemiminorAxis-1._wp, lat2, lon2, alt2)
91+
call assert_allclose([lat2,lon2,alt2],[90._wp, 0._wp, -1._wp], &
92+
rtol=0.01_wp, err_msg='ecef2geodetic-degrees')
93+
8394
call enu2aer(e1,n1,u1, az2, el2, rng2)
8495
call assert_allclose([az2,el2,rng2],[az,el,rng],err_msg='enu2aer-degrees')
8596

0 commit comments

Comments
 (0)