| 1 | ! $Id: occ_point.f90 2019 2009-01-14 10:20:26Z frhl $
|
|---|
| 2 |
|
|---|
| 3 | !****f* Coordinates/occ_point
|
|---|
| 4 | !
|
|---|
| 5 | ! NAME
|
|---|
| 6 | ! occ_point - Determine the occultation point
|
|---|
| 7 | !
|
|---|
| 8 | ! SYNOPSIS
|
|---|
| 9 | ! call occ_point(r_leo, r_gns, lat, lon, r_coc, roc, azimuth, undulation,
|
|---|
| 10 | ! cfile, efile)
|
|---|
| 11 | !
|
|---|
| 12 | ! DESCRIPTION
|
|---|
| 13 | ! This subroutine calculates the lowest occultation perigree point projected
|
|---|
| 14 | ! to the Earth's surface
|
|---|
| 15 | !
|
|---|
| 16 | ! INPUTS
|
|---|
| 17 | ! r_leo cartesian LEO position vector (relative to ECF frame)
|
|---|
| 18 | ! r_gns cartesian GPS position vector (relative to ECF frame)
|
|---|
| 19 | ! cfile path to geoid potential coefficients file (optional)
|
|---|
| 20 | ! efile path to geoid potential corrections file (optional)
|
|---|
| 21 | !
|
|---|
| 22 | ! OUTPUT
|
|---|
| 23 | ! lat Occultation point latitude
|
|---|
| 24 | ! lon Occultation point longitude
|
|---|
| 25 | ! r_coc Cartesian centre of curvature vector for occ point (ECF)
|
|---|
| 26 | ! roc Radius of curvature value for occultation point
|
|---|
| 27 | ! azimuth GPS to LEO azimuth direction wrt true North (deg)
|
|---|
| 28 | ! undulation Difference between ellipsoid (WGS-84) and EGM-96 geoid (m)
|
|---|
| 29 | !
|
|---|
| 30 | ! SEE ALSO
|
|---|
| 31 | !
|
|---|
| 32 | ! REFERENCES
|
|---|
| 33 | !
|
|---|
| 34 | ! AUTHOR
|
|---|
| 35 | ! Met Office, Exeter, UK.
|
|---|
| 36 | ! Any comments on this software should be given via the ROM SAF
|
|---|
| 37 | ! Helpdesk at http://www.romsaf.org
|
|---|
| 38 | !
|
|---|
| 39 | ! COPYRIGHT
|
|---|
| 40 | ! (c) EUMETSAT. All rights reserved.
|
|---|
| 41 | ! For further details please refer to the file COPYRIGHT
|
|---|
| 42 | ! which you should have received as part of this distribution.
|
|---|
| 43 | !
|
|---|
| 44 | !****
|
|---|
| 45 |
|
|---|
| 46 | subroutine occ_point(r_leo, r_gns, lat, lon, r_coc, roc, azimuth, &
|
|---|
| 47 | undulation, cfile,efile)
|
|---|
| 48 |
|
|---|
| 49 | ! 1.1 Declarations
|
|---|
| 50 | ! ----------------
|
|---|
| 51 |
|
|---|
| 52 | use typesizes, only: wp => EightByteReal
|
|---|
| 53 | use coordinates, not_this => occ_point
|
|---|
| 54 | use EarthMod, only: datum_hmsl
|
|---|
| 55 |
|
|---|
| 56 | implicit none
|
|---|
| 57 |
|
|---|
| 58 | real(wp), dimension(:,:), intent(in) :: r_leo ! LEO position vector (ECF)
|
|---|
| 59 | real(wp), dimension(:,:), intent(in) :: r_gns ! GPS position vector (ECF)
|
|---|
| 60 | real(wp), intent(out) :: lat ! Occultation point latitude
|
|---|
| 61 | real(wp), intent(out) :: lon ! Occultation point longitude
|
|---|
| 62 | real(wp), dimension(size(r_leo,2)), intent(out) :: r_coc ! Centre curvature
|
|---|
| 63 | real(wp), intent(out) :: roc ! Radius curvature
|
|---|
| 64 | real(wp), intent(out) :: azimuth ! Azimuth (deg)
|
|---|
| 65 | real(wp), intent(out) :: undulation ! Undulation
|
|---|
| 66 | character(len=*), optional, intent(in) :: cfile ! Coefficient file path
|
|---|
| 67 | character(len=*), optional, intent(in) :: efile ! Corrections file path
|
|---|
| 68 |
|
|---|
| 69 | real(wp), dimension(size(r_leo,1),size(r_leo,2)) :: perigee
|
|---|
| 70 | real(wp) :: slta ! Straight line tangent ht
|
|---|
| 71 | real(wp) :: ro ! Length of r_leo
|
|---|
| 72 | real(wp) :: alpha ! Angle r_leo and perigee
|
|---|
| 73 | real(wp) :: theta ! Cross section azimuth
|
|---|
| 74 | real(wp), dimension(size(r_leo,1)) :: height_per
|
|---|
| 75 | real(wp), dimension(size(r_leo,1)) :: lat_per
|
|---|
| 76 | real(wp), dimension(size(r_leo,1)) :: lon_per
|
|---|
| 77 | real(wp), dimension(3), parameter :: pa = (/0,0,1/) ! Polar axis
|
|---|
| 78 |
|
|---|
| 79 | integer:: i, iocc
|
|---|
| 80 |
|
|---|
| 81 | do i=1,size(r_leo,1)
|
|---|
| 82 |
|
|---|
| 83 | ! 1.2 Determine ray tangent points
|
|---|
| 84 | ! --------------------------------
|
|---|
| 85 |
|
|---|
| 86 | slta = impact_parameter(r_leo(i,:), r_gns(i,:))
|
|---|
| 87 | ro = Sqrt(Dot_Product(r_leo(i,:), r_leo(i,:)))
|
|---|
| 88 | alpha = acos(slta/ro)
|
|---|
| 89 |
|
|---|
| 90 | perigee(i,:) = rotate(r_leo(i,:), vector_product(r_leo(i,:), r_gns(i,:)), alpha) * (slta/ro)
|
|---|
| 91 |
|
|---|
| 92 | enddo
|
|---|
| 93 |
|
|---|
| 94 | ! 1.3 Convert cartesian to geodetic points
|
|---|
| 95 | ! ----------------------------------------
|
|---|
| 96 |
|
|---|
| 97 | call cart2geod(perigee, lat_per, lon_per, height_per)
|
|---|
| 98 |
|
|---|
| 99 | ! 1.4 Find the lowest perigee
|
|---|
| 100 | ! ---------------------------
|
|---|
| 101 |
|
|---|
| 102 | iocc = Sum(MinLoc(Abs(height_per)))
|
|---|
| 103 |
|
|---|
| 104 | ! 1.5 Define occultation point latitude and longitude
|
|---|
| 105 | ! ---------------------------------------------------
|
|---|
| 106 |
|
|---|
| 107 | lat = lat_per(iocc)
|
|---|
| 108 | lon = lon_per(iocc)
|
|---|
| 109 |
|
|---|
| 110 | ! 1.6 Determine occultation point centre of curvature and radius
|
|---|
| 111 | ! --------------------------------------------------------------
|
|---|
| 112 |
|
|---|
| 113 | ! 1.6.1 Cross-section azimuth
|
|---|
| 114 |
|
|---|
| 115 | theta = vector_angle( vector_product(perigee(iocc,:), pa), &
|
|---|
| 116 | vector_product(r_gns(iocc,:), r_leo(iocc,:)), &
|
|---|
| 117 | -perigee(iocc,:) )
|
|---|
| 118 |
|
|---|
| 119 | azimuth = theta * rad2deg
|
|---|
| 120 |
|
|---|
| 121 | if ( azimuth < 0.0_wp ) azimuth = azimuth + 360.0_wp
|
|---|
| 122 |
|
|---|
| 123 | ! 1.6.2 Compute curvature
|
|---|
| 124 |
|
|---|
| 125 | call curvature(lat, lon, theta, r_coc, roc)
|
|---|
| 126 |
|
|---|
| 127 | ! 1.7 Find undulation - height difference between local ellipsoid and geoid
|
|---|
| 128 | ! -------------------------------------------------------------------------
|
|---|
| 129 |
|
|---|
| 130 | if (present(cfile) .and. present(efile)) then
|
|---|
| 131 | call datum_hmsl("WGS84", (/lat, lon, 0.0_wp/), undulation, cfile, efile)
|
|---|
| 132 | else
|
|---|
| 133 | call datum_hmsl("WGS84", (/lat, lon, 0.0_wp/), undulation)
|
|---|
| 134 | endif
|
|---|
| 135 | if (undulation > -999999.000) undulation = -1.0_wp * undulation
|
|---|
| 136 |
|
|---|
| 137 | end subroutine occ_point
|
|---|
| 138 |
|
|---|
| 139 |
|
|---|
| 140 |
|
|---|