geodesic_wgs84 1.44.1 → 1.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/geodesic_wgs84/geodesic.c +185 -90
- data/ext/geodesic_wgs84/geodesic.h +301 -178
- data/geodesic_wgs84.gemspec +2 -2
- data/lib/geodesic_wgs84/version.rb +1 -1
- metadata +5 -5
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
2
|
* \file geodesic.h
|
3
|
-
* \brief
|
3
|
+
* \brief API for the geodesic routines in C
|
4
4
|
*
|
5
5
|
* This an implementation in C of the geodesic algorithms described in
|
6
6
|
* - C. F. F. Karney,
|
@@ -9,7 +9,7 @@
|
|
9
9
|
* J. Geodesy <b>87</b>, 43--55 (2013);
|
10
10
|
* DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
|
11
11
|
* 10.1007/s00190-012-0578-z</a>;
|
12
|
-
* addenda: <a href="http://geographiclib.
|
12
|
+
* addenda: <a href="http://geographiclib.sourceforge.net/geod-addenda.html">
|
13
13
|
* geod-addenda.html</a>.
|
14
14
|
* .
|
15
15
|
* The principal advantages of these algorithms over previous ones (e.g.,
|
@@ -75,30 +75,29 @@
|
|
75
75
|
* (obviously) uniquely defined. However, in a few special cases there are
|
76
76
|
* multiple azimuths which yield the same shortest distance. Here is a
|
77
77
|
* catalog of those cases:
|
78
|
-
* - \e lat1 = −\e lat2 (with neither point at a pole). If \e azi1 =
|
79
|
-
*
|
80
|
-
*
|
81
|
-
*
|
82
|
-
*
|
83
|
-
*
|
84
|
-
* - \e lon2 = \e lon1 ± 180° (with neither point at a pole).
|
85
|
-
*
|
86
|
-
*
|
87
|
-
*
|
88
|
-
*
|
78
|
+
* - \e lat1 = −\e lat2 (with neither point at a pole). If \e azi1 = \e
|
79
|
+
* azi2, the geodesic is unique. Otherwise there are two geodesics and the
|
80
|
+
* second one is obtained by setting [\e azi1, \e azi2] → [\e azi2, \e
|
81
|
+
* azi1], [\e M12, \e M21] → [\e M21, \e M12], \e S12 → −\e
|
82
|
+
* S12. (This occurs when the longitude difference is near ±180°
|
83
|
+
* for oblate ellipsoids.)
|
84
|
+
* - \e lon2 = \e lon1 ± 180° (with neither point at a pole). If \e
|
85
|
+
* azi1 = 0° or ±180°, the geodesic is unique. Otherwise
|
86
|
+
* there are two geodesics and the second one is obtained by setting [\e
|
87
|
+
* azi1, \e azi2] → [−\e azi1, −\e azi2], \e S12 →
|
88
|
+
* −\e S12. (This occurs when \e lat2 is near −\e lat1 for
|
89
89
|
* prolate ellipsoids.)
|
90
|
-
* - Points 1 and 2 at opposite poles. There are infinitely many
|
91
|
-
*
|
92
|
-
*
|
93
|
-
*
|
94
|
-
*
|
95
|
-
*
|
96
|
-
*
|
97
|
-
* azi2] + [\e d, \e d], for arbitrary \e d.
|
90
|
+
* - Points 1 and 2 at opposite poles. There are infinitely many geodesics
|
91
|
+
* which can be generated by setting [\e azi1, \e azi2] → [\e azi1, \e
|
92
|
+
* azi2] + [\e d, −\e d], for arbitrary \e d. (For spheres, this
|
93
|
+
* prescription applies when points 1 and 2 are antipodal.)
|
94
|
+
* - \e s12 = 0 (coincident points). There are infinitely many geodesics which
|
95
|
+
* can be generated by setting [\e azi1, \e azi2] → [\e azi1, \e azi2] +
|
96
|
+
* [\e d, \e d], for arbitrary \e d.
|
98
97
|
*
|
99
98
|
* These routines are a simple transcription of the corresponding C++ classes
|
100
|
-
* in <a href="http://geographiclib.
|
101
|
-
* data" is represented by the structs geod_geodesic, geod_geodesicline,
|
99
|
+
* in <a href="http://geographiclib.sourceforge.net"> GeographicLib</a>. The
|
100
|
+
* "class data" is represented by the structs geod_geodesic, geod_geodesicline,
|
102
101
|
* geod_polygon and pointers to these objects are passed as initial arguments
|
103
102
|
* to the member functions. Most of the internal comments have been retained.
|
104
103
|
* However, in the process of transcription some documentation has been lost
|
@@ -108,12 +107,12 @@
|
|
108
107
|
* twice about restructuring the internals of the C code since this may make
|
109
108
|
* porting fixes from the C++ code more difficult.
|
110
109
|
*
|
111
|
-
* Copyright (c) Charles Karney (2012-
|
110
|
+
* Copyright (c) Charles Karney (2012-2016) <charles@karney.com> and licensed
|
112
111
|
* under the MIT/X11 License. For more information, see
|
113
112
|
* http://geographiclib.sourceforge.net/
|
114
113
|
*
|
115
114
|
* This library was distributed with
|
116
|
-
* <a href="../index.html">GeographicLib</a> 1.
|
115
|
+
* <a href="../index.html">GeographicLib</a> 1.46.
|
117
116
|
**********************************************************************/
|
118
117
|
|
119
118
|
#if !defined(GEODESIC_H)
|
@@ -128,7 +127,7 @@
|
|
128
127
|
* The minor version of the geodesic library. (This tracks the version of
|
129
128
|
* GeographicLib.)
|
130
129
|
**********************************************************************/
|
131
|
-
#define GEODESIC_VERSION_MINOR
|
130
|
+
#define GEODESIC_VERSION_MINOR 46
|
132
131
|
/**
|
133
132
|
* The patch level of the geodesic library. (This tracks the version of
|
134
133
|
* GeographicLib.)
|
@@ -177,7 +176,8 @@ extern "C" {
|
|
177
176
|
|
178
177
|
/**
|
179
178
|
* The struct containing information about a single geodesic. This must be
|
180
|
-
* initialized by geod_lineinit()
|
179
|
+
* initialized by geod_lineinit(), geod_directline(), geod_gendirectline(),
|
180
|
+
* or geod_inverseline() before use.
|
181
181
|
**********************************************************************/
|
182
182
|
struct geod_geodesicline {
|
183
183
|
double lat1; /**< the starting latitude */
|
@@ -185,9 +185,13 @@ extern "C" {
|
|
185
185
|
double azi1; /**< the starting azimuth */
|
186
186
|
double a; /**< the equatorial radius */
|
187
187
|
double f; /**< the flattening */
|
188
|
+
double salp1; /**< sine of \e azi1 */
|
189
|
+
double calp1; /**< cosine of \e azi1 */
|
190
|
+
double a13; /**< arc length to reference point */
|
191
|
+
double s13; /**< distance to reference point */
|
188
192
|
/**< @cond SKIP */
|
189
193
|
double b, c2, f1, salp0, calp0, k2,
|
190
|
-
|
194
|
+
ssig1, csig1, dn1, stau1, ctau1, somg1, comg1,
|
191
195
|
A1m1, A2m1, A3c, B11, B21, B31, A4, B41;
|
192
196
|
double C1a[6+1], C1pa[6+1], C2a[6+1], C3a[6], C4a[6];
|
193
197
|
/**< @endcond */
|
@@ -222,46 +226,6 @@ extern "C" {
|
|
222
226
|
**********************************************************************/
|
223
227
|
void geod_init(struct geod_geodesic* g, double a, double f);
|
224
228
|
|
225
|
-
/**
|
226
|
-
* Initialize a geod_geodesicline object.
|
227
|
-
*
|
228
|
-
* @param[out] l a pointer to the object to be initialized.
|
229
|
-
* @param[in] g a pointer to the geod_geodesic object specifying the
|
230
|
-
* ellipsoid.
|
231
|
-
* @param[in] lat1 latitude of point 1 (degrees).
|
232
|
-
* @param[in] lon1 longitude of point 1 (degrees).
|
233
|
-
* @param[in] azi1 azimuth at point 1 (degrees).
|
234
|
-
* @param[in] caps bitor'ed combination of geod_mask() values specifying the
|
235
|
-
* capabilities the geod_geodesicline object should possess, i.e., which
|
236
|
-
* quantities can be returned in calls to geod_position() and
|
237
|
-
* geod_genposition().
|
238
|
-
*
|
239
|
-
* \e g must have been initialized with a call to geod_init(). \e lat1
|
240
|
-
* should be in the range [−90°, 90°].
|
241
|
-
*
|
242
|
-
* The geod_mask values are [see geod_mask()]:
|
243
|
-
* - \e caps |= GEOD_LATITUDE for the latitude \e lat2; this is
|
244
|
-
* added automatically,
|
245
|
-
* - \e caps |= GEOD_LONGITUDE for the latitude \e lon2,
|
246
|
-
* - \e caps |= GEOD_AZIMUTH for the latitude \e azi2; this is
|
247
|
-
* added automatically,
|
248
|
-
* - \e caps |= GEOD_DISTANCE for the distance \e s12,
|
249
|
-
* - \e caps |= GEOD_REDUCEDLENGTH for the reduced length \e m12,
|
250
|
-
* - \e caps |= GEOD_GEODESICSCALE for the geodesic scales \e M12
|
251
|
-
* and \e M21,
|
252
|
-
* - \e caps |= GEOD_AREA for the area \e S12,
|
253
|
-
* - \e caps |= GEOD_DISTANCE_IN permits the length of the
|
254
|
-
* geodesic to be given in terms of \e s12; without this capability the
|
255
|
-
* length can only be specified in terms of arc length.
|
256
|
-
* .
|
257
|
-
* A value of \e caps = 0 is treated as GEOD_LATITUDE | GEOD_LONGITUDE |
|
258
|
-
* GEOD_AZIMUTH | GEOD_DISTANCE_IN (to support the solution of the "standard"
|
259
|
-
* direct problem).
|
260
|
-
**********************************************************************/
|
261
|
-
void geod_lineinit(struct geod_geodesicline* l,
|
262
|
-
const struct geod_geodesic* g,
|
263
|
-
double lat1, double lon1, double azi1, unsigned caps);
|
264
|
-
|
265
229
|
/**
|
266
230
|
* Solve the direct geodesic problem.
|
267
231
|
*
|
@@ -270,7 +234,7 @@ extern "C" {
|
|
270
234
|
* @param[in] lat1 latitude of point 1 (degrees).
|
271
235
|
* @param[in] lon1 longitude of point 1 (degrees).
|
272
236
|
* @param[in] azi1 azimuth at point 1 (degrees).
|
273
|
-
* @param[in] s12 distance
|
237
|
+
* @param[in] s12 distance from point 1 to point 2 (meters); it can be
|
274
238
|
* negative.
|
275
239
|
* @param[out] plat2 pointer to the latitude of point 2 (degrees).
|
276
240
|
* @param[out] plon2 pointer to the longitude of point 2 (degrees).
|
@@ -302,6 +266,51 @@ extern "C" {
|
|
302
266
|
double lat1, double lon1, double azi1, double s12,
|
303
267
|
double* plat2, double* plon2, double* pazi2);
|
304
268
|
|
269
|
+
/**
|
270
|
+
* The general direct geodesic problem.
|
271
|
+
*
|
272
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
273
|
+
* ellipsoid.
|
274
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
275
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
276
|
+
* @param[in] azi1 azimuth at point 1 (degrees).
|
277
|
+
* @param[in] flags bitor'ed combination of geod_flags(); \e flags &
|
278
|
+
* GEOD_ARCMODE determines the meaning of \e s12_a12 and \e flags &
|
279
|
+
* GEOD_LONG_UNROLL "unrolls" \e lon2.
|
280
|
+
* @param[in] s12_a12 if \e flags & GEOD_ARCMODE is 0, this is the distance
|
281
|
+
* from point 1 to point 2 (meters); otherwise it is the arc length
|
282
|
+
* from point 1 to point 2 (degrees); it can be negative.
|
283
|
+
* @param[out] plat2 pointer to the latitude of point 2 (degrees).
|
284
|
+
* @param[out] plon2 pointer to the longitude of point 2 (degrees).
|
285
|
+
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
286
|
+
* @param[out] ps12 pointer to the distance from point 1 to point 2
|
287
|
+
* (meters).
|
288
|
+
* @param[out] pm12 pointer to the reduced length of geodesic (meters).
|
289
|
+
* @param[out] pM12 pointer to the geodesic scale of point 2 relative to
|
290
|
+
* point 1 (dimensionless).
|
291
|
+
* @param[out] pM21 pointer to the geodesic scale of point 1 relative to
|
292
|
+
* point 2 (dimensionless).
|
293
|
+
* @param[out] pS12 pointer to the area under the geodesic
|
294
|
+
* (meters<sup>2</sup>).
|
295
|
+
* @return \e a12 arc length from point 1 to point 2 (degrees).
|
296
|
+
*
|
297
|
+
* \e g must have been initialized with a call to geod_init(). \e lat1
|
298
|
+
* should be in the range [−90°, 90°]. The function value \e
|
299
|
+
* a12 equals \e s12_a12 if \e flags & GEOD_ARCMODE. Any of the "return"
|
300
|
+
* arguments, \e plat2, etc., may be replaced by 0, if you do not need some
|
301
|
+
* quantities computed.
|
302
|
+
*
|
303
|
+
* With \e flags & GEOD_LONG_UNROLL bit set, the longitude is "unrolled" so
|
304
|
+
* that the quantity \e lon2 − \e lon1 indicates how many times and in
|
305
|
+
* what sense the geodesic encircles the ellipsoid.
|
306
|
+
**********************************************************************/
|
307
|
+
double geod_gendirect(const struct geod_geodesic* g,
|
308
|
+
double lat1, double lon1, double azi1,
|
309
|
+
unsigned flags, double s12_a12,
|
310
|
+
double* plat2, double* plon2, double* pazi2,
|
311
|
+
double* ps12, double* pm12, double* pM12, double* pM21,
|
312
|
+
double* pS12);
|
313
|
+
|
305
314
|
/**
|
306
315
|
* Solve the inverse geodesic problem.
|
307
316
|
*
|
@@ -311,7 +320,7 @@ extern "C" {
|
|
311
320
|
* @param[in] lon1 longitude of point 1 (degrees).
|
312
321
|
* @param[in] lat2 latitude of point 2 (degrees).
|
313
322
|
* @param[in] lon2 longitude of point 2 (degrees).
|
314
|
-
* @param[out] ps12 pointer to the distance
|
323
|
+
* @param[out] ps12 pointer to the distance from point 1 to point 2
|
315
324
|
* (meters).
|
316
325
|
* @param[out] pazi1 pointer to the azimuth at point 1 (degrees).
|
317
326
|
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
@@ -344,23 +353,181 @@ extern "C" {
|
|
344
353
|
double lat1, double lon1, double lat2, double lon2,
|
345
354
|
double* ps12, double* pazi1, double* pazi2);
|
346
355
|
|
356
|
+
/**
|
357
|
+
* The general inverse geodesic calculation.
|
358
|
+
*
|
359
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
360
|
+
* ellipsoid.
|
361
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
362
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
363
|
+
* @param[in] lat2 latitude of point 2 (degrees).
|
364
|
+
* @param[in] lon2 longitude of point 2 (degrees).
|
365
|
+
* @param[out] ps12 pointer to the distance from point 1 to point 2
|
366
|
+
* (meters).
|
367
|
+
* @param[out] pazi1 pointer to the azimuth at point 1 (degrees).
|
368
|
+
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
369
|
+
* @param[out] pm12 pointer to the reduced length of geodesic (meters).
|
370
|
+
* @param[out] pM12 pointer to the geodesic scale of point 2 relative to
|
371
|
+
* point 1 (dimensionless).
|
372
|
+
* @param[out] pM21 pointer to the geodesic scale of point 1 relative to
|
373
|
+
* point 2 (dimensionless).
|
374
|
+
* @param[out] pS12 pointer to the area under the geodesic
|
375
|
+
* (meters<sup>2</sup>).
|
376
|
+
* @return \e a12 arc length from point 1 to point 2 (degrees).
|
377
|
+
*
|
378
|
+
* \e g must have been initialized with a call to geod_init(). \e lat1 and
|
379
|
+
* \e lat2 should be in the range [−90°, 90°]. Any of the
|
380
|
+
* "return" arguments \e ps12, etc., may be replaced by 0, if you do not need
|
381
|
+
* some quantities computed.
|
382
|
+
**********************************************************************/
|
383
|
+
double geod_geninverse(const struct geod_geodesic* g,
|
384
|
+
double lat1, double lon1, double lat2, double lon2,
|
385
|
+
double* ps12, double* pazi1, double* pazi2,
|
386
|
+
double* pm12, double* pM12, double* pM21,
|
387
|
+
double* pS12);
|
388
|
+
|
389
|
+
/**
|
390
|
+
* Initialize a geod_geodesicline object.
|
391
|
+
*
|
392
|
+
* @param[out] l a pointer to the object to be initialized.
|
393
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
394
|
+
* ellipsoid.
|
395
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
396
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
397
|
+
* @param[in] azi1 azimuth at point 1 (degrees).
|
398
|
+
* @param[in] caps bitor'ed combination of geod_mask() values specifying the
|
399
|
+
* capabilities the geod_geodesicline object should possess, i.e., which
|
400
|
+
* quantities can be returned in calls to geod_position() and
|
401
|
+
* geod_genposition().
|
402
|
+
*
|
403
|
+
* \e g must have been initialized with a call to geod_init(). \e lat1
|
404
|
+
* should be in the range [−90°, 90°].
|
405
|
+
*
|
406
|
+
* The geod_mask values are [see geod_mask()]:
|
407
|
+
* - \e caps |= GEOD_LATITUDE for the latitude \e lat2; this is
|
408
|
+
* added automatically,
|
409
|
+
* - \e caps |= GEOD_LONGITUDE for the latitude \e lon2,
|
410
|
+
* - \e caps |= GEOD_AZIMUTH for the latitude \e azi2; this is
|
411
|
+
* added automatically,
|
412
|
+
* - \e caps |= GEOD_DISTANCE for the distance \e s12,
|
413
|
+
* - \e caps |= GEOD_REDUCEDLENGTH for the reduced length \e m12,
|
414
|
+
* - \e caps |= GEOD_GEODESICSCALE for the geodesic scales \e M12
|
415
|
+
* and \e M21,
|
416
|
+
* - \e caps |= GEOD_AREA for the area \e S12,
|
417
|
+
* - \e caps |= GEOD_DISTANCE_IN permits the length of the
|
418
|
+
* geodesic to be given in terms of \e s12; without this capability the
|
419
|
+
* length can only be specified in terms of arc length.
|
420
|
+
* .
|
421
|
+
* A value of \e caps = 0 is treated as GEOD_LATITUDE | GEOD_LONGITUDE |
|
422
|
+
* GEOD_AZIMUTH | GEOD_DISTANCE_IN (to support the solution of the "standard"
|
423
|
+
* direct problem).
|
424
|
+
*
|
425
|
+
* When initialized by this function, point 3 is undefined (l->s13 = l->a13 =
|
426
|
+
* NaN).
|
427
|
+
**********************************************************************/
|
428
|
+
void geod_lineinit(struct geod_geodesicline* l,
|
429
|
+
const struct geod_geodesic* g,
|
430
|
+
double lat1, double lon1, double azi1, unsigned caps);
|
431
|
+
|
432
|
+
/**
|
433
|
+
* Initialize a geod_geodesicline object in terms of the direct geodesic
|
434
|
+
* problem.
|
435
|
+
*
|
436
|
+
* @param[out] l a pointer to the object to be initialized.
|
437
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
438
|
+
* ellipsoid.
|
439
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
440
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
441
|
+
* @param[in] azi1 azimuth at point 1 (degrees).
|
442
|
+
* @param[in] s12 distance from point 1 to point 2 (meters); it can be
|
443
|
+
* negative.
|
444
|
+
* @param[in] caps bitor'ed combination of geod_mask() values specifying the
|
445
|
+
* capabilities the geod_geodesicline object should possess, i.e., which
|
446
|
+
* quantities can be returned in calls to geod_position() and
|
447
|
+
* geod_genposition().
|
448
|
+
*
|
449
|
+
* This function sets point 3 of the geod_geodesicline to correspond to point
|
450
|
+
* 2 of the direct geodesic problem. See geod_lineinit() for more
|
451
|
+
* informaion.
|
452
|
+
**********************************************************************/
|
453
|
+
void geod_directline(struct geod_geodesicline* l,
|
454
|
+
const struct geod_geodesic* g,
|
455
|
+
double lat1, double lon1, double azi1, double s12,
|
456
|
+
unsigned caps);
|
457
|
+
|
458
|
+
/**
|
459
|
+
* Initialize a geod_geodesicline object in terms of the direct geodesic
|
460
|
+
* problem spacified in terms of either distance or arc length.
|
461
|
+
*
|
462
|
+
* @param[out] l a pointer to the object to be initialized.
|
463
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
464
|
+
* ellipsoid.
|
465
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
466
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
467
|
+
* @param[in] azi1 azimuth at point 1 (degrees).
|
468
|
+
* @param[in] flags either GEOD_NOFLAGS or GEOD_ARCMODE to determining the
|
469
|
+
* meaning of the \e s12_a12.
|
470
|
+
* @param[in] s12_a12 if \e flags = GEOD_NOFLAGS, this is the distance
|
471
|
+
* from point 1 to point 2 (meters); if \e flags = GEOD_ARCMODE, it is
|
472
|
+
* the arc length from point 1 to point 2 (degrees); it can be
|
473
|
+
* negative.
|
474
|
+
* @param[in] caps bitor'ed combination of geod_mask() values specifying the
|
475
|
+
* capabilities the geod_geodesicline object should possess, i.e., which
|
476
|
+
* quantities can be returned in calls to geod_position() and
|
477
|
+
* geod_genposition().
|
478
|
+
*
|
479
|
+
* This function sets point 3 of the geod_geodesicline to correspond to point
|
480
|
+
* 2 of the direct geodesic problem. See geod_lineinit() for more
|
481
|
+
* informaion.
|
482
|
+
**********************************************************************/
|
483
|
+
void geod_gendirectline(struct geod_geodesicline* l,
|
484
|
+
const struct geod_geodesic* g,
|
485
|
+
double lat1, double lon1, double azi1,
|
486
|
+
unsigned flags, double s12_a12,
|
487
|
+
unsigned caps);
|
488
|
+
|
489
|
+
/**
|
490
|
+
* Initialize a geod_geodesicline object in terms of the inverse geodesic
|
491
|
+
* problem.
|
492
|
+
*
|
493
|
+
* @param[out] l a pointer to the object to be initialized.
|
494
|
+
* @param[in] g a pointer to the geod_geodesic object specifying the
|
495
|
+
* ellipsoid.
|
496
|
+
* @param[in] lat1 latitude of point 1 (degrees).
|
497
|
+
* @param[in] lon1 longitude of point 1 (degrees).
|
498
|
+
* @param[in] lat2 latitude of point 2 (degrees).
|
499
|
+
* @param[in] lon2 longitude of point 2 (degrees).
|
500
|
+
* @param[in] caps bitor'ed combination of geod_mask() values specifying the
|
501
|
+
* capabilities the geod_geodesicline object should possess, i.e., which
|
502
|
+
* quantities can be returned in calls to geod_position() and
|
503
|
+
* geod_genposition().
|
504
|
+
*
|
505
|
+
* This function sets point 3 of the geod_geodesicline to correspond to point
|
506
|
+
* 2 of the inverse geodesic problem. See geod_lineinit() for more
|
507
|
+
* informaion.
|
508
|
+
**********************************************************************/
|
509
|
+
void geod_inverseline(struct geod_geodesicline* l,
|
510
|
+
const struct geod_geodesic* g,
|
511
|
+
double lat1, double lon1, double lat2, double lon2,
|
512
|
+
unsigned caps);
|
513
|
+
|
347
514
|
/**
|
348
515
|
* Compute the position along a geod_geodesicline.
|
349
516
|
*
|
350
517
|
* @param[in] l a pointer to the geod_geodesicline object specifying the
|
351
518
|
* geodesic line.
|
352
|
-
* @param[in] s12 distance
|
519
|
+
* @param[in] s12 distance from point 1 to point 2 (meters); it can be
|
353
520
|
* negative.
|
354
521
|
* @param[out] plat2 pointer to the latitude of point 2 (degrees).
|
355
522
|
* @param[out] plon2 pointer to the longitude of point 2 (degrees); requires
|
356
523
|
* that \e l was initialized with \e caps |= GEOD_LONGITUDE.
|
357
524
|
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
358
525
|
*
|
359
|
-
* \e l must have been initialized with a call to geod_lineinit()
|
360
|
-
* caps |= GEOD_DISTANCE_IN. The values of \e lon2 and \e azi2
|
361
|
-
* in the range [−180°, 180°). Any of the
|
362
|
-
* \e plat2, etc., may be replaced by 0, if you do not
|
363
|
-
* computed.
|
526
|
+
* \e l must have been initialized with a call, e.g., to geod_lineinit(),
|
527
|
+
* with \e caps |= GEOD_DISTANCE_IN. The values of \e lon2 and \e azi2
|
528
|
+
* returned are in the range [−180°, 180°). Any of the
|
529
|
+
* "return" arguments \e plat2, etc., may be replaced by 0, if you do not
|
530
|
+
* need some quantities computed.
|
364
531
|
*
|
365
532
|
* Example, compute way points between JFK and Singapore Changi Airport
|
366
533
|
* the "obvious" way using geod_direct():
|
@@ -379,13 +546,12 @@ extern "C" {
|
|
379
546
|
@code{.c}
|
380
547
|
struct geod_geodesic g;
|
381
548
|
struct geod_geodesicline l;
|
382
|
-
double
|
549
|
+
double lat[101],lon[101];
|
383
550
|
int i;
|
384
551
|
geod_init(&g, 6378137, 1/298.257223563);
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
geod_position(&l, i * s12 * 0.01, lat + i, lon + i, 0);
|
552
|
+
geod_inverseline(&l, &g, 40.64, -73.78, 1.36, 103.99, 0);
|
553
|
+
for (i = 0; i <= 100; ++i) {
|
554
|
+
geod_position(&l, i * l.s13 * 0.01, lat + i, lon + i, 0);
|
389
555
|
printf("%.5f %.5f\n", lat[i], lon[i]);
|
390
556
|
}
|
391
557
|
@endcode
|
@@ -393,84 +559,6 @@ extern "C" {
|
|
393
559
|
void geod_position(const struct geod_geodesicline* l, double s12,
|
394
560
|
double* plat2, double* plon2, double* pazi2);
|
395
561
|
|
396
|
-
/**
|
397
|
-
* The general direct geodesic problem.
|
398
|
-
*
|
399
|
-
* @param[in] g a pointer to the geod_geodesic object specifying the
|
400
|
-
* ellipsoid.
|
401
|
-
* @param[in] lat1 latitude of point 1 (degrees).
|
402
|
-
* @param[in] lon1 longitude of point 1 (degrees).
|
403
|
-
* @param[in] azi1 azimuth at point 1 (degrees).
|
404
|
-
* @param[in] flags bitor'ed combination of geod_flags(); \e flags &
|
405
|
-
* GEOD_ARCMODE determines the meaning of \e s12_a12 and \e flags &
|
406
|
-
* GEOD_LONG_UNROLL "unrolls" \e lon2.
|
407
|
-
* @param[in] s12_a12 if \e flags & GEOD_ARCMODE is 0, this is the distance
|
408
|
-
* between point 1 and point 2 (meters); otherwise it is the arc length
|
409
|
-
* between point 1 and point 2 (degrees); it can be negative.
|
410
|
-
* @param[out] plat2 pointer to the latitude of point 2 (degrees).
|
411
|
-
* @param[out] plon2 pointer to the longitude of point 2 (degrees).
|
412
|
-
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
413
|
-
* @param[out] ps12 pointer to the distance between point 1 and point 2
|
414
|
-
* (meters).
|
415
|
-
* @param[out] pm12 pointer to the reduced length of geodesic (meters).
|
416
|
-
* @param[out] pM12 pointer to the geodesic scale of point 2 relative to
|
417
|
-
* point 1 (dimensionless).
|
418
|
-
* @param[out] pM21 pointer to the geodesic scale of point 1 relative to
|
419
|
-
* point 2 (dimensionless).
|
420
|
-
* @param[out] pS12 pointer to the area under the geodesic
|
421
|
-
* (meters<sup>2</sup>).
|
422
|
-
* @return \e a12 arc length of between point 1 and point 2 (degrees).
|
423
|
-
*
|
424
|
-
* \e g must have been initialized with a call to geod_init(). \e lat1
|
425
|
-
* should be in the range [−90°, 90°]. The function value \e
|
426
|
-
* a12 equals \e s12_a12 if \e flags & GEOD_ARCMODE. Any of the "return"
|
427
|
-
* arguments, \e plat2, etc., may be replaced by 0, if you do not need some
|
428
|
-
* quantities computed.
|
429
|
-
*
|
430
|
-
* With \e flags & GEOD_LONG_UNROLL bit set, the longitude is "unrolled" so
|
431
|
-
* that the quantity \e lon2 − \e lon1 indicates how many times and in
|
432
|
-
* what sense the geodesic encircles the ellipsoid.
|
433
|
-
**********************************************************************/
|
434
|
-
double geod_gendirect(const struct geod_geodesic* g,
|
435
|
-
double lat1, double lon1, double azi1,
|
436
|
-
unsigned flags, double s12_a12,
|
437
|
-
double* plat2, double* plon2, double* pazi2,
|
438
|
-
double* ps12, double* pm12, double* pM12, double* pM21,
|
439
|
-
double* pS12);
|
440
|
-
|
441
|
-
/**
|
442
|
-
* The general inverse geodesic calculation.
|
443
|
-
*
|
444
|
-
* @param[in] g a pointer to the geod_geodesic object specifying the
|
445
|
-
* ellipsoid.
|
446
|
-
* @param[in] lat1 latitude of point 1 (degrees).
|
447
|
-
* @param[in] lon1 longitude of point 1 (degrees).
|
448
|
-
* @param[in] lat2 latitude of point 2 (degrees).
|
449
|
-
* @param[in] lon2 longitude of point 2 (degrees).
|
450
|
-
* @param[out] ps12 pointer to the distance between point 1 and point 2
|
451
|
-
* (meters).
|
452
|
-
* @param[out] pazi1 pointer to the azimuth at point 1 (degrees).
|
453
|
-
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
454
|
-
* @param[out] pm12 pointer to the reduced length of geodesic (meters).
|
455
|
-
* @param[out] pM12 pointer to the geodesic scale of point 2 relative to
|
456
|
-
* point 1 (dimensionless).
|
457
|
-
* @param[out] pM21 pointer to the geodesic scale of point 1 relative to
|
458
|
-
* point 2 (dimensionless).
|
459
|
-
* @param[out] pS12 pointer to the area under the geodesic
|
460
|
-
* (meters<sup>2</sup>).
|
461
|
-
* @return \e a12 arc length of between point 1 and point 2 (degrees).
|
462
|
-
*
|
463
|
-
* \e g must have been initialized with a call to geod_init(). \e lat1 and
|
464
|
-
* \e lat2 should be in the range [−90°, 90°]. Any of the
|
465
|
-
* "return" arguments \e ps12, etc., may be replaced by 0, if you do not need
|
466
|
-
* some quantities computed.
|
467
|
-
**********************************************************************/
|
468
|
-
double geod_geninverse(const struct geod_geodesic* g,
|
469
|
-
double lat1, double lon1, double lat2, double lon2,
|
470
|
-
double* ps12, double* pazi1, double* pazi2,
|
471
|
-
double* pm12, double* pM12, double* pM21,
|
472
|
-
double* pS12);
|
473
|
-
|
474
562
|
/**
|
475
563
|
* The general position function.
|
476
564
|
*
|
@@ -481,14 +569,14 @@ extern "C" {
|
|
481
569
|
* GEOD_LONG_UNROLL "unrolls" \e lon2; if \e flags & GEOD_ARCMODE is 0,
|
482
570
|
* then \e l must have been initialized with \e caps |= GEOD_DISTANCE_IN.
|
483
571
|
* @param[in] s12_a12 if \e flags & GEOD_ARCMODE is 0, this is the
|
484
|
-
* distance
|
485
|
-
* arc length
|
572
|
+
* distance from point 1 to point 2 (meters); otherwise it is the
|
573
|
+
* arc length from point 1 to point 2 (degrees); it can be
|
486
574
|
* negative.
|
487
575
|
* @param[out] plat2 pointer to the latitude of point 2 (degrees).
|
488
576
|
* @param[out] plon2 pointer to the longitude of point 2 (degrees); requires
|
489
577
|
* that \e l was initialized with \e caps |= GEOD_LONGITUDE.
|
490
578
|
* @param[out] pazi2 pointer to the (forward) azimuth at point 2 (degrees).
|
491
|
-
* @param[out] ps12 pointer to the distance
|
579
|
+
* @param[out] ps12 pointer to the distance from point 1 to point 2
|
492
580
|
* (meters); requires that \e l was initialized with \e caps |=
|
493
581
|
* GEOD_DISTANCE.
|
494
582
|
* @param[out] pm12 pointer to the reduced length of geodesic (meters);
|
@@ -502,7 +590,7 @@ extern "C" {
|
|
502
590
|
* @param[out] pS12 pointer to the area under the geodesic
|
503
591
|
* (meters<sup>2</sup>); requires that \e l was initialized with \e caps |=
|
504
592
|
* GEOD_AREA.
|
505
|
-
* @return \e a12 arc length
|
593
|
+
* @return \e a12 arc length from point 1 to point 2 (degrees).
|
506
594
|
*
|
507
595
|
* \e l must have been initialized with a call to geod_lineinit() with \e
|
508
596
|
* caps |= GEOD_DISTANCE_IN. The value \e azi2 returned is in the range
|
@@ -515,22 +603,21 @@ extern "C" {
|
|
515
603
|
* that the quantity \e lon2 − \e lon1 indicates how many times and in
|
516
604
|
* what sense the geodesic encircles the ellipsoid.
|
517
605
|
*
|
518
|
-
* Example, compute way points between JFK and Singapore Changi Airport
|
519
|
-
*
|
520
|
-
*
|
521
|
-
* faster than using geod_position() would be appropriate if drawing the
|
522
|
-
* on a map.
|
606
|
+
* Example, compute way points between JFK and Singapore Changi Airport using
|
607
|
+
* geod_genposition(). In this example, the points are evenly space in arc
|
608
|
+
* length (and so only approximately equally spaced in distance). This is
|
609
|
+
* faster than using geod_position() and would be appropriate if drawing the
|
610
|
+
* path on a map.
|
523
611
|
@code{.c}
|
524
612
|
struct geod_geodesic g;
|
525
613
|
struct geod_geodesicline l;
|
526
|
-
double
|
614
|
+
double lat[101], lon[101];
|
527
615
|
int i;
|
528
616
|
geod_init(&g, 6378137, 1/298.257223563);
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
geod_genposition(&l, 1, i * a12 * 0.01,
|
617
|
+
geod_inverseline(&l, &g, 40.64, -73.78, 1.36, 103.99,
|
618
|
+
GEOD_LATITUDE | GEOD_LONGITUDE);
|
619
|
+
for (i = 0; i <= 100; ++i) {
|
620
|
+
geod_genposition(&l, GEOD_ARCMODE, i * l.a13 * 0.01,
|
534
621
|
lat + i, lon + i, 0, 0, 0, 0, 0, 0);
|
535
622
|
printf("%.5f %.5f\n", lat[i], lon[i]);
|
536
623
|
}
|
@@ -543,6 +630,36 @@ extern "C" {
|
|
543
630
|
double* pM12, double* pM21,
|
544
631
|
double* pS12);
|
545
632
|
|
633
|
+
/**
|
634
|
+
* Specify position of point 3 in terms of distance.
|
635
|
+
*
|
636
|
+
* @param[inout] l a pointer to the geod_geodesicline object.
|
637
|
+
* @param[in] s13 the distance from point 1 to point 3 (meters); it
|
638
|
+
* can be negative.
|
639
|
+
*
|
640
|
+
* This is only useful if the geod_geodesicline object has been constructed
|
641
|
+
* with \e caps |= GEOD_DISTANCE_IN.
|
642
|
+
**********************************************************************/
|
643
|
+
void geod_setdistance(struct geod_geodesicline* l, double s13);
|
644
|
+
|
645
|
+
/**
|
646
|
+
* Specify position of point 3 in terms of either distance or arc length.
|
647
|
+
*
|
648
|
+
* @param[inout] l a pointer to the geod_geodesicline object.
|
649
|
+
* @param[in] flags either GEOD_NOFLAGS or GEOD_ARCMODE to determining the
|
650
|
+
* meaning of the \e s13_a13.
|
651
|
+
* @param[in] s13_a13 if \e flags = GEOD_NOFLAGS, this is the distance
|
652
|
+
* from point 1 to point 3 (meters); if \e flags = GEOD_ARCMODE, it is
|
653
|
+
* the arc length from point 1 to point 3 (degrees); it can be
|
654
|
+
* negative.
|
655
|
+
*
|
656
|
+
* If flags = GEOD_NOFLAGS, this calls geod_setdistance(). If flags =
|
657
|
+
* GEOD_ARCMODE, the \e s13 is only set if the geod_geodesicline object has
|
658
|
+
* been constructed with \e caps |= GEOD_DISTANCE.
|
659
|
+
**********************************************************************/
|
660
|
+
void geod_gensetdistance(struct geod_geodesicline* l,
|
661
|
+
unsigned flags, double s13_a13);
|
662
|
+
|
546
663
|
/**
|
547
664
|
* Initialize a geod_polygon object.
|
548
665
|
*
|
@@ -564,6 +681,13 @@ extern "C" {
|
|
564
681
|
**********************************************************************/
|
565
682
|
void geod_polygon_init(struct geod_polygon* p, int polylinep);
|
566
683
|
|
684
|
+
/**
|
685
|
+
* Clear the polygon, allowing a new polygon to be started.
|
686
|
+
*
|
687
|
+
* @param[in,out] p a pointer to the object to be cleared.
|
688
|
+
**********************************************************************/
|
689
|
+
void geod_polygon_clear(struct geod_polygon* p);
|
690
|
+
|
567
691
|
/**
|
568
692
|
* Add a point to the polygon or polyline.
|
569
693
|
*
|
@@ -630,6 +754,8 @@ extern "C" {
|
|
630
754
|
* vertex. Set \e pA or \e pP to zero, if you do not want the corresponding
|
631
755
|
* quantity returned.
|
632
756
|
*
|
757
|
+
* More points can be added to the polygon after this call.
|
758
|
+
*
|
633
759
|
* Example, compute the perimeter and area of the geodesic triangle with
|
634
760
|
* vertices (0°N,0°E), (0°N,90°E), (90°N,0°E).
|
635
761
|
@code{.c}
|
@@ -774,10 +900,7 @@ extern "C" {
|
|
774
900
|
enum geod_flags {
|
775
901
|
GEOD_NOFLAGS = 0U, /**< No flags */
|
776
902
|
GEOD_ARCMODE = 1U<<0, /**< Position given in terms of arc distance */
|
777
|
-
GEOD_LONG_UNROLL = 1U<<15
|
778
|
-
/**< @cond SKIP */
|
779
|
-
GEOD_LONG_NOWRAP = GEOD_LONG_UNROLL /* For backward compatibility only */
|
780
|
-
/**< @endcond */
|
903
|
+
GEOD_LONG_UNROLL = 1U<<15 /**< Unroll the longitude */
|
781
904
|
};
|
782
905
|
|
783
906
|
#if defined(__cplusplus)
|