source: trunk/SRC/Interpolation/map_npoints.pro @ 136

Last change on this file since 136 was 136, checked in by pinsard, 18 years ago

some improvements and corrections in some .pro file according to
aspell and idldoc log file

  • Property svn:keywords set to Id
File size: 6.1 KB
Line 
1;+
2;
3; @file_comments
4; Return the distance in meter between all np0 points P0 and all
5; np1 points P1 on a sphere. If keyword /TWO_BY_TWO is given then
6; returns the distances between number n of P0 points and number
7; n of P1 points (in that case, np0 and np1 must be equal).
8; Same as map_2points with the meter parameter but for n points
9; without do loop.
10;
11; @categories Maps
12;
13; @param Lon0 {in}{required}
14; @param Lat0 {in}{required}
15; np0 elements vector. longitudes and latitudes of np0 points P0
16;
17; @param Lon1 {in}{required}
18; @param Lat1 {in}{required}
19; np1 elements vector. longitude and latitude of np1 points P1
20;
21; @keyword AZIMUTH
22; A named variable that will receive the azimuth of the great
23; circle connecting the two points, P0 to P1
24;
25; @keyword MIDDLE
26; to get the longitude/latitude of the middle point betwen P0 and P1.
27;
28; @keyword RADIANS
29; if set, inputs and angular outputs are in radians, otherwise degrees.
30;
31; @keyword RADIUS {default=6378206.4d0}
32; If given, return the distance between the two points calculated using the
33; given radius.
34; Default value is the Earth radius.
35;
36; @keyword TWO_BY_TWO
37; If given,then Map_nPoints returns the distances between number n of
38; P0 points and number n of P1 points
39; In that case, np0 and np1 must be equal.
40;
41; @returns
42; An (np0,np1) array giving the distance in meter between np0
43; points P0 and np1 points P1. Element (i,j) of the ouput is the
44; distance between element P0[i] and P1[j].
45; If keyword /TWO_BY_TWO is given then Map_nPoints returns
46; an np-element vector giving the distance in meter between P0[i]
47; and P1[i] (in that case, we have np0 = np1 = np) ; if /MIDDLE see this keyword.
48; @examples
49; IDL> print, $
50; IDL> map_npoints([-105.15,1],[40.02,1],[-0.07,100,50],[51.30,20,0])
51; 7551369.3 5600334.8
52; 12864354. 10921254.
53; 14919237. 5455558.8
54;
55; IDL> lon0 = [-10, 20, 100]
56; IDL> lat0 = [0, -10, 45]
57; IDL> lon1 = [10, 60, 280]
58; IDL> lat1 = [0, 10, 45]
59; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, AZIMUTH = azi)
60; IDL> help, dist, azi
61; DIST DOUBLE = Array[3, 3]
62; AZI DOUBLE = Array[3, 3]
63; IDL> print, dist[4*lindgen(3)], azi[4*lindgen(3)]
64; 2226414.0 4957944.5 10018863.
65; 90.000000 64.494450 4.9615627e-15
66; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, AZIMUTH = azi, /TWO_BY_TWO)
67; IDL> help, dist, azi
68; DIST DOUBLE = Array[3]
69; AZI DOUBLE = Array[3]
70; IDL> print, dist, azi
71; 2226414.0 4957944.5 10018863.
72; 90.000000 64.494450 4.9615627e-15
73; IDL> print, map_2points(lon0[0], lat0[0], lon1[0], lat1[0])
74; 20.000000 90.000000
75; IDL> print, map_npoints(lon0[0], lat0[0], lon1[0], lat1[0], AZIMUTH=azi)/6378206.4d0 / !dtor, azi
76; 20.000000
77; 90.000000
78;
79; IDL> lon0 = [-10, 20, 100]
80; IDL> lat0 = [0, -10, 45]
81; IDL> lon1 = [10, 60, 280]
82; IDL> lat1 = [0, 10, 45]
83; IDL> mid = map_npoints(lon0, lat0, lon1, lat1, /MIDDLE, /TWO_BY_TWO)
84; IDL> print, reform(mid[0,*]), reform(mid[1,*])
85; 0.0000000 40.000000 190.00000
86; 0.0000000 -1.5902773e-15 90.000000
87; IDL> print, (map_2points(lon0[0], lat0[0], lon1[0], lat1[0], npath = 3))[*, 1]
88; 0.0000000 0.0000000
89; IDL> print, (map_2points(lon0[1], lat0[1], lon1[1], lat1[1], npath = 3))[*, 1]
90; 40.000000 -1.5902773e-15
91; IDL> print, (map_2points(lon0[2], lat0[2], lon1[2], lat1[2], npath = 3))[*, 1]
92; 190.00000 90.000000
93;
94; @history
95; Based on the IDL function map_2points.pro,v 1.6 2001/01/15
96; Sebastien Masson (smasson\@lodyc.jussieu.fr)
97; October 2003
98;
99; @version $Id$
100;
101;-
102Function Map_npoints, lon0, lat0, lon1, lat1, AZIMUTH = azimuth $
103 , RADIANS = radians, RADIUS = radius, MIDDLE = middle, TWO_BY_TWO = two_by_two
104
105 COMPILE_OPT idl2, strictarrsubs
106
107 IF (N_PARAMS() LT 4) THEN $
108 MESSAGE, 'Incorrect number of arguments.'
109
110 np0 = n_elements(lon0)
111 IF n_elements(lat0) NE np0 THEN $
112 MESSAGE, 'lon0 and lat0 must have the same number of elements'
113 np1 = n_elements(lon1)
114 IF n_elements(lat1) NE np1 THEN $
115 MESSAGE, 'lon1 and lat1 must have the same number of elements'
116 if keyword_set(two_by_two) AND np0 NE np1 then $
117 MESSAGE, 'When using two_by_two keyword, P0 and P1 must have the same number of elements'
118
119 mx = MAX(ABS([lat0[*], lat1[*]]))
120 pi2 = !dpi/2
121 IF (mx GT (KEYWORD_SET(radians) ? pi2 : 90)) THEN $
122 MESSAGE, 'Value of Latitude is out of allowed range.'
123
124 k = KEYWORD_SET(radians) ? 1.0d0 : !dpi/180.0
125;Earth equatorial radius, meters, Clarke 1866 ellipsoid
126 r_sphere = n_elements(RADIUS) NE 0 ? RADIUS : 6378206.4d0
127;
128 coslt1 = cos(k*lat1[*])
129 sinlt1 = sin(k*lat1[*])
130 coslt0 = cos(k*lat0[*])
131 sinlt0 = sin(k*lat0[*])
132;
133 IF np0 EQ np1 AND np1 EQ 1 THEN two_by_two = 1
134;
135 if NOT keyword_set(two_by_two) THEN BEGIN
136 coslt1 = replicate(1.0d0, np0)#temporary(coslt1)
137 sinlt1 = replicate(1.0d0, np0)#temporary(sinlt1)
138 coslt0 = temporary(coslt0)#replicate(1.0d0, np1)
139 sinlt0 = temporary(sinlt0)#replicate(1.0d0, np1)
140 ENDIF
141;
142 if keyword_set(two_by_two) THEN BEGIN
143 cosl0l1 = cos(k*(lon1[*]-lon0[*]))
144 sinl0l1 = sin(k*(lon1[*]-lon0[*]))
145 ENDIF ELSE BEGIN
146 cosl0l1 = cos(k*(replicate(1.0d0, np0)#lon1[*]-lon0[*]#replicate(1.0d0, np1)))
147 sinl0l1 = sin(k*(replicate(1.0d0, np0)#lon1[*]-lon0[*]#replicate(1.0d0, np1)))
148 ENDELSE
149
150 cosc = sinlt0 * sinlt1 + coslt0 * coslt1 * cosl0l1 ;Cos of angle between pnts
151; Avoid roundoff problems by clamping cosine range to [-1,1].
152 cosc = -1.0d0 > cosc < 1.0d0
153;
154 if arg_present(azimuth) OR keyword_set(middle) then begin
155 sinc = sqrt(1.0d0 - cosc*cosc)
156 bad = where(abs(sinc) le 1.0e-7)
157 IF bad[0] NE -1 THEN sinc[bad] = 1
158 cosaz = (coslt0 * sinlt1 - sinlt0*coslt1*cosl0l1) / sinc
159 sinaz = sinl0l1*coslt1/sinc
160 IF bad[0] NE -1 THEN BEGIN
161 sinc[bad] = 0.0d0
162 sinaz[bad] = 0.0d0
163 cosaz[bad] = 1.0d0
164 ENDIF
165 ENDIF
166;
167 IF keyword_set(middle) then BEGIN
168
169 s0 = 0.5d0 * acos(cosc)
170 ;
171 coss = cos(s0)
172 sins = sin(s0)
173;
174 lats = asin(sinlt0 * coss + coslt0 * sins * cosaz) / k
175 lons = atan(sins * sinaz, coslt0 * coss - sinlt0 * sins * cosaz) / k
176;
177 if keyword_set(two_by_two) THEN BEGIN
178 return, transpose([[lon0[*] + lons], [lats]])
179 ENDIF ELSE BEGIN
180 return, [ [[lon0[*]#replicate(1.0d0, np1) + lons]], [[lats]] ]
181 ENDELSE
182;
183 ENDIF
184;
185 if arg_present(azimuth) then begin
186 azimuth = atan(sinaz, cosaz)
187 IF k NE 1.0d0 THEN azimuth = temporary(azimuth) / k
188 ENDIF
189 return, acos(cosc) * r_sphere
190;
191end
Note: See TracBrowser for help on using the repository browser.