9 ! Define some private constants
11 real, private
, parameter :: pi
= 3.1415926
12 real, private
, parameter :: deg_per_rad
= 180.0/pi
13 real, private
, parameter :: rad_per_deg
= pi
/ 180.0
14 logical, private
, parameter :: print_detail_map
= .false
.
16 integer, private
, parameter :: stdout
= 6
18 ! Mean Earth Radius in m. The value below is consistent
19 ! with NCEP's routines and grids.
20 ! real, public , parameter :: earth_radius_m = 6371200.0 ! from Brent
21 real, public
, parameter :: earth_radius_m
= 6370000.0
22 real, public
, parameter :: radians_per_degree
= pi
/ 180.0
24 ! Define public parameters
26 ! Projection codes for proj_info structure:
27 integer, public
, parameter :: PROJ_LATLON
= 0
28 integer, public
, parameter :: PROJ_MERC
= 1
29 integer, public
, parameter :: PROJ_LC
= 3
30 integer, public
, parameter :: PROJ_PS
= 5
33 ! Define data structures to define various projections
36 integer :: code
! integer code for projection type
37 real :: lat1
! SW latitude (1,1) in degrees (-90->90N)
38 real :: lon1
! SW longitude (1,1) in degrees (-180->180E)
39 real :: dx
! Grid spacing in meters at truelats, used
40 ! only for ps, lc, and merc projections
41 real :: dlat
! Lat increment for lat/lon grids
42 real :: dlon
! Lon increment for lat/lon grids
43 real :: stdlon
! Longitude parallel to y-axis (-180->180E)
44 real :: truelat1
! First true latitude (all projections)
45 real :: truelat2
! Second true lat (LC only)
46 real :: hemi
! 1 for NH, -1 for SH
47 real :: cone
! Cone factor for LC projections
48 real :: polei
! Computed i-location of pole point
49 real :: polej
! Computed j-location of pole point
50 real :: rsw
! Computed radius to SW corner
51 real :: rebydx
! Earth radius divided by dx
52 real :: knowni
! X-location of known lat/lon
53 real :: knownj
! Y-location of known lat/lon
54 real :: latinc
! Latitude increments in degrees
55 real :: loninc
! Longitude increments in degrees
56 logical :: init
! Flag to indicate if this struct is
60 type(proj_info
) :: map_info
62 character(len
=10000),private
:: message(50)
67 subroutine da_llxy_latlon(lat
, lon
, proj
, x
, y
)
69 !-----------------------------------------------------------------------
70 ! Purpose: Compute the x/y location of a lat/lon on a LATLON grid.
71 !-----------------------------------------------------------------------
75 real, intent(in
) :: lat
76 real, intent(in
) :: lon
77 type(proj_info
), intent(in
) :: proj
78 real, intent(out
) :: x
79 real, intent(out
) :: y
87 ! Extract the latitude and longitude increments for this grid
88 ! (e.g., 2.5 deg for NCEP reanalysis) from the proj structure, where
89 ! loninc is saved in the stdlon tag and latinc is saved in truelat1
91 latinc
= proj
%truelat1
94 ! Compute deltalat and deltalon as the difference between the input
95 ! lat/lon and the origin lat/lon
97 deltalat
= lat
- proj
%lat1
99 ! To account for issues around the dateline, convert the incoming
100 ! longitudes to be 0->360.0
106 deltalon
= lon360
- proj
%lon1
109 x
= deltalon
/loninc
+ 1.0
110 y
= deltalat
/latinc
+ 1.0
112 end subroutine da_llxy_latlon
115 subroutine da_llxy_lc(lat
, lon
, proj
, x
, y
)
117 !-----------------------------------------------------------------------
118 ! Purpose: compute the geographical latitude and longitude values
119 ! to the cartesian x/y on a Lambert Conformal projection.
120 !-----------------------------------------------------------------------
124 real, intent(in
) :: lat
! Latitude (-90->90 deg N)
125 real, intent(in
) :: lon
! Longitude (-180->180 E)
126 type(proj_info
),intent(in
) :: proj
! Projection info structure
128 real, intent(out
) :: x
! Cartesian X coordinate
129 real, intent(out
) :: y
! Cartesian Y coordinate
137 ! Compute deltalon between known longitude and standard lon and ensure
138 ! it is not in the cut zone
139 deltalon
= lon
- proj
%stdlon
140 if (deltalon
> +180.0) deltalon
= deltalon
- 360.0
141 if (deltalon
< -180.0) deltalon
= deltalon
+ 360.0
143 ! Convert truelat1 to radian and compute COS for later use
144 tl1r
= proj
%truelat1
* rad_per_deg
147 ! Radius to desired point
148 rm
= proj
%rebydx
* ctl1r
/proj
%cone
* &
149 (TAN((90.0*proj
%hemi
-lat
)*rad_per_deg
/2.0) / &
150 TAN((90.0*proj
%hemi
-proj
%truelat1
)*rad_per_deg
/2.0))**proj
%cone
152 arg
= proj
%cone
*(deltalon
*rad_per_deg
)
153 x
= proj
%polei
+ proj
%hemi
* rm
* Sin(arg
)
154 y
= proj
%polej
- rm
* COS(arg
)
156 ! Finally, if we are in the southern hemisphere, flip the i/j
157 ! values to a coordinate system where (1,1) is the SW corner
158 ! (what we assume) which is different than the original NCEP
159 ! algorithms which used the NE corner as the origin in the
160 ! southern hemisphere (left-hand vs. right-hand coordinate?)
161 if (proj
%hemi
== -1.0) then
166 end subroutine da_llxy_lc
169 subroutine da_llxy_merc(lat
, lon
, proj
, x
, y
)
171 !-----------------------------------------------------------------------
172 ! Purpose: Compute x,y coordinate from lat lon for mercator projection
173 !-----------------------------------------------------------------------
177 real, intent(in
) :: lat
178 real, intent(in
) :: lon
179 type(proj_info
),intent(in
) :: proj
180 real,intent(out
) :: x
181 real,intent(out
) :: y
184 deltalon
= lon
- proj
%lon1
185 if (deltalon
< -180.0) deltalon
= deltalon
+ 360.0
186 if (deltalon
> 180.0) deltalon
= deltalon
- 360.0
187 x
= 1.0 + (deltalon
/(proj
%dlon
*deg_per_rad
))
188 y
= 1.0 + (ALOG(TAN(0.5*((lat
+ 90.0) * rad_per_deg
)))) / &
191 end subroutine da_llxy_merc
194 subroutine da_llxy_ps(lat
,lon
,proj
,x
,y
)
196 !-----------------------------------------------------------------------
197 ! Purpose: Given latitude (-90 to 90), longitude (-180 to 180), and the
198 ! standard polar-stereographic projection information via the
199 ! public proj structure, this routine returns the x/y indices which
200 ! if within the domain range from 1->nx and 1->ny, respectively.
201 !-----------------------------------------------------------------------
205 real, intent(in
) :: lat
206 real, intent(in
) :: lon
207 type(proj_info
),intent(in
) :: proj
209 real, intent(out
) :: x
!(x-index)
210 real, intent(out
) :: y
!(y-index)
218 reflon
= proj
%stdlon
+ 90.0
220 ! Compute numerator term of map scale factor
222 scale_top
= 1.0 + proj
%hemi
* Sin(proj
%truelat1
* rad_per_deg
)
224 ! Find radius to desired point
225 ala
= lat
* rad_per_deg
226 rm
= proj
%rebydx
* COS(ala
) * scale_top
/(1.0 + proj
%hemi
*Sin(ala
))
227 alo
= (lon
- reflon
) * rad_per_deg
228 x
= proj
%polei
+ rm
* COS(alo
)
229 y
= proj
%polej
+ proj
%hemi
* rm
* Sin(alo
)
231 end subroutine da_llxy_ps
234 subroutine da_llxy_wrf(proj
, lat
, lon
, x
, y
)
236 !-----------------------------------------------------------------------
237 ! Purpose: Converts input lat/lon values to the cartesian (x, y) value
238 ! for the given projection.
239 !-----------------------------------------------------------------------
243 type(proj_info
), intent(in
) :: proj
244 real, intent(in
) :: lat
245 real, intent(in
) :: lon
246 real, intent(out
) :: x
247 real, intent(out
) :: y
249 if (.NOT
.proj
%init
) then
250 write(stdout
,*) "da_llxy_wrf.inc"// &
251 "You have not called map_set for this projection!"
255 select
case(proj
%code
)
258 call da_llxy_latlon(lat
,lon
,proj
,x
,y
)
261 call da_llxy_merc(lat
,lon
,proj
,x
,y
)
262 x
= x
+ proj
%knowni
- 1.0
263 y
= y
+ proj
%knownj
- 1.0
266 call da_llxy_ps(lat
,lon
,proj
,x
,y
)
269 call da_llxy_lc(lat
,lon
,proj
,x
,y
)
270 x
= x
+ proj
%knowni
- 1.0
271 y
= y
+ proj
%knownj
- 1.0
274 write(unit
=message(1),fmt
='(A,I2)') &
275 'Unrecognized map projection code: ', proj
%code
276 write(stdout
,*) "da_llxy_wrf.inc"//message(1:1)
280 end subroutine da_llxy_wrf
283 subroutine da_xyll(proj
, xx
, yy
, lat
, lon
)
285 !-----------------------------------------------------------------------
286 ! Purpose: Computes geographical latitude and longitude for a given (i,j)
287 ! point in a grid with a projection of proj
288 !-----------------------------------------------------------------------
292 type(proj_info
), intent(in
) :: proj
293 real, intent(in
) :: xx
294 real, intent(in
) :: yy
295 real, intent(out
) :: lat
296 real, intent(out
) :: lon
300 if (.NOT
.proj
%init
) then
301 write(stdout
,*) "da_xyll.inc"// &
302 "You have not called map_set for this projection!"
309 select
case (proj
%code
)
311 call da_xyll_latlon(x
, y
, proj
, lat
, lon
)
314 x
= xx
- proj
%knowni
+ 1.0
315 y
= yy
- proj
%knownj
+ 1.0
316 call da_xyll_merc(x
, y
, proj
, lat
, lon
)
319 call da_xyll_ps(x
, y
, proj
, lat
, lon
)
323 x
= xx
- proj
%knowni
+ 1.0
324 y
= yy
- proj
%knownj
+ 1.0
325 call da_xyll_lc(x
, y
, proj
, lat
, lon
)
328 write(unit
=message(1),fmt
='(A,I2)') &
329 "Unrecognized map projection code: ", proj
%code
330 write(stdout
,*) "da_xyll.inc"//message(1:1)
335 end subroutine da_xyll
338 subroutine da_xyll_latlon(x
, y
, proj
, lat
, lon
)
340 !-----------------------------------------------------------------------
341 ! Purpose: Compute the lat/lon location of an x/y on a LATLON grid.
342 !-----------------------------------------------------------------------
346 real, intent(in
) :: x
347 real, intent(in
) :: y
348 type(proj_info
), intent(in
) :: proj
349 real, intent(out
) :: lat
350 real, intent(out
) :: lon
357 ! Extract the latitude and longitude increments for this grid
358 ! (e.g., 2.5 deg for NCEP reanalysis) from the proj structure, where
359 ! loninc is saved in the stdlon tag and latinc is saved in truelat1
361 latinc
= proj
%truelat1
364 ! Compute deltalat and deltalon
366 deltalat
= (x
-1.0)*latinc
367 deltalon
= (y
-1.0)*loninc
368 lat
= proj
%lat1
+ deltalat
369 lon
= proj
%lon1
+ deltalon
371 if ((ABS(lat
) > 90.0).OR
.(ABS(deltalon
) > 360.0)) then
372 ! Off the earth for this grid
378 if (lon
> 180.0) lon
= lon
-360.0
381 end subroutine da_xyll_latlon
384 subroutine da_xyll_lc(x
, y
, proj
, lat
, lon
)
386 ! subroutine da_to convert from the (x,y) cartesian coordinate to the
387 ! geographical latitude and longitude for a Lambert Conformal projection.
391 real, intent(in
) :: x
! Cartesian X coordinate
392 real, intent(in
) :: y
! Cartesian Y coordinate
393 type(proj_info
),intent(in
) :: proj
! Projection info structure
396 real, intent(out
) :: lat
! Latitude (-90->90 deg N)
397 real, intent(out
) :: lon
! Longitude (-180->180 E)
402 real :: chi
,chi1
,chi2
407 chi1
= (90.0 - proj
%hemi
*proj
%truelat1
)*rad_per_deg
408 chi2
= (90.0 - proj
%hemi
*proj
%truelat2
)*rad_per_deg
410 ! See if we are in the southern hemispere and flip the indices
412 if (proj
%hemi
== -1.0) then
420 ! Compute radius**2 to i/j location
421 xx
= inew
- proj
%polei
422 yy
= proj
%polej
- jnew
424 r
= sqrt(r2
)/proj
%rebydx
428 lat
= proj
%hemi
* 90.0
433 lon
= proj
%stdlon
+ deg_per_rad
* ATAN2(proj
%hemi
*xx
,yy
)/proj
%cone
434 lon
= MOD(lon
+360.0, 360.0)
436 ! Latitude. Latitude determined by solving an equation adapted
438 ! Maling, D.H., 1973: Coordinate Systems and Map Projections
439 ! Equations #20 in Appendix I.
441 if (chi1
== chi2
) then
442 chi
= 2.0*ATAN((r
/TAN(chi1
))**(1.0/proj
%cone
) * TAN(chi1
*0.5))
444 chi
= 2.0*ATAN((r
*proj
%cone
/Sin(chi1
))**(1.0/proj
%cone
) * TAN(chi1
*0.5))
446 lat
= (90.0-chi
*deg_per_rad
)*proj
%hemi
449 if (lon
> +180.0) lon
= lon
- 360.0
450 if (lon
< -180.0) lon
= lon
+ 360.0
452 end subroutine da_xyll_lc
455 subroutine da_xyll_merc(x
, y
, proj
, lat
, lon
)
457 !-----------------------------------------------------------------------
458 ! Compute the lat/lon from i/j for mercator projection
459 !-----------------------------------------------------------------------
465 type(proj_info
),intent(in
) :: proj
466 real, intent(out
) :: lat
467 real, intent(out
) :: lon
469 lat
= 2.0*ATAN(EXP(proj
%dlon
*(proj
%rsw
+ y
-1.0)))*deg_per_rad
- 90.0
470 lon
= (x
-1.0)*proj
%dlon
*deg_per_rad
+ proj
%lon1
471 if (lon
> 180.0) lon
= lon
- 360.0
472 if (lon
< -180.0) lon
= lon
+ 360.0
474 end subroutine da_xyll_merc
477 subroutine da_xyll_ps(x
, y
, proj
, lat
, lon
)
479 ! This is the inverse subroutine da_of llij_ps. It returns the
480 ! latitude and longitude of an x/y point given the projection info
485 real, intent(in
) :: x
! Column
486 real, intent(in
) :: y
! Row
487 type (proj_info
), intent(in
) :: proj
489 real, intent(out
) :: lat
! -90 -> 90 North
490 real, intent(out
) :: lon
! -180 -> 180 East
498 ! Compute the reference longitude by rotating 90 degrees to the east
499 ! to find the longitude line parallel to the positive x-axis.
500 reflon
= proj
%stdlon
+ 90.0
502 ! Compute numerator term of map scale factor
503 scale_top
= 1.0 + proj
%hemi
* Sin(proj
%truelat1
* rad_per_deg
)
505 ! Compute radius to point of interest
507 yy
= (y
- proj
%polej
) * proj
%hemi
512 lat
= proj
%hemi
* 90.0
515 gi2
= (proj
%rebydx
* scale_top
)**2.0
516 lat
= deg_per_rad
* proj
%hemi
* ASin((gi2
-r2
)/(gi2
+r2
))
517 arccos
= ACOS(xx
/sqrt(r2
))
519 lon
= reflon
+ deg_per_rad
* arccos
521 lon
= reflon
- deg_per_rad
* arccos
525 ! Convert to a -180 -> 180 East convention
526 if (lon
> 180.0) lon
= lon
- 360.0
527 if (lon
< -180.0) lon
= lon
+ 360.0
529 end subroutine da_xyll_ps
532 subroutine da_set_lc(proj
)
534 !-----------------------------------------------------------------------
535 ! Purpose: Initialize the remaining items in the proj structure for a
536 ! lambert conformal grid.
537 !-----------------------------------------------------------------------
541 type(proj_info
), intent(inout
) :: proj
548 ! Compute cone factor
549 call da_lc_cone(proj
%truelat1
, proj
%truelat2
, proj
%cone
)
550 if (print_detail_map
) then
551 write(unit
=stdout
, fmt
='(A,F8.6)') 'Computed cone factor: ', proj
%cone
553 ! Compute longitude differences and ensure we stay out of the
554 ! forbidden "cut zone"
555 deltalon1
= proj
%lon1
- proj
%stdlon
556 if (deltalon1
.gt
. +180.0) deltalon1
= deltalon1
- 360.0
557 if (deltalon1
.lt
. -180.0) deltalon1
= deltalon1
+ 360.0
559 ! Convert truelat1 to radian and compute COS for later use
560 tl1r
= proj
%truelat1
* rad_per_deg
563 ! Compute the radius to our known lower-left (SW) corner
564 proj
%rsw
= proj
%rebydx
* ctl1r
/proj
%cone
* &
565 (TAN((90.0*proj
%hemi
-proj
%lat1
)*rad_per_deg
/2.0) / &
566 TAN((90.0*proj
%hemi
-proj
%truelat1
)*rad_per_deg
/2.0))**proj
%cone
569 arg
= proj
%cone
*(deltalon1
*rad_per_deg
)
570 proj
%polei
= 1.0 - proj
%hemi
* proj
%rsw
* Sin(arg
)
571 proj
%polej
= 1.0 + proj
%rsw
* COS(arg
)
572 if (print_detail_map
) then
573 write(unit
=stdout
,fmt
='(A,2F10.3)') 'Computed pole i/j = ', proj
%polei
, proj
%polej
576 end subroutine da_set_lc
579 subroutine da_set_ps(proj
)
581 ! Initializes a polar-stereographic map projection from the partially
582 ! filled proj structure. This routine computes the radius to the
583 ! southwest corner and computes the i/j location of the pole for use
584 ! in llij_ps and ijll_ps.
588 type(proj_info
), intent(inout
) :: proj
595 ! To define the cone factor for polar stereographic projection
598 reflon
= proj
%stdlon
+ 90.0
600 ! Compute numerator term of map scale factor
601 scale_top
= 1.0 + proj
%hemi
* Sin(proj
%truelat1
* rad_per_deg
)
603 ! Compute radius to lower-left (SW) corner
604 ala1
= proj
%lat1
* rad_per_deg
605 proj
%rsw
= proj
%rebydx
*COS(ala1
)*scale_top
/(1.0+proj
%hemi
*Sin(ala1
))
607 ! Find the pole point
608 alo1
= (proj
%lon1
- reflon
) * rad_per_deg
609 proj
%polei
= proj
%knowni
- proj
%rsw
* COS(alo1
)
610 proj
%polej
= proj
%knownj
- proj
%hemi
* proj
%rsw
* Sin(alo1
)
611 if (print_detail_map
) then
612 write(unit
=stdout
,fmt
='(A,2F10.1)') 'Computed (I,J) of pole point: ',proj
%polei
,proj
%polej
615 end subroutine da_set_ps
618 subroutine da_map_init(proj
)
620 !-----------------------------------------------------------------------
621 ! Purpose: Initializes the map projection structure to missing values
622 !-----------------------------------------------------------------------
626 type(proj_info
), intent(inout
) :: proj
632 proj
%truelat1
= -999.9
633 proj
%truelat2
= -999.9
645 end subroutine da_map_init
648 subroutine da_map_set(proj_code
,lat1
,lon1
,knowni
,knownj
,dx
,stdlon
,truelat1
,truelat2
,latinc
,loninc
,proj
)
649 ! Given a partially filled proj_info structure, this routine computes
650 ! polei, polej, rsw, and cone (if LC projection) to complete the
651 ! structure. This allows us to eliminate redundant calculations when
652 ! calling the coordinate conversion routines multiple times for the
654 ! This will generally be the first routine called when a user wants
655 ! to be able to use the coordinate conversion routines, and it
656 ! will call the appropriate subroutines based on the
657 ! proj%code which indicates which projection type this is.
661 integer, intent(in
) :: proj_code
662 real, intent(in
) :: lat1
663 real, intent(in
) :: lon1
664 real, intent(in
) :: dx
665 real, intent(in
) :: stdlon
666 real, intent(in
) :: truelat1
667 real, intent(in
) :: truelat2
668 real, intent(in
) :: knowni
, knownj
669 real, intent(in
) :: latinc
, loninc
670 type(proj_info
), intent(out
) :: proj
672 ! First, check for validity of mandatory variables in proj
673 if (ABS(lat1
) > 90.0) then
674 write(stdout
,*) "da_map_set.inc"// &
675 "Latitude of origin corner required as follows: -90N <= lat1 < = 90N"
678 if (ABS(lon1
) > 180.0) then
679 write(stdout
,*) "da_map_set.inc"// &
680 "Longitude of origin required as follows: -180E <= lon1 <= 180W"
683 if ((dx
.LE
. 0.0).AND
.(proj_code
.NE
. PROJ_LATLON
)) then
684 write(stdout
,*) "da_map_set.inc"// &
685 "Require grid spacing (dx) in meters be positive!"
688 if ((ABS(stdlon
) > 180.0).AND
.(proj_code
.NE
. PROJ_MERC
)) then
689 write(stdout
,*) "da_map_set.inc"// &
690 "Need orientation longitude (stdlon) as: -180E <= lon1 <= 180W"
693 if (proj
%code
.NE
. PROJ_LATLON
.and
. ABS(truelat1
)>90.0) then
694 write(stdout
,*) "da_map_set.inc"// &
695 "Set true latitude 1 for all projections!"
699 call da_map_init(proj
)
700 proj
%code
= proj_code
707 proj
%truelat1
= truelat1
708 proj
%truelat2
= truelat2
711 if (proj
%code
.NE
. PROJ_LATLON
) then
713 if (truelat1
< 0.0) then
718 proj
%rebydx
= earth_radius_m
/ dx
720 pick_proj
: select
case(proj
%code
)
723 if (print_detail_map
) then
724 write(unit
=stdout
,fmt
='(A)') 'Setting up POLAR STEREOGRAPHIC map...'
729 if (print_detail_map
) then
730 write(unit
=stdout
,fmt
='(A)') 'Setting up LAMBERT CONFORMAL map...'
732 if (ABS(proj
%truelat2
) > 90.0) then
733 if (print_detail_map
) then
734 write(unit
=stdout
,fmt
='(A)') 'Second true latitude not set, assuming a tangent'
735 write(unit
=stdout
,fmt
='(A,F10.3)') 'projection at truelat1: ', proj
%truelat1
737 proj
%truelat2
=proj
%truelat1
742 if (print_detail_map
) then
743 write(unit
=stdout
,fmt
='(A)') 'Setting up MERCATOR map...'
745 call da_set_merc(proj
)
748 if (print_detail_map
) then
749 write(unit
=stdout
,fmt
='(A)') 'Setting up CYLinDRICAL EQUIDISTANT LATLON map...'
751 ! Convert lon1 to 0->360 notation
752 if (proj
%lon1
< 0.0) proj
%lon1
= proj
%lon1
+ 360.0
756 write(unit
=message(1),fmt
='(A,I2)') 'Unknown projection code: ', proj
%code
757 write(stdout
,*) "da_map_set.inc"//message(1:1)
763 end subroutine da_map_set
766 subroutine da_set_merc(proj
)
768 !--------------------------------------------------------------------------
769 ! Purpose: Sets up the remaining basic elements for the mercator projection
770 !--------------------------------------------------------------------------
774 type(proj_info
), intent(inout
) :: proj
778 ! Preliminary variables
780 clain
= COS(rad_per_deg
*proj
%truelat1
)
781 proj
%dlon
= proj
%dx
/ (earth_radius_m
* clain
)
783 ! Compute distance from equator to origin, and store in the
787 if (proj
%lat1
.NE
. 0.0) then
788 proj
%rsw
= (alog(tan(0.5*((proj
%lat1
+90.)*rad_per_deg
))))/proj
%dlon
791 end subroutine da_set_merc
794 subroutine da_lc_cone(truelat1
, truelat2
, cone
)
796 !------------------------------------------------------------------------
797 ! Purpose: compute the cone factor of a Lambert Conformal projection
798 !------------------------------------------------------------------------
802 real, intent(in
) :: truelat1
! (-90 -> 90 degrees N)
803 real, intent(in
) :: truelat2
! " " " " "
804 real, intent(out
) :: cone
806 ! First, see if this is a secant or tangent projection. For tangent
807 ! projections, truelat1 = truelat2 and the cone is tangent to the
808 ! Earth's surface at this latitude. For secant projections, the cone
809 ! intersects the Earth's surface at each of the distinctly different
811 if (abs(truelat1
-truelat2
) > 0.1) then
812 cone
= alog10(cos(truelat1
*rad_per_deg
)) - &
813 alog10(cos(truelat2
*rad_per_deg
))
814 cone
= cone
/(alog10(tan((45.0 - abs(truelat1
)/2.0) * rad_per_deg
)) - &
815 alog10(tan((45.0 - abs(truelat2
)/2.0) * rad_per_deg
)))
817 cone
= sin(abs(truelat1
)*rad_per_deg
)
820 end subroutine da_lc_cone
822 end module da_verif_tools