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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * \file geodesic.h
3
- * \brief Header for the geodesic routines in C
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.sf.net/geod-addenda.html">
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 = &minus;\e lat2 (with neither point at a pole). If \e azi1 =
79
- * \e azi2, the geodesic is unique. Otherwise there are two geodesics
80
- * and the second one is obtained by setting [\e azi1, \e azi2] = [\e
81
- * azi2, \e azi1], [\e M12, \e M21] = [\e M21, \e M12], \e S12 =
82
- * &minus;\e S12. (This occurs when the longitude difference is near
83
- * &plusmn;180&deg; for oblate ellipsoids.)
84
- * - \e lon2 = \e lon1 &plusmn; 180&deg; (with neither point at a pole).
85
- * If \e azi1 = 0&deg; or &plusmn;180&deg;, the geodesic is unique.
86
- * Otherwise there are two geodesics and the second one is obtained by
87
- * setting [\e azi1, \e azi2] = [&minus;\e azi1, &minus;\e azi2], \e S12
88
- * = &minus;\e S12. (This occurs when \e lat2 is near &minus;\e lat1 for
78
+ * - \e lat1 = &minus;\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] &rarr; [\e azi2, \e
81
+ * azi1], [\e M12, \e M21] &rarr; [\e M21, \e M12], \e S12 &rarr; &minus;\e
82
+ * S12. (This occurs when the longitude difference is near &plusmn;180&deg;
83
+ * for oblate ellipsoids.)
84
+ * - \e lon2 = \e lon1 &plusmn; 180&deg; (with neither point at a pole). If \e
85
+ * azi1 = 0&deg; or &plusmn;180&deg;, the geodesic is unique. Otherwise
86
+ * there are two geodesics and the second one is obtained by setting [\e
87
+ * azi1, \e azi2] &rarr; [&minus;\e azi1, &minus;\e azi2], \e S12 &rarr;
88
+ * &minus;\e S12. (This occurs when \e lat2 is near &minus;\e lat1 for
89
89
  * prolate ellipsoids.)
90
- * - Points 1 and 2 at opposite poles. There are infinitely many
91
- * geodesics which can be generated by setting [\e azi1, \e azi2] =
92
- * [\e azi1, \e azi2] + [\e d, &minus;\e d], for arbitrary \e d. (For
93
- * spheres, this prescription applies when points 1 and 2 are
94
- * antipodal.)
95
- * - \e s12 = 0 (coincident points). There are infinitely many geodesics
96
- * which can be generated by setting [\e azi1, \e azi2] = [\e azi1, \e
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] &rarr; [\e azi1, \e
92
+ * azi2] + [\e d, &minus;\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] &rarr; [\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.sf.net"> GeographicLib</a>. The "class
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-2015) <charles@karney.com> and licensed
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.44.
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 44
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() before use.
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
- salp1, calp1, ssig1, csig1, dn1, stau1, ctau1, somg1, comg1,
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 [&minus;90&deg;, 90&deg;].
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 between point 1 and point 2 (meters); it can be
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 [&minus;90&deg;, 90&deg;]. 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 &minus; \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 between point 1 and point 2
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 [&minus;90&deg;, 90&deg;]. 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 [&minus;90&deg;, 90&deg;].
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 between point 1 and point 2 (meters); it can be
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() with \e
360
- * caps |= GEOD_DISTANCE_IN. The values of \e lon2 and \e azi2 returned are
361
- * in the range [&minus;180&deg;, 180&deg;). Any of the "return" arguments
362
- * \e plat2, etc., may be replaced by 0, if you do not need some quantities
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 [&minus;180&deg;, 180&deg;). 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 s12, azi1, lat[101],lon[101];
549
+ double lat[101],lon[101];
383
550
  int i;
384
551
  geod_init(&g, 6378137, 1/298.257223563);
385
- geod_inverse(&g, 40.64, -73.78, 1.36, 103.99, &s12, &azi1, 0);
386
- geod_lineinit(&l, &g, 40.64, -73.78, azi1, 0);
387
- for (i = 0; i < 101; ++i) {
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 [&minus;90&deg;, 90&deg;]. 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 &minus; \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 [&minus;90&deg;, 90&deg;]. 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 between point 1 and point 2 (meters); otherwise it is the
485
- * arc length between point 1 and point 2 (degrees); it can be
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 between point 1 and point 2
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 of between point 1 and point 2 (degrees).
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 &minus; \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
- * using geod_genposition(). In this example, the points are evenly space in
520
- * arc length (and so only approximately equally space in distance). This is
521
- * faster than using geod_position() would be appropriate if drawing the path
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 a12, azi1, lat[101], lon[101];
614
+ double lat[101], lon[101];
527
615
  int i;
528
616
  geod_init(&g, 6378137, 1/298.257223563);
529
- a12 = geod_geninverse(&g, 40.64, -73.78, 1.36, 103.99,
530
- 0, &azi1, 0, 0, 0, 0, 0);
531
- geod_lineinit(&l, &g, 40.64, -73.78, azi1, GEOD_LATITUDE | GEOD_LONGITUDE);
532
- for (i = 0; i < 101; ++i) {
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&deg;N,0&deg;E), (0&deg;N,90&deg;E), (90&deg;N,0&deg;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, /**< Unroll the longitude */
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)