400 lines
14 KiB
Plaintext
400 lines
14 KiB
Plaintext
=head1 NAME
|
|
|
|
GeodSolve -- perform geodesic calculations
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
B<GeodSolve>
|
|
[ B<-i> | B<-L> I<lat1> I<lon1> I<azi1> |
|
|
B<-D> I<lat1> I<lon1> I<azi1> I<s13> | B<-I> I<lat1> I<lon1> I<lat3> I<lon3> ]
|
|
[ B<-a> ] [ B<-e> I<a> I<f> ] [ B<-u> ] [ B<-F> ]
|
|
[ B<-d> | B<-:> ] [ B<-w> ] [ B<-b> ] [ B<-f> ] [ B<-p> I<prec> ] [ B<-E> ]
|
|
[ B<--comment-delimiter> I<commentdelim> ]
|
|
[ B<--version> | B<-h> | B<--help> ]
|
|
[ B<--input-file> I<infile> | B<--input-string> I<instring> ]
|
|
[ B<--line-separator> I<linesep> ]
|
|
[ B<--output-file> I<outfile> ]
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
The shortest path between two points on the ellipsoid at (I<lat1>,
|
|
I<lon1>) and (I<lat2>, I<lon2>) is called the geodesic. Its length is
|
|
I<s12> and the geodesic from point 1 to point 2 has forward azimuths
|
|
I<azi1> and I<azi2> at the two end points.
|
|
|
|
B<GeodSolve> operates in one of three modes:
|
|
|
|
=over
|
|
|
|
=item 1.
|
|
|
|
By default, B<GeodSolve> accepts lines on the standard input containing
|
|
I<lat1> I<lon1> I<azi1> I<s12> and prints I<lat2> I<lon2> I<azi2>
|
|
on standard output. This is the direct geodesic calculation.
|
|
|
|
=item 2.
|
|
|
|
With the B<-i> command line argument, B<GeodSolve> performs the inverse
|
|
geodesic calculation. It reads lines containing I<lat1> I<lon1> I<lat2>
|
|
I<lon2> and prints the corresponding values of I<azi1> I<azi2> I<s12>.
|
|
|
|
=item 3.
|
|
|
|
Command line arguments B<-L> I<lat1> I<lon1> I<azi1> specify a geodesic
|
|
line. B<GeodSolve> then accepts a sequence of I<s12> values (one per
|
|
line) on standard input and prints I<lat2> I<lon2> I<azi2> for each.
|
|
This generates a sequence of points on a single geodesic. Command line
|
|
arguments B<-D> and B<-I> work similarly with the geodesic line defined
|
|
in terms of a direct or inverse geodesic calculation, respectively.
|
|
|
|
=back
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over
|
|
|
|
=item B<-i>
|
|
|
|
perform an inverse geodesic calculation (see 2 above).
|
|
|
|
=item B<-L> I<lat1> I<lon1> I<azi1>
|
|
|
|
line mode (see 3 above); generate a sequence of points along the
|
|
geodesic specified by I<lat1> I<lon1> I<azi1>. The B<-w> flag can be
|
|
used to swap the default order of the 2 geographic coordinates, provided
|
|
that it appears before B<-L>. (B<-l> is an alternative, deprecated,
|
|
spelling of this flag.)
|
|
|
|
=item B<-D> I<lat1> I<lon1> I<azi1> I<s13>
|
|
|
|
line mode (see 3 above); generate a sequence of points along the
|
|
geodesic specified by I<lat1> I<lon1> I<azi1> I<s13>. The B<-w> flag
|
|
can be used to swap the default order of the 2 geographic coordinates,
|
|
provided that it appears before B<-D>. Similarly, the B<-a> flag can be
|
|
used to change the interpretation of I<s13> to I<a13>, provided that it
|
|
appears before B<-D>.
|
|
|
|
=item B<-I> I<lat1> I<lon1> I<lat3> I<lon3>
|
|
|
|
line mode (see 3 above); generate a sequence of points along the
|
|
geodesic specified by I<lat1> I<lon1> I<lat3> I<lon3>. The B<-w> flag
|
|
can be used to swap the default order of the 2 geographic coordinates,
|
|
provided that it appears before B<-I>.
|
|
|
|
=item B<-a>
|
|
|
|
toggle the arc mode flag (it starts off); if this flag is on, then on
|
|
input I<and> output I<s12> is replaced by I<a12> the arc length (in
|
|
degrees) on the auxiliary sphere. See L</AUXILIARY SPHERE>.
|
|
|
|
=item B<-e> I<a> I<f>
|
|
|
|
specify the ellipsoid via the equatorial radius, I<a> and
|
|
the flattening, I<f>. Setting I<f> = 0 results in a sphere. Specify
|
|
I<f> E<lt> 0 for a prolate ellipsoid. A simple fraction, e.g., 1/297,
|
|
is allowed for I<f>. By default, the WGS84 ellipsoid is used, I<a> =
|
|
6378137 m, I<f> = 1/298.257223563.
|
|
|
|
=item B<-u>
|
|
|
|
unroll the longitude. Normally, on output longitudes are reduced to lie
|
|
in [-180deg,180deg). However with this option, the returned longitude
|
|
I<lon2> is "unrolled" so that I<lon2> - I<lon1> indicates how often and
|
|
in what sense the geodesic has encircled the earth. Use the B<-f>
|
|
option, to get both longitudes printed.
|
|
|
|
=item B<-F>
|
|
|
|
fractional mode. This only has any effect with the B<-D> and B<-I>
|
|
options (and is otherwise ignored). The values read on standard input
|
|
are interpreted as fractional distances to point 3, i.e., as
|
|
I<s12>/I<s13> instead of I<s12>. If arc mode is in effect, then the
|
|
values denote fractional arc length, i.e., I<a12>/I<a13>. The
|
|
fractional distances can be entered as a simple fraction, e.g., 3/4.
|
|
|
|
=item B<-d>
|
|
|
|
output angles as degrees, minutes, seconds instead of decimal degrees.
|
|
|
|
=item B<-:>
|
|
|
|
like B<-d>, except use : as a separator instead of the d, ', and "
|
|
delimiters.
|
|
|
|
=item B<-w>
|
|
|
|
toggle the longitude first flag (it starts off); if the flag is on, then
|
|
on input and output, longitude precedes latitude (except that, on input,
|
|
this can be overridden by a hemisphere designator, I<N>, I<S>, I<E>,
|
|
I<W>).
|
|
|
|
=item B<-b>
|
|
|
|
report the I<back> azimuth at point 2 instead of the forward azimuth.
|
|
|
|
=item B<-f>
|
|
|
|
full output; each line of output consists of 12 quantities: I<lat1>
|
|
I<lon1> I<azi1> I<lat2> I<lon2> I<azi2> I<s12> I<a12> I<m12> I<M12>
|
|
I<M21> I<S12>. I<a12> is described in L</AUXILIARY SPHERE>. The four
|
|
quantities I<m12>, I<M12>, I<M21>, and I<S12> are described in
|
|
L</ADDITIONAL QUANTITIES>.
|
|
|
|
=item B<-p> I<prec>
|
|
|
|
set the output precision to I<prec> (default 3); I<prec> is the
|
|
precision relative to 1 m. See L</PRECISION>.
|
|
|
|
=item B<-E>
|
|
|
|
use "exact" algorithms (based on elliptic integrals) for the geodesic
|
|
calculations. These are more accurate than the (default) series
|
|
expansions for |I<f>| E<gt> 0.02.
|
|
|
|
=item B<--comment-delimiter> I<commentdelim>
|
|
|
|
set the comment delimiter to I<commentdelim> (e.g., "#" or "//"). If
|
|
set, the input lines will be scanned for this delimiter and, if found,
|
|
the delimiter and the rest of the line will be removed prior to
|
|
processing and subsequently appended to the output line (separated by a
|
|
space).
|
|
|
|
=item B<--version>
|
|
|
|
print version and exit.
|
|
|
|
=item B<-h>
|
|
|
|
print usage and exit.
|
|
|
|
=item B<--help>
|
|
|
|
print full documentation and exit.
|
|
|
|
=item B<--input-file> I<infile>
|
|
|
|
read input from the file I<infile> instead of from standard input; a file
|
|
name of "-" stands for standard input.
|
|
|
|
=item B<--input-string> I<instring>
|
|
|
|
read input from the string I<instring> instead of from standard input.
|
|
All occurrences of the line separator character (default is a semicolon)
|
|
in I<instring> are converted to newlines before the reading begins.
|
|
|
|
=item B<--line-separator> I<linesep>
|
|
|
|
set the line separator character to I<linesep>. By default this is a
|
|
semicolon.
|
|
|
|
=item B<--output-file> I<outfile>
|
|
|
|
write output to the file I<outfile> instead of to standard output; a
|
|
file name of "-" stands for standard output.
|
|
|
|
=back
|
|
|
|
=head1 INPUT
|
|
|
|
B<GeodSolve> measures all angles in degrees and all lengths (I<s12>) in
|
|
meters, and all areas (I<S12>) in meters^2. On input angles (latitude,
|
|
longitude, azimuth, arc length) can be as decimal degrees or degrees,
|
|
minutes, seconds. For example, C<40d30>, C<40d30'>, C<40:30>, C<40.5d>,
|
|
and C<40.5> are all equivalent. By default, latitude precedes longitude
|
|
for each point (the B<-w> flag switches this convention); however on
|
|
input either may be given first by appending (or prepending) I<N> or
|
|
I<S> to the latitude and I<E> or I<W> to the longitude. Azimuths are
|
|
measured clockwise from north; however this may be overridden with I<E>
|
|
or I<W>.
|
|
|
|
For details on the allowed formats for angles, see the C<GEOGRAPHIC
|
|
COORDINATES> section of GeoConvert(1).
|
|
|
|
=head1 AUXILIARY SPHERE
|
|
|
|
Geodesics on the ellipsoid can be transferred to the I<auxiliary sphere>
|
|
on which the distance is measured in terms of the arc length I<a12>
|
|
(measured in degrees) instead of I<s12>. In terms of I<a12>, 180
|
|
degrees is the distance from one equator crossing to the next or from
|
|
the minimum latitude to the maximum latitude. Geodesics with I<a12>
|
|
E<gt> 180 degrees do not correspond to shortest paths. With the B<-a>
|
|
flag, I<s12> (on both input and output) is replaced by I<a12>. The
|
|
B<-a> flag does I<not> affect the full output given by the B<-f> flag
|
|
(which always includes both I<s12> and I<a12>).
|
|
|
|
=head1 ADDITIONAL QUANTITIES
|
|
|
|
The B<-f> flag reports four additional quantities.
|
|
|
|
The reduced length of the geodesic, I<m12>, is defined such that if the
|
|
initial azimuth is perturbed by dI<azi1> (radians) then the second point
|
|
is displaced by I<m12> dI<azi1> in the direction perpendicular to the
|
|
geodesic. I<m12> is given in meters. On a curved surface the
|
|
reduced length obeys a symmetry relation, I<m12> + I<m21> = 0. On a
|
|
flat surface, we have I<m12> = I<s12>.
|
|
|
|
I<M12> and I<M21> are geodesic scales. If two geodesics are parallel at
|
|
point 1 and separated by a small distance I<dt>, then they are separated
|
|
by a distance I<M12> I<dt> at point 2. I<M21> is defined similarly
|
|
(with the geodesics being parallel to one another at point 2). I<M12>
|
|
and I<M21> are dimensionless quantities. On a flat surface, we have
|
|
I<M12> = I<M21> = 1.
|
|
|
|
If points 1, 2, and 3 lie on a single geodesic, then the following
|
|
addition rules hold:
|
|
|
|
s13 = s12 + s23,
|
|
a13 = a12 + a23,
|
|
S13 = S12 + S23,
|
|
m13 = m12 M23 + m23 M21,
|
|
M13 = M12 M23 - (1 - M12 M21) m23 / m12,
|
|
M31 = M32 M21 - (1 - M23 M32) m12 / m23.
|
|
|
|
Finally, I<S12> is the area between the geodesic from point 1 to point 2
|
|
and the equator; i.e., it is the area, measured counter-clockwise, of
|
|
the geodesic quadrilateral with corners (I<lat1>,I<lon1>), (0,I<lon1>),
|
|
(0,I<lon2>), and (I<lat2>,I<lon2>). It is given in meters^2.
|
|
|
|
=head1 PRECISION
|
|
|
|
I<prec> gives precision of the output with I<prec> = 0 giving 1 m
|
|
precision, I<prec> = 3 giving 1 mm precision, etc. I<prec> is the
|
|
number of digits after the decimal point for lengths. For decimal
|
|
degrees, the number of digits after the decimal point is I<prec> + 5.
|
|
For DMS (degree, minute, seconds) output, the number of digits after the
|
|
decimal point in the seconds component is I<prec> + 1. The minimum
|
|
value of I<prec> is 0 and the maximum is 10.
|
|
|
|
=head1 ERRORS
|
|
|
|
An illegal line of input will print an error message to standard output
|
|
beginning with C<ERROR:> and causes B<GeodSolve> to return an exit code
|
|
of 1. However, an error does not cause B<GeodSolve> to terminate;
|
|
following lines will be converted.
|
|
|
|
=head1 ACCURACY
|
|
|
|
Using the (default) series solution, GeodSolve is accurate to about 15
|
|
nm (15 nanometers) for the WGS84 ellipsoid. The approximate maximum
|
|
error (expressed as a distance) for an ellipsoid with the same equatorial
|
|
radius as the WGS84 ellipsoid and different values of the flattening is
|
|
|
|
|f| error
|
|
0.01 25 nm
|
|
0.02 30 nm
|
|
0.05 10 um
|
|
0.1 1.5 mm
|
|
0.2 300 mm
|
|
|
|
If B<-E> is specified, GeodSolve is accurate to about 40 nm (40
|
|
nanometers) for the WGS84 ellipsoid. The approximate maximum error
|
|
(expressed as a distance) for an ellipsoid with a quarter meridian of
|
|
10000 km and different values of the I<a/b> = 1 - I<f> is
|
|
|
|
1-f error (nm)
|
|
1/128 387
|
|
1/64 345
|
|
1/32 269
|
|
1/16 210
|
|
1/8 115
|
|
1/4 69
|
|
1/2 36
|
|
1 15
|
|
2 25
|
|
4 96
|
|
8 318
|
|
16 985
|
|
32 2352
|
|
64 6008
|
|
128 19024
|
|
|
|
=head1 MULTIPLE SOLUTIONS
|
|
|
|
The shortest distance returned for the inverse problem is (obviously)
|
|
uniquely defined. However, in a few special cases there are multiple
|
|
azimuths which yield the same shortest distance. Here is a catalog of
|
|
those cases:
|
|
|
|
=over
|
|
|
|
=item I<lat1> = -I<lat2> (with neither point at a pole)
|
|
|
|
If I<azi1> = I<azi2>, the geodesic is unique. Otherwise there are two
|
|
geodesics and the second one is obtained by setting [I<azi1>,I<azi2>] =
|
|
[I<azi2>,I<azi1>], [I<M12>,I<M21>] = [I<M21>,I<M12>], I<S12> = -I<S12>.
|
|
(This occurs when the longitude difference is near +/-180 for oblate
|
|
ellipsoids.)
|
|
|
|
=item I<lon2> = I<lon1> +/- 180 (with neither point at a pole)
|
|
|
|
If I<azi1> = 0 or +/-180, the geodesic is unique. Otherwise there are
|
|
two geodesics and the second one is obtained by setting
|
|
[I<azi1>,I<azi2>] = [-I<azi1>,-I<azi2>], I<S12> = -I<S12>. (This occurs
|
|
when I<lat2> is near -I<lat1> for prolate ellipsoids.)
|
|
|
|
=item Points 1 and 2 at opposite poles
|
|
|
|
There are infinitely many geodesics which can be generated by setting
|
|
[I<azi1>,I<azi2>] = [I<azi1>,I<azi2>] + [I<d>,-I<d>], for arbitrary
|
|
I<d>. (For spheres, this prescription applies when points 1 and 2 are
|
|
antipodal.)
|
|
|
|
=item I<s12> = 0 (coincident points)
|
|
|
|
There are infinitely many geodesics which can be generated by setting
|
|
[I<azi1>,I<azi2>] = [I<azi1>,I<azi2>] + [I<d>,I<d>], for arbitrary I<d>.
|
|
|
|
=back
|
|
|
|
=head1 EXAMPLES
|
|
|
|
Route from JFK Airport to Singapore Changi Airport:
|
|
|
|
echo 40:38:23N 073:46:44W 01:21:33N 103:59:22E |
|
|
GeodSolve -i -: -p 0
|
|
|
|
003:18:29.9 177:29:09.2 15347628
|
|
|
|
Equally spaced waypoints on the route:
|
|
|
|
for ((i = 0; i <= 10; ++i)); do echo $i/10; done |
|
|
GeodSolve -I 40:38:23N 073:46:44W 01:21:33N 103:59:22E -F -: -p 0
|
|
|
|
40:38:23.0N 073:46:44.0W 003:18:29.9
|
|
54:24:51.3N 072:25:39.6W 004:18:44.1
|
|
68:07:37.7N 069:40:42.9W 006:44:25.4
|
|
81:38:00.4N 058:37:53.9W 017:28:52.7
|
|
83:43:26.0N 080:37:16.9E 156:26:00.4
|
|
70:20:29.2N 097:01:29.4E 172:31:56.4
|
|
56:38:36.0N 100:14:47.6E 175:26:10.5
|
|
42:52:37.1N 101:43:37.2E 176:34:28.6
|
|
29:03:57.0N 102:39:34.8E 177:07:35.2
|
|
15:13:18.6N 103:22:08.0E 177:23:44.7
|
|
01:21:33.0N 103:59:22.0E 177:29:09.2
|
|
|
|
=head1 SEE ALSO
|
|
|
|
GeoConvert(1).
|
|
|
|
An online version of this utility is availbable at
|
|
L<https://geographiclib.sourceforge.io/cgi-bin/GeodSolve>.
|
|
|
|
The algorithms are described in C. F. F. Karney,
|
|
I<Algorithms for geodesics>, J. Geodesy 87, 43-55 (2013); DOI:
|
|
L<https://doi.org/10.1007/s00190-012-0578-z>;
|
|
addenda: L<https://geographiclib.sourceforge.io/geod-addenda.html>.
|
|
|
|
The Wikipedia page, Geodesics on an ellipsoid,
|
|
L<https://en.wikipedia.org/wiki/Geodesics_on_an_ellipsoid>.
|
|
|
|
=head1 AUTHOR
|
|
|
|
B<GeodSolve> was written by Charles Karney.
|
|
|
|
=head1 HISTORY
|
|
|
|
B<GeodSolve> was added to GeographicLib,
|
|
L<https://geographiclib.sourceforge.io>, in 2009-03. Prior to version
|
|
1.30, it was called B<Geod>. (The name was changed to avoid a conflict
|
|
with the B<geod> utility in I<proj.4>.)
|