ADD: new track message, Entity class and Position class

This commit is contained in:
Henry Winkel
2022-12-20 17:20:35 +01:00
parent 469ecfb099
commit 98ebb563a8
2114 changed files with 482360 additions and 24 deletions

View File

@@ -0,0 +1,248 @@
#! /bin/sh
#
# GeoConvert.cgi
# cgi script for geographic coordinate conversion
#
# Copyright (c) Charles Karney (2011-2022) <charles@karney.com> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
. ./utils.sh
OPTION=`lookupkey "$QUERY_STRING" option`
if test "$OPTION" = Reset; then
INPUT=
else
INPUT=`lookupcheckkey "$QUERY_STRING" input`
ZONE=`lookupkey "$QUERY_STRING" zone`
PREC=`lookupkey "$QUERY_STRING" prec`
fi
test "$ZONE" || ZONE=-3
test "$PREC" || PREC=0
INPUTENC=`encodevalue "$INPUT"`
EXECDIR=../bin
COMMAND="GeoConvert"
VERSION=`$EXECDIR/$COMMAND --version | cut -f4 -d" "`
F='<font color="Blue">'
G='</font>'
test $PREC = 0 || COMMAND="$COMMAND -p $PREC"
LOCG=
LOCD=
LOCU=
LOCM=
GEOH=
set -o pipefail
if test "$INPUT"; then
LOCG=`echo $INPUT | $EXECDIR/$COMMAND | head -1`
if test $? -eq 0; then
GEOH=`echo $INPUT | $EXECDIR/$COMMAND -p 1 | head -1`
LOCG=`geohack $GEOH $LOCG Blue`
LOCD=\(`echo $INPUT | $EXECDIR/$COMMAND -d | head -1`\)
case $ZONE in
-3 ) ;;
-2 ) COMMAND="$COMMAND -t";;
-1 ) COMMAND="$COMMAND -s";;
* ) COMMAND="$COMMAND -z $ZONE"
esac
LOCU=`echo $INPUT | $EXECDIR/$COMMAND -u | head -1`
LOCM=`echo $INPUT | $EXECDIR/$COMMAND -m | head -1`
fi
# echo `date +"%F %T"` "$COMMAND: $INPUT" >> ../persistent/utilities.log
fi
echo Content-type: text/html
echo
cat <<EOF
<html>
<head>
<title>
Online geographic coordinate converter
</title>
<meta name="description"
content="Online geographic coordinate converter" />
<meta name="author" content="Charles F. F. Karney" />
<meta name="keywords"
content="geographic coordinate conversions,
geographic coordinates,
latitude and longitude,
degrees minutes seconds,
universal transverse Mercator, UTM,
easting northing and zone,
universal polar sterographic, UPS,
military grid reference system, MGRS,
online calculator,
WGS84 ellipsoid,
GeographicLib" />
</head>
<body>
<h3>
Online geographic coordinate conversions using the
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoConvert.1.html">
GeoConvert</a> utility
</h3>
<form action="/cgi-bin/GeoConvert" method="get">
<p>
Location
(ex. &laquo;<tt>33.33 44.4</tt>&raquo;,
&laquo;<tt>33d19'47"N 44d23.9'E</tt>&raquo;,
&laquo;<tt>38SMB4488</tt>&raquo;,
&laquo;<tt>38n 444000 3688000</tt>&raquo;):<br>
&nbsp;&nbsp;&nbsp;
<input type=text name="input" size=40 value="$INPUTENC">
</p>
<table>
<tr>
<td>
&nbsp;&nbsp;&nbsp;
Output zone:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<select name="zone" size=1>
EOF
(
cat <<EOF
-3 Match input or standard
-1 Standard UPS/UTM zone
0 UPS
-2 Standard UTM zone
EOF
) | while read z name; do
SELECTED=
test "$z" = "$ZONE" && SELECTED=SELECTED
echo "<option $SELECTED value=\"$z\">$name</option>"
done
for ((z=1; z<=60; ++z)); do
SELECTED=
test "$z" = "$ZONE" && SELECTED=SELECTED
name="UTM zone $z"
echo "<option $SELECTED value=\"$z\">$name</option>"
done
cat <<EOF
</select>
</td>
<td>
&nbsp;&nbsp;&nbsp;
Output precision:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<select name="prec" size=1>
EOF
(
cat <<EOF
-5 100km 1d
-4 10km 0.1d
-3 1km 0.01d 1'
-2 100m 0.001d 0.1'
-1 10m 0.0001d 1"
0 1m 0.00001d 0.1"
1 100mm 0.01"
2 10mm 0.001"
3 1mm 0.0001"
4 100um 0.00001"
5 10um 0.000001"
6 1um 0.0000001"
7 100nm 0.00000001"
8 10nm 0.000000001"
9 1nm 0.0000000001"
10 0.00000000001"
EOF
) | while read p desc; do
SELECTED=
test "$p" = "$PREC" && SELECTED=SELECTED
echo "<option $SELECTED value=\"$p\">$desc</option>"
done
cat <<EOF
</select>
</td>
</tr>
</table>
<p>
Select action:<br>
&nbsp;&nbsp;&nbsp;
<input type="submit" name="option" value="Submit">
<input type="submit" name="option" value="Reset">
</p>
<p>
Results:
<font size="4"><pre>
input = `encodevalue "$INPUT"`
lat lon = $F$LOCG `convertdeg "$LOCD"`$G
<a href="https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system">UTM</a>/<a href="https://en.wikipedia.org/wiki/Universal_Polar_Stereographic">UPS</a> = $F`encodevalue "$LOCU"`$G
<a href="https://en.wikipedia.org/wiki/Military_grid_reference_system">MGRS</a> = $F`encodevalue "$LOCM"`$G</pre></font>
</p>
</form>
<hr>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoConvert.1.html">
GeoConvert (version $VERSION)</a>
converts between geographic (latitude and longitude) coordinates,
<a href="https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system">
universal transverse Mercator (UTM)</a> or
<a href="https://en.wikipedia.org/wiki/Universal_Polar_Stereographic">
universal polar stereographic (UPS)</a> coordinates, and the
<a href="https://en.wikipedia.org/wiki/Military_grid_reference_system">
military grid reference system (MGRS)</a>.
Examples of legal geographic locations are (these all refer to roughly
the same place, Cape Morris Jesup on the northern tip of Greenland):
<pre>
Latitude and longitude: MGRS:
83.627 -32.664 24XWT783908
W32d40 N83d37.6 YUB17770380
83&deg;37'39"N 32&deg;39'52"W UTM:
83:37:39 32:39:52W 25n 504158 9286521
32:39.9W 83:37.6N 430000 9290000 26n
32:40W+0:0:6 83:37.6 UPS:
32:40W+0:0:6 83:38-0:0.4 n 1617772 1403805</pre>
<b>Notes:</b>
<ul>
<li>
The letter in following the zone number in the UTM position is
a hemisphere designator (n or s) and <em>not</em> the MGRS
latitude band letter. "north" or "south" can also be used,
e.g., 25north.
<li>
MGRS coordinates are taken to refer to <em>grid squares</em>
(<em>not</em> to the intersections of grid lines). Thus in UTM
zone 38n, the square area with easting in [444 km, 445 km) and
northing in [3688 km, 3689 km) corresponds to the MGRS square
38SMB4488 (at 1 km precision).
<ul>
<li>
When an MGRS coordinate is read, a representative point
within the grid square, namely, the <em>center</em>, is
returned.
<li>
The MGRS easting and northing are obtained
by <em>truncation</em> to the requested precision
(<em>not</em> rounding).
</ul>
<li>
Usually <em>Output zone</em> should be <em>Match input or
standard</em>. If the latitude and longitude are given, the
standard UPS and UTM zone rules are applied; otherwise the
UPS/UTM selection and the UTM zone match the input. The other
choices let you override this selection.
</ul>
</p>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoConvert.1.html">
GeoConvert</a>,
which is a simple wrapper of the
<a href="https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1GeoCoords.html">
GeographicLib::GeoCoords</a> class,
is one of the utilities provided
with <a href="https://geographiclib.sourceforge.io/">
GeographicLib</a>.
This web interface illustrates a subset of its capabilities. If
you wish to use GeoConvert directly,
<a href="https://sourceforge.net/projects/geographiclib/files/distrib-C++">
download</a>
and compile GeographicLib.
</p>
<hr>
<address>Charles Karney
<a href="mailto:charles@karney.com">&lt;charles@karney.com&gt;</a>
(2022-04-10)</address>
<a href="https://geographiclib.sourceforge.io">
GeographicLib home
</a>
</body>
</html>
EOF

View File

@@ -0,0 +1,35 @@
#! /bin/sh
#
# Geod.cgi (redirect to GeodSolve.cgi)
#
# Copyright (c) Charles Karney (2013) <charles@karney.com> and licensed
# under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
cat <<EOF
Content-type: text/html
<html>
<head>
<title>Online geodesic calculator</title>
<meta HTTP-EQUIV="Refresh"
CONTENT="5; URL=https://geographiclib.sourceforge.io/cgi-bin/GeodSolve">
</head>
<body topmargin=10 leftmargin=10>
<h3>
<blockquote>
<em>
The Geod calculator has been renamed GeodSolve which is available at
<center>
<a href="https://geographiclib.sourceforge.io/cgi-bin/GeodSolve">
https://geographiclib.sourceforge.io/cgi-bin/GeodSolve</a>.
</center>
<br>
You will be redirected there. Click on the link to go there
directly.
</em>
</blockquote>
</h3>
</body>
</html>
EOF

View File

@@ -0,0 +1,387 @@
#! /bin/sh
#
# GeodSolve.cgi
# cgi script for geodesic calculations
#
# Copyright (c) Charles Karney (2011-2022) <charles@karney.com> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
. ./utils.sh
DEFAULTRADIUS=6378137
DEFAULTFLATTENING=1/298.257223563
OPTION=`lookupkey "$QUERY_STRING" option`
if test "$OPTION" = Reset; then
INPUT=
RADIUS=
FLATTENING=
else
INPUT=`lookupcheckkey "$QUERY_STRING" input`
RADIUS=`lookupellipsoid "$QUERY_STRING" radius`
FLATTENING=`lookupellipsoid "$QUERY_STRING" flattening`
FORMAT=`lookupkey "$QUERY_STRING" format`
AZF2=`lookupkey "$QUERY_STRING" azi2`
UNROLL=`lookupkey "$QUERY_STRING" unroll`
PREC=`lookupkey "$QUERY_STRING" prec`
TYPE=`lookupkey "$QUERY_STRING" type`
fi
test "$RADIUS" || RADIUS=$DEFAULTRADIUS
test "$FLATTENING" || FLATTENING=$DEFAULTFLATTENING
test "$FORMAT" || FORMAT=g
test "$AZF2" || AZF2=f
test "$UNROLL" || UNROLL=r
test "$PREC" || PREC=3
test "$TYPE" || TYPE=I
AZIX="fazi2"
test "$AZF2" = b && AZIX="bazi2"
TAG=
if test "$RADIUS" = "$DEFAULTRADIUS" -a \
"$FLATTENING" = "$DEFAULTFLATTENING"; then
TAG=" (WGS84)"
fi
INPUTENC=`encodevalue "$INPUT"`
EXECDIR=../bin
COMMAND="GeodSolve -E -f"
VERSION=`$EXECDIR/$COMMAND --version | cut -f4 -d" "`
F='<font color="blue">'
G='</font>'
S=' '
test $TYPE = I && COMMAND="$COMMAND -i"
COMMANDX="$COMMAND -p 1"
test $FORMAT = d && COMMAND="$COMMAND -$FORMAT"
test $AZF2 = b && COMMAND="$COMMAND -$AZF2"
test $UNROLL = u && COMMAND="$COMMAND -$UNROLL"
test $PREC = 3 || COMMAND="$COMMAND -p $PREC"
STATUS=
POSITION1=
POSITION2=
DIST12=
a12=
m12=
M1221=
S12=
set -o pipefail
if test "$INPUT"; then
OUTPUT=`echo $INPUT | $EXECDIR/$COMMAND -e "$RADIUS" "$FLATTENING" 2>&1 |
head -1`
if test $? -eq 0; then
STATUS=OK
OUTPUTG=`echo $INPUT | $EXECDIR/$COMMANDX -e "$RADIUS" "$FLATTENING" |
head -1`
POS1="`echo $OUTPUT | cut -f1-2 -d' '`"
POS2="`echo $OUTPUT | cut -f4-5 -d' '`"
POSG1="`echo $OUTPUTG | cut -f1-2 -d' '`"
POSG2="`echo $OUTPUTG | cut -f4-5 -d' '`"
AZI1="`echo $OUTPUT | cut -f3 -d' '`"
AZI2="`echo $OUTPUT | cut -f6 -d' '`"
DIST12="`echo $OUTPUT | cut -f7 -d' '`"
a12="`echo $OUTPUT | cut -f8 -d' '`"
m12="`echo $OUTPUT | cut -f9 -d' '`"
M1221="`echo $OUTPUT | cut -f10-11 -d' '`"
S12="`echo $OUTPUT | cut -f12 -d' '`"
if test "$TYPE" = D; then
POSITION1=$(geohack $POSG1 $POS1 Black)\ $(convertdeg "$AZI1")
POSITION2=$F$(geohack $POSG2 $POS2 Blue)\ $(convertdeg "$AZI2")$G
DIST12=$(encodevalue "$DIST12")
else
POSITION1=$(geohack $POSG1 $POS1 Black)\ $F$(convertdeg "$AZI1")$G
POSITION2=$(geohack $POSG2 $POS2 Black)\ $F$(convertdeg "$AZI2")$G
DIST12=$F$(encodevalue "$DIST12")$G
fi
else
STATUS="$OUTPUT"
fi
# echo `date +"%F %T"` "$COMMAND: $INPUT" >> ../persistent/utilities.log
fi
echo Content-type: text/html
echo
cat <<EOF
<html>
<head>
<title>
Online geodesic calculator
</title>
<meta name="description" content="Online geodesic calculator" />
<meta name="author" content="Charles F. F. Karney" />
<meta name="keywords"
content="geodesics,
geodesic distance,
geographic distance,
shortest path,
direct geodesic problem,
inverse geodesic problem,
distance and azimuth,
distance and heading,
range and bearing,
spheroidal triangle,
latitude and longitude,
online calculator,
WGS84 ellipsoid,
GeographicLib" />
</head>
<body>
<h3>
Online geodesic calculations using the
<a href="https://geographiclib.sourceforge.io/C++/doc/GeodSolve.1.html">
GeodSolve</a> utility
</h3>
<form action="/cgi-bin/GeodSolve" method="get">
<p>
Geodesic calculation:
<table>
<tr>
<td valign='baseline'>
&nbsp;&nbsp;&nbsp;
<label for='I'>
<input type="radio" name="type" value="I" id='I'
`test "$TYPE" = I && echo CHECKED`>
&nbsp;Inverse:&nbsp;
</label>
</td>
<td valign='baseline'>
<em>lat1 lon1 lat2 lon2</em>
</td>
<td valign='baseline'>
&rarr; <em>azi1 azi2 s12</em>
</td>
</tr>
<tr>
<td valign='baseline'>
&nbsp;&nbsp;&nbsp;
<label for='D'>
<input type="radio" name="type" value="D" id='D'
`test "$TYPE" = D && echo CHECKED`>
&nbsp;Direct:&nbsp;
</label>
</td>
<td valign='baseline'>
<em>lat1 lon1 azi1 s12</em>
</td>
<td valign='baseline'>
&rarr; <em>lat2 lon2 azi2</em>
</td>
</tr>
</table>
</p>
<p>
Input (ex. &laquo;<tt>40.6 -73.8 49&deg;01'N 2&deg;33'E</tt>&raquo;
[inverse],
&laquo;<tt>40d38'23"N 073d46'44"W 53d30' 5850e3</tt>&raquo;
[direct]):
<br>
&nbsp;&nbsp;&nbsp;
<input type=text name="input" size=72 value="$INPUTENC">
</p>
<p>
<table>
<tr>
<td>
Output format:
</td>
EOF
while read c desc; do
CHECKED=
test "$c" = "$FORMAT" && CHECKED=CHECKED
echo "<td>&nbsp;<label for='$c'>"
echo "<input type='radio' name='format' value='$c' id='$c' $CHECKED>"
echo "$desc</label></td>"
done <<EOF
g decimal degrees
d degrees minutes seconds
EOF
cat <<EOF
</tr>
<tr>
<td>
Heading at point 2:
</td>
EOF
while read c desc; do
CHECKED=
test "$c" = "$AZF2" && CHECKED=CHECKED
echo "<td>&nbsp;<label for='$c'>"
echo "<input type='radio' name='azi2' value='$c' id='$c' $CHECKED>"
echo "$desc</label></td>"
done <<EOF
f forward azimuth
b back azimuth
EOF
cat <<EOF
</tr>
<tr>
<td>
Longitude:
</td>
EOF
while read c desc; do
CHECKED=
test "$c" = "$UNROLL" && CHECKED=CHECKED
echo "<td>&nbsp;<label for='$c'>"
echo "<input type='radio' name='unroll' value='$c' id='$c' $CHECKED>"
echo "$desc</label></td>"
done <<EOF
r reduce to [&minus;180&deg;,180&deg;]
u unroll
EOF
cat <<EOF
</tr>
<tr>
<td>
Output precision:
</td>
<td colspan="2">&nbsp;
<select name="prec" size=1>
EOF
while read p desc; do
SELECTED=
test "$p" = "$PREC" && SELECTED=SELECTED
echo "<option $SELECTED value='$p'> $desc</option>"
done <<EOF
0 1m 0.00001d 0.1"
1 100mm 0.01"
2 10mm 0.001"
3 1mm 0.0001"
4 100&mu;m 0.00001"
5 10&mu;m 0.000001"
6 1&mu;m 0.0000001"
7 100nm 0.00000001"
8 10nm 0.000000001"
9 1nm 0.0000000001"
EOF
cat <<EOF
</select>
</td>
</tr>
<tr>
<td>Equatorial radius:</td>
<td>
<input type=text name="radius" size=20 value="$RADIUS">
</td>
<td>meters</td>
</tr>
<tr>
<td>Flattening:</td>
<td>
<input type=text name="flattening" size=20 value="$FLATTENING">
</td>
</tr>
</table>
</p>
<p>
Select action:<br>
&nbsp;&nbsp;&nbsp;
<input type="submit" name="option" value="Submit">
<input type="submit" name="option" value="Reset">
</p>
<p>
Geodesic (input in black, output in ${F}blue${G}):<br>
<font size="4"><pre>
ellipsoid (a f)$S= `encodevalue "$RADIUS"` `encodevalue "$FLATTENING"`$TAG
status $S= `encodevalue "$STATUS"`
lat1 lon1 fazi1 (&deg;) = $POSITION1
lat2 lon2 $AZIX (&deg;) = $POSITION2
s12 (m) = $DIST12
a12 (&deg;) = $F$a12$G
m12 (m) = $F$m12$G
M12 M21 = $F$M1221$G
S12 (m^2) = $F$S12$G</pre></font>
</p>
</form>
<hr>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeodSolve.1.html">
GeodSolve (version $VERSION)</a>
performs geodesic calculations for an arbitrary ellipsoid of
revolution. The shortest path between two points on the ellipsoid
at (<em>lat1</em>, <em>lon1</em>) and (<em>lat2</em>,
<em>lon2</em>) is called the <em>geodesic</em>; its length
is <em>s12</em> and the geodesic from point 1 to point 2 has
azimuths <em>azi1</em> and <em>azi2</em> at the two end points.
There are two standard geodesic problems:
<ul>
<li> Direct: &nbsp; given [<em>lat1 lon1 azi1 s12</em>], find
[<em>lat2 lon2 azi2</em>];
<li> Inverse: given [<em>lat1 lon1 lat2 lon2</em>], find
[<em>azi1 azi2 s12</em>].
</ul>
Latitudes and longitudes can be given in various formats, for
example (these all refer to the position of Timbuktu):
<pre>
16.776 -3.009
16d47' -3d1'
W3&deg;0'34" N16&deg;46'33"
3:0:34W 16:46:33N</pre>
Azimuths are given in degrees clockwise from north. The
distance <em>s12</em> is in meters.
</p>
<p>
The additional quantities computed are:
<ul>
<li> <em>a12</em>, the arc length on the auxiliary sphere (&deg;),
<li> <em>m12</em>, the reduced length (m),
<li> <em>M12</em> and <em>M21</em>, the geodesic scales,
<li> <em>S12</em>, the area between the geodesic
and the equator (m<sup>2</sup>).
</ul>
</p>
<p>
The ellipsoid is specified by its equatorial radius, <em>a</em>,
and its flattening,
<em>f</em>&nbsp;=
(<em>a</em>&nbsp;&minus;&nbsp;<em>b</em>)/<em>a</em>,
where <em>b</em> is the polar semi-axis. The default values for
these parameters correspond to the WGS84 ellipsoid. The method is
accurate for &minus;99&nbsp;&le; <em>f</em>&nbsp;&le; 0.99
(corresponding to 0.01&nbsp;&le; <em>b</em>/<em>a</em>&nbsp;&le;
100). Note that <em>f</em> is negative for a prolate ellipsoid
(<em>b</em>&nbsp;&gt; <em>a</em>) and that it can be entered as a
fraction, e.g., 1/297.
</p>
<p>
GeodSolve is accurate to about 15&nbsp;nanometers (for the WGS84
ellipsoid) and gives solutions for the inverse problem for any
pair of points.
</p>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeodSolve.1.html">
GeodSolve</a>,
which is a simple wrapper of the
<a href="https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1Geodesic.html">
GeographicLib::Geodesic</a> class,
is one of the utilities provided
with <a href="https://geographiclib.sourceforge.io/">
GeographicLib</a>.
Geodesics can also be computed using JavaScript; see the
<a href="../scripts/geod-calc.html">JavaScript geodesic
calculator</a> and
<a href="../scripts/geod-google.html">geodesics on Google
maps</a>. If you wish to use GeodSolve directly,
<a href="https://sourceforge.net/projects/geographiclib/files/distrib-C++">
download</a>
and compile GeographicLib. The algorithms are described
in C. F. F. Karney,
<a href="https://doi.org/10.1007/s00190-012-0578-z"><i>Algorithms for
geodesics</i></a>,
J. Geodesy <b>87</b>, 43&ndash;55 (2013); DOI:
<a href="https://doi.org/10.1007/s00190-012-0578-z">
10.1007/s00190-012-0578-z</a>;
addenda:
<a href="https://geographiclib.sourceforge.io/geod-addenda.html">
geod-addenda.html</a>. See also the Wikipedia page,
<a href="https://en.wikipedia.org/wiki/Geodesics_on_an_ellipsoid">
Geodesics on an ellipsoid</a>.
</p>
<hr>
<address>Charles Karney
<a href="mailto:charles@karney.com">&lt;charles@karney.com&gt;</a>
(2022-04-10)</address>
<a href="https://geographiclib.sourceforge.io">
GeographicLib home
</a>
</body>
</html>
EOF

View File

@@ -0,0 +1,166 @@
#! /bin/sh
#
# GeoidEval.cgi
# cgi script for geoid height evaluations
#
# Copyright (c) Charles Karney (2011-2022) <charles@karney.com> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
. ./utils.sh
OPTION=`lookupkey "$QUERY_STRING" option`
if test "$OPTION" = Reset; then
INPUT=
else
INPUT=`lookupcheckkey "$QUERY_STRING" input`
fi
INPUTENC=`encodevalue "$INPUT"`
EXECDIR=../bin
COMMAND="GeoidEval"
VERSION=`$EXECDIR/$COMMAND --version | cut -f4 -d" "`
export GEOGRAPHICLIB_DATA=..
F='<font color="blue">'
G='</font>'
POSITION1=
POSITION2=
HEIGHT96=
HEIGHT84=
HEIGHT2008=
set -o pipefail
if test "$INPUT"; then
HEIGHT96=`echo $INPUT |
$EXECDIR/$COMMAND -n egm96-5 | head -1`
if test $? -eq 0; then
POSITION1=`echo $INPUT | $EXECDIR/GeoConvert | head -1`
POSITION1=`geohack $POSITION1 $POSITION1 Black`
POSITION2=\(`echo $INPUT | $EXECDIR/GeoConvert -d -p -1 | head -1`\)
HEIGHT2008=`echo $INPUT |
$EXECDIR/$COMMAND -n egm2008-1 | head -1`
HEIGHT84=`echo $INPUT |
$EXECDIR/$COMMAND -n egm84-15 | head -1`
else
POSITION1=`encodevalue "$HEIGHT96"`
HEIGHT96=
fi
# echo `date +"%F %T"` "$COMMAND: $INPUT" >> ../persistent/utilities.log
fi
echo Content-type: text/html
echo
cat <<EOF
<html>
<head>
<title>
Online geoid calculator
</title>
<meta name="description" content="Online geoid calculator" />
<meta name="author" content="Charles F. F. Karney" />
<meta name="keywords"
content="geoid height,
orthometric height,
earth gravity model,
EGM84, EGM96, EGM2008,
mean sea level, MSL,
height above ellipsoid, HAE,
vertical datum,
latitude and longitude,
online calculator,
WGS84 ellipsoid,
GeographicLib" />
</head>
<body>
<h3>
Online geoid calculations using the
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoidEval.1.html">
GeoidEval</a> utility
</h3>
<form action="/cgi-bin/GeoidEval" method="get">
<p>
Position
(ex. &laquo;<tt>16.78 -3.01</tt>&raquo;,
&laquo;<tt>16d46'33"N 3d0.6'W</tt>&raquo;):<br>
&nbsp;&nbsp;&nbsp;
<input type=text name="input" size=30 value="$INPUTENC">
</p>
<p>
Select action:<br>
&nbsp;&nbsp;&nbsp;
<input type="submit" name="option" value="Submit">
<input type="submit" name="option" value="Reset">
</p>
<p>
Geoid height:
<font size="4"><pre>
lat lon = $POSITION1 `convertdeg "$POSITION2"`
geoid heights (m)
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm2008">EGM2008</a> = $F`encodevalue "$HEIGHT2008"`$G
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm96">EGM96</a> = $F`encodevalue "$HEIGHT96"`$G
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm84">EGM84</a> = $F`encodevalue "$HEIGHT84"`$G</pre></font>
</p>
</form>
<hr>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoidEval.1.html">
GeoidEval (version $VERSION)</a>
computes the height of the geoid above the WGS84 ellipsoid
using interpolation in a grid of values for the earth
gravity models,
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm84">
EGM84</a>, or
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm96">
EGM96</a>,
<a href="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_egm2008">
EGM2008</a>.
The RMS error in the interpolated height is about 1&nbsp;mm.
Give the position in terms of latitude and longitude, for example
(these all refer to the position of Timbuktu):
<pre>
16.776 -3.009
16d47' -3d1'
W3&deg;0'34" N16&deg;46'33"
3:0:34W 16:46:33N</pre>
The coordinates can also be given in UTM, UPS, or MGRS coordinates (see
the documentation on the
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoConvert.1.html">
GeoConvert</a> utility).
</p>
<p>
The height of the geoid above the ellipsoid, <i>N</i>, is
sometimes called the geoid undulation. It can be used to convert
a height above the ellipsoid, <i>h</i>, to the corresponding
height above the geoid (the orthometric height, roughly the height
above mean sea level), <i>H</i>, using the relations
<blockquote>
<i>h</i> = <i>N</i> + <i>H</i>;
&nbsp;&nbsp;<i>H</i> = &minus;<i>N</i> + <i>h</i>.
</blockquote>
</p>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/GeoidEval.1.html">
GeoidEval</a>,
which is a simple wrapper of the
<a href="https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1Geoid.html">
GeographicLib::Geoid</a> class,
is one of the utilities provided
with <a href="https://geographiclib.sourceforge.io/">
GeographicLib</a>.
This web interface illustrates a subset of its capabilities. If
you wish to use GeoidEval directly,
<a href="https://sourceforge.net/projects/geographiclib/files/distrib-C++">
download</a>
and compile GeographicLib. A description of the methods is given
<a href="https://geographiclib.sourceforge.io/C++/doc/geoid.html">
here</a>.
</p>
<p>
</p>
<hr>
<address>Charles Karney
<a href="mailto:charles@karney.com">&lt;charles@karney.com&gt;</a>
(2022-04-10)</address>
<a href="https://geographiclib.sourceforge.io">
GeographicLib home
</a>
</body>
</html>
EOF

View File

@@ -0,0 +1,230 @@
#! /bin/sh
#
# Planimeter.cgi
# cgi script for measuring the area of geodesic polygons
#
# Copyright (c) Charles Karney (2011-2022) <charles@karney.com> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
. ./utils.sh
OPTION=`lookupkey "$QUERY_STRING" option`
if test "$OPTION" = Reset; then
INPUT=
else
INPUT=`lookupcheckkey "$QUERY_STRING" input`
NORM=`lookupkey "$QUERY_STRING" norm`
TYPE=`lookupkey "$QUERY_STRING" type`
RHUMB=`lookupkey "$QUERY_STRING" rhumb`
fi
env > /tmp/env
INPUTENC=`encodevalue "$INPUT"`
if test "$TYPE" = "polyline"; then
LINEFLAG=-l
else
LINEFLAG=
fi
if test "$RHUMB" = "rhumb"; then
RHUMBFLAG=-R
else
RHUMBFLAG=
fi
EXECDIR=../bin
# Don't add -E flag since this utility only treats the WGS84 ellipsoid
COMMAND="Planimeter"
VERSION=`$EXECDIR/$COMMAND --version | cut -f4 -d" "`
STATUS=
NUM=
LEN=
AREA=
if test "$INPUT"; then
STATUS=`echo "$INPUT" | head -1 | $EXECDIR/GeoConvert`
if test $? -eq 0; then
STATUS=OK
OUTPUT=`echo "$INPUT" | $EXECDIR/$COMMAND $LINEFLAG $RHUMBFLAG |
head -1`
NUM="`echo $OUTPUT | cut -f1 -d' '`"
LEN="`echo $OUTPUT | cut -f2 -d' '`"
AREA="`echo $OUTPUT | cut -f3 -d' '`"
if test "$NORM"; then
TRANSFORMEDINPUT=`echo "$INPUT" | $EXECDIR/GeoConvert -p 20 |
sed '/^ERROR/,$d'`
INPUTENC=`encodevalue "$TRANSFORMEDINPUT"`
fi
fi
# echo `date +"%F %T"` "$COMMAND: $INPUT" >> ../persistent/utilities.log
fi
echo Content-type: text/html
echo
cat <<EOF
<html>
<head>
<title>
Online geodesic planimeter
</title>
<meta name="description" content="Online geodesic planimeter" />
<meta name="author" content="Charles F. F. Karney" />
<meta name="keywords"
content="geodesics,
geodesic distance,
geodesic area,
geographic distance,
geographic area,
geodesic polygon,
shortest path,
spheroidal triangle,
latitude and longitude,
rhumb lines,
online calculator,
WGS84 ellipsoid,
GeographicLib" />
</head>
<body>
<h3>
Online geodesic polygon calculations using the
<a href="https://geographiclib.sourceforge.io/C++/doc/Planimeter.1.html">
Planimeter</a> utility
</h3>
<form action="/cgi-bin/Planimeter" method="get">
<p>
<table>
<tr>
<td>
Closed/open:
</td>
<td>&nbsp;<label for="c">
<input type="radio" name="type" value="polygon" id="c"
`test "$LINEFLAG" || echo CHECKED`>
Polygon</label>
</td>
<td>&nbsp;<label for="o">
<input type="radio" name="type" value="polyline" id="o"
`test "$LINEFLAG" && echo CHECKED`>
Polyline</label>
</td>
</tr>
<tr>
<td>
Edge type:
</td>
<td>&nbsp;<label for="g">
<input type="radio" name="rhumb" value="geodesic" id="g"
`test "$RHUMBFLAG" || echo CHECKED`>
Geodesic</label>
</td>
<td>&nbsp;<label for="r">
<input type="radio" name="rhumb" value="rhumb" id="r"
`test "$RHUMBFLAG" && echo CHECKED`>
Rhumb line</label>
</td>
</tr>
</table>
</p>
<p>
Enter the vertices as latitude longitude pairs, one per line:
<br>
&nbsp;&nbsp;&nbsp;
<textarea cols=45 rows=15 name="input">$INPUTENC</textarea>
</p>
<p>
<input type="checkbox" name="norm" value="decdegrees"
`test "$NORM" && echo CHECKED` />
Convert vertices to decimal degrees
</p>
<p>
Select action:<br>
&nbsp;&nbsp;&nbsp;
<input type="submit" name="option" value="Submit">
<input type="submit" name="option" value="Reset">
</p>
<p>
Results:<br>
<font size="4"><pre>
STATUS = $STATUS
number of vertices = $NUM
Perimeter (m) = $LEN
area (m^2) = $AREA</pre></font>
</p>
</form>
<hr>
<p>
In polygon mode,
<a href="https://geographiclib.sourceforge.io/C++/doc/Planimeter.1.html">
Planimeter (version $VERSION)</a>
calculates the perimeter and area of a polygon whose edges are
either geodesics or rhumb lines on the WGS84 ellipsoid.
</p>
<p>
The edges of the polygon are given by the <i>shortest</i> geodesic
or rhumb line between consecutive vertices. In certain cases,
there may be two or many such shortest paths, and in that case,
the polygon is not uniquely specified by its vertices. In such
cases, insert an additional vertex near the middle of the long
edge to define the boundary of the polygon.
</p>
<p>
Counter-clockwise traversal of a polygon results in a positive
area. Arbitrarily complex polygons are allowed. In the case of
self-intersecting polygons the area is accumulated
"algebraically", i.e., the areas of the 2 loops in a figure-8
polygon will partially cancel. There is no need to close the
polygon. Polygons may include one or both poles. In polyline
mode,
<a href="https://geographiclib.sourceforge.io/C++/doc/Planimeter.1.html">
Planimeter</a>
calculates the length of the geodesic path joining the points.
</p>
<p>
Give the vertices in terms of latitude and longitude, for example
(these all refer to the position of Timbuktu):
<pre>
16.776 -3.009
16d47' -3d1'
W3&deg;0'34" N16&deg;46'33"
3:0:34W 16:46:33N</pre>
A blank line or a coordinate which cannot be understood
causes the reading of vertices to be stopped.
</p>
<p>
For moderately complex polygons, the perimeter is accurate to
about 200&nbsp;nm and the area is accurate to about
0.1&nbsp;m<sup>2</sup>.
</p>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/Planimeter.1.html">
Planimeter</a>,
which is a simple wrapper of the
<a href="https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1PolygonAreaT.html">
GeographicLib::PolygonAreaT</a> class,
is one of the utilities provided
with <a href="https://geographiclib.sourceforge.io/">
GeographicLib</a>.
Geodesic areas can also be computed using JavaScript; see the
<a href="../scripts/geod-calc.html">JavaScript geodesic
calculator</a>.
If you wish to use Planimeter directly,
<a href="https://sourceforge.net/projects/geographiclib/files/distrib-C++">
download</a>
and compile GeographicLib. The algorithms are described
in C. F. F. Karney,
<a href="https://doi.org/10.1007/s00190-012-0578-z"><i>Algorithms for
geodesics</i></a>,
J. Geodesy <b>87</b>, 43&ndash;55 (2013); DOI:
<a href="https://doi.org/10.1007/s00190-012-0578-z">
10.1007/s00190-012-0578-z</a>;
addenda:
<a href="https://geographiclib.sourceforge.io/geod-addenda.html">
geod-addenda.html</a>.
</p>
<hr>
<address>Charles Karney
<a href="mailto:charles@karney.com">&lt;charles@karney.com&gt;</a>
(2022-04-10)</address>
<a href="https://geographiclib.sourceforge.io">
GeographicLib home
</a>
</body>
</html>
EOF

View File

@@ -0,0 +1,349 @@
#! /bin/sh
#
# RhumbSolve.cgi
# cgi script for rhumb line calculations
#
# Copyright (c) Charles Karney (2014-2022) <charles@karney.com> and
# licensed under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
. ./utils.sh
DEFAULTRADIUS=6378137
DEFAULTFLATTENING=1/298.257223563
OPTION=`lookupkey "$QUERY_STRING" option`
if test "$OPTION" = Reset; then
INPUT=
RADIUS=
FLATTENING=
else
INPUT=`lookupcheckkey "$QUERY_STRING" input`
RADIUS=`lookupellipsoid "$QUERY_STRING" radius`
FLATTENING=`lookupellipsoid "$QUERY_STRING" flattening`
FORMAT=`lookupkey "$QUERY_STRING" format`
PREC=`lookupkey "$QUERY_STRING" prec`
TYPE=`lookupkey "$QUERY_STRING" type`
fi
test "$RADIUS" || RADIUS=$DEFAULTRADIUS
test "$FLATTENING" || FLATTENING=$DEFAULTFLATTENING
test "$FORMAT" || FORMAT=g
test "$PREC" || PREC=3
test "$TYPE" || TYPE=I
TAG=
if test "$RADIUS" = "$DEFAULTRADIUS" -a \
"$FLATTENING" = "$DEFAULTFLATTENING"; then
TAG=" (WGS84)"
fi
INPUTENC=`encodevalue "$INPUT"`
EXECDIR=../bin
COMMAND="RhumbSolve"
VERSION=`$EXECDIR/$COMMAND --version | cut -f4 -d" "`
F='<font color="blue">'
G='</font>'
test $TYPE = D || COMMAND="$COMMAND -i"
COMMANDX="$COMMAND -p 1"
test $FORMAT = g || COMMAND="$COMMAND -$FORMAT"
test $PREC = 3 || COMMAND="$COMMAND -p $PREC"
GCOMMAND=`echo "$COMMAND" | sed "s/RhumbSolve/GeodSolve -f/"`
GCOMMANDX=`echo "$COMMANDX" | sed "s/RhumbSolve/GeodSolve -f/"`
STATUS=
POSITION1=
POSITION2=
DIST12=
S12=
set -o pipefail
if test "$INPUT"; then
OUTPUT=`echo $INPUT | $EXECDIR/$COMMAND -e "$RADIUS" "$FLATTENING" 2>&1 |
head -1`
if test $? -eq 0; then
STATUS=OK
GOUTPUT=`echo $INPUT | $EXECDIR/$GCOMMAND -e "$RADIUS" "$FLATTENING" |
head -1`
OUTPUTF=`echo $INPUT | $EXECDIR/$COMMANDX -e "$RADIUS" "$FLATTENING" |
head -1`
GOUTPUTF=`echo $INPUT |
$EXECDIR/$GCOMMANDX -e "$RADIUS" "$FLATTENING" |
head -1`
if test "$TYPE" = D; then
POS1="`echo $GOUTPUT | cut -f1-2 -d' '`"
POSG1="`echo $GOUTPUTF | cut -f1-2 -d' '`"
AZI12="`echo $GOUTPUT | cut -f3 -d' '`"
DIST12="`echo $GOUTPUT | cut -f7 -d' '`"
POS2="`echo $OUTPUT | cut -f1-2 -d' '`"
POSG2="`echo $OUTPUTF | cut -f1-2 -d' '`"
S12="`echo $OUTPUT | cut -f3 -d' '`"
POSITION1=$(geohack $POSG1 $POS1 Black)
POSITION2=$F$(geohack $POSG2 $POS2 Blue)$G
echo $POS2 | grep nan > /dev/null &&
POSITION2=$F$(convertdeg "$POS2")$G
AZIMUTH=$(convertdeg "$AZI12")
DIST12=$(encodevalue "$DIST12")
else
POS1="`echo $GOUTPUT | cut -f1-2 -d' '`"
POSG1="`echo $GOUTPUTF | cut -f1-2 -d' '`"
POS2="`echo $GOUTPUT | cut -f4-5 -d' '`"
POSG2="`echo $GOUTPUTF | cut -f4-5 -d' '`"
AZI12="`echo $OUTPUT | cut -f1 -d' '`"
DIST12="`echo $OUTPUT | cut -f2 -d' '`"
S12="`echo $OUTPUT | cut -f3 -d' '`"
POSITION1=$(geohack $POSG1 $POS1 Black)
POSITION2=$(geohack $POSG2 $POS2 Black)
AZIMUTH=$F$(convertdeg "$AZI12")$G
DIST12=$F$(encodevalue "$DIST12")$G
fi
else
STATUS="$OUTPUT"
fi
# echo `date +"%F %T"` "$COMMAND: $INPUT" >> ../persistent/utilities.log
fi
echo Content-type: text/html
echo
cat <<EOF
<html>
<head>
<title>
Online rhumb line calculator
</title>
<meta name="description" content="Online rhumb line calculator" />
<meta name="author" content="Charles F. F. Karney" />
<meta name="keywords"
content="rhumb line, loxodrome,
rhumb line distance,
geographic distance,
direct rhumb line problem,
inverse rhumb line problem,
distance and azimuth,
distance and heading,
range and bearing,
latitude and longitude,
online calculator,
WGS84 ellipsoid,
GeographicLib" />
</head>
<body>
<h3>
Online rhumb line calculations using the
<a href="https://geographiclib.sourceforge.io/C++/doc/RhumbSolve.1.html">
RhumbSolve</a> utility
</h3>
<form action="/cgi-bin/RhumbSolve" method="get">
<p>
Rhumb Line calculation:
<table>
<tr>
<td valign='baseline'>
&nbsp;&nbsp;&nbsp;
<label for='I'>
<input type="radio" name="type" value="I" id='I'
`test "$TYPE" = I && echo CHECKED`>
&nbsp;Inverse:&nbsp;
</label>
</td>
<td valign='baseline'>
<em>lat1 lon1 lat2 lon2</em>
</td>
<td valign='baseline'>
&rarr; <em>azi12 s12</em>
</td>
</tr>
<tr>
<td valign='baseline'>
&nbsp;&nbsp;&nbsp;
<label for='D'>
<input type="radio" name="type" value="D" id='D'
`test "$TYPE" = D && echo CHECKED`>
&nbsp;Direct:&nbsp;
</label>
</td>
<td valign='baseline'>
<em>lat1 lon1 azi12 s12</em>
</td>
<td valign='baseline'>
&rarr; <em>lat2 lon2</em>
</td>
</tr>
</table>
</p>
<p>
Input (ex. &laquo;<tt>40.6 -73.8 49&deg;01'N 2&deg;33'E</tt>&raquo;
[inverse],
&laquo;<tt>40d38'23"N 073d46'44"W 53d30' 5850e3</tt>&raquo;
[direct]):
<br>
&nbsp;&nbsp;&nbsp;
<input type=text name="input" size=72 value="$INPUTENC">
</p>
<p>
<table>
<tr>
<td>
Output format:
</td>
EOF
while read c desc; do
CHECKED=
test "$c" = "$FORMAT" && CHECKED=CHECKED
echo "<td>&nbsp;<label for='$c'>"
echo "<input type='radio' name='format' value='$c' id='$c' $CHECKED>"
echo "$desc</label>"
echo "</td>"
done <<EOF
g Decimal degrees
d Degrees minutes seconds
EOF
cat <<EOF
</tr>
<tr>
<td>
Output precision:
</td>
<td colspan="2">&nbsp;
<select name="prec" size=1>
EOF
while read p desc; do
SELECTED=
test "$p" = "$PREC" && SELECTED=SELECTED
echo "<option $SELECTED value='$p'> $desc</option>"
done <<EOF
0 1m 0.00001d 0.1"
1 100mm 0.01"
2 10mm 0.001"
3 1mm 0.0001"
4 100&mu;m 0.00001"
5 10&mu;m 0.000001"
6 1&mu;m 0.0000001"
7 100nm 0.00000001"
8 10nm 0.000000001"
9 1nm 0.0000000001"
EOF
cat <<EOF
</select>
</td>
</tr>
<tr>
<td>Equatorial radius:</td>
<td>
<input type=text name="radius" size=20 value="$RADIUS">
</td>
<td>meters</td>
</tr>
<tr>
<td>Flattening:</td>
<td>
<input type=text name="flattening" size=20 value="$FLATTENING">
</td>
</tr>
</table>
</p>
<p>
Select action:<br>
&nbsp;&nbsp;&nbsp;
<input type="submit" name="option" value="Submit">
<input type="submit" name="option" value="Reset">
</p>
<p>
Rhumb Line (input in black, output in ${F}blue${G}):<br>
<font size="4"><pre>
ellipsoid (a f) = `encodevalue "$RADIUS"` `encodevalue "$FLATTENING"`$TAG
status = `encodevalue "$STATUS"`
lat1 lon1 (&deg;) = $POSITION1
lat2 lon2 (&deg;) = $POSITION2
azi12 (&deg;) = $AZIMUTH
s12 (m) = $DIST12
S12 (m^2) = $F$S12$G</pre></font>
</p>
</form>
<hr>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/RhumbSolve.1.html">
RhumbSolve (version $VERSION)</a>
performs rhumb line calculations for an arbitrary ellipsoid of
revolution. The path with a constant heading between two points
on the ellipsoid at (<em>lat1</em>, <em>lon1</em>) and
(<em>lat2</em>, <em>lon2</em>) is called the <em>rhumb line</em>
(or <em>loxodrome</em>); its length is <em>s12</em> and the rhumb
line has a forward azimuth <em>azi12</em> along its
length. <b>NOTE:</b> the rhumb line is <em>not</em> the shortest
path between two points; that is the geodesic and it is calculated
by
<a href="https://geographiclib.sourceforge.io/cgi-bin/GeodSolve">
GeodSolve</a>.
</p>
<p>
There are two standard rhumb line problems:
<ul>
<li> Direct: &nbsp; given [<em>lat1 lon1 azi12 s12</em>], find
[<em>lat2 lon2</em>];
<li> Inverse: given [<em>lat1 lon1 lat2 lon2</em>], find
[<em>azi12 s12</em>].
</ul>
Latitudes and longitudes can be given in various formats, for
example (these all refer to the position of Timbuktu):
<pre>
16.776 -3.009
16d47' -3d1'
W3&deg;0'34" N16&deg;46'33"
3:0:34W 16:46:33N</pre>
Azimuths are given in degrees clockwise from north. The
distance <em>s12</em> is in meters.
</p>
<p>
The additional quantity computed is:
<ul>
<li> <em>S12</em>, the area between the rhumb line
and the equator (m<sup>2</sup>).
</ul>
</p>
<p>
A point at a pole is treated as a point a tiny distance away from
the pole on the given line of longitude. The longitude becomes
indeterminate when a rhumb line passes through a pole, and
RhumbSolve reports NaNs for the longitude and the area in this
case.
</p>
<p>
The ellipsoid is specified by its equatorial radius, <em>a</em>,
and its flattening, <em>f</em>&nbsp;=
(<em>a</em>&nbsp;&minus;&nbsp;<em>b</em>)/<em>a</em>,
where <em>b</em> is the polar semi-axis. The default values for
these parameters correspond to the WGS84 ellipsoid. The method is
accurate for &minus;99&nbsp;&le; <em>f</em>&nbsp;&le; 0.99
(corresponding to 0.01&nbsp;&le; <em>b</em>/<em>a</em>&nbsp;&le;
100). Note that <em>f</em> is negative for a prolate ellipsoid
(<em>b</em>&nbsp;&gt; <em>a</em>) and that it can be entered as a
fraction, e.g., 1/297.
</p>
<p>
RhumbSolve is accurate to about 15&nbsp;nanometers (for the WGS84
ellipsoid) and gives solutions for the inverse problem for any
pair of points. The longitude becomes indeterminate when a rhumb
line passes through a pole, and this tool reports NaNs (not a
number) for <em>lon2</em> and <em>S12</em> in this case.
</p>
<p>
<a href="https://geographiclib.sourceforge.io/C++/doc/RhumbSolve.1.html">
RhumbSolve</a>,
which is a simple wrapper of the
<a href="https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1Rhumb.html">
GeographicLib::Rhumb</a> class, is one of the utilities provided
with <a href="https://geographiclib.sourceforge.io/">
GeographicLib</a>. See also the section of the GeographicLib
documentation on
<a href="https://geographiclib.sourceforge.io/C++/doc/rhumb.html">
Rhumb lines</a> and the Wikipedia page,
<a href="https://en.wikipedia.org/wiki/Rhumb_line">
Rhumb line</a>.
</P>
<hr>
<address>Charles Karney
<a href="mailto:charles@karney.com">&lt;charles@karney.com&gt;</a>
(2022-04-10)</address>
<a href="https://geographiclib.sourceforge.io">
GeographicLib home page
</a>
</body>
</html>
EOF

View File

@@ -0,0 +1,37 @@
#! /bin/sh -ex
# This is the script to build the utilities for the cgi-bin scripts. Note:
# 0: To access the machine for running this command, use
# ssh -t karney,geographiclib@shell.sourceforge.net create
# Once logged in the following paths are available
# git: /home/git/p/geographiclib/code.git
WEB=/home/project-web/geographiclib
FRS=/home/frs/project/geographiclib
# 1: The utilities used long double (GEOGRAPHICLIB_PRECISION=3)
# 2: GeoidEval needs access to geoid data which is installed in
# $WEB/geoids. It find this with
# export GEOGRAPHICLIB_DATA=..
# 3: Static libraries are used so the utilities are self contained
# executables.
VERSION=2.0
FULLVERSION=$VERSION-alpha
rm -rf /tmp/GeographicLib-$VERSION /tmp/geog-$VERSION
tar xfpzC $FRS/distrib-C++/GeographicLib-$FULLVERSION.tar.gz /tmp
cd /tmp/GeographicLib-$VERSION
# N.B. $HOME/cmake/bin is in PATH for cmake
cmake \
-D CMAKE_INSTALL_PREFIX=/tmp/geog-$VERSION \
-D BUILD_SHARED_LIBS=OFF \
-D GEOGRAPHICLIB_PRECISION=3 \
-D EXAMPLEDIR= -B BUILD -S .
cd BUILD
make
make install
mkdir -p $WEB/bin-$VERSION
cd /tmp/geog-$VERSION/bin
install CartConvert ConicProj GeodesicProj GeoConvert GeodSolve GeoidEval Gravity MagneticField Planimeter RhumbSolve TransverseMercatorProj $WEB/bin-$VERSION/

View File

@@ -0,0 +1,26 @@
#! /bin/sh
#
# printlogs.cgi
# cgi script for printing error logs
#
# Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed
# under the MIT/X11 License. For more information, see
# https://geographiclib.sourceforge.io/
echo Content-type: text/html
echo
cat <<EOF
<html>
<header>
<title>
GeographicLib web utilities log
</title>
</header>
<body>
<pre>
EOF
cat ../persistent/utilities.log
cat <<EOF
</pre>
</body>
</html>

View File

@@ -0,0 +1,132 @@
# Look up a key in a QUERY_STRING and return raw value
lookuprawkey () {
QUERY="$1"
KEY="$2"
echo "$QUERY" | tr '&' '\n' | grep "^$KEY=" | tail -1 | cut -f2- -d=
}
# Decode raw value translating + to space, changing CR-LF to LF,
# interpreting %XX, converting "," and TAB to spaces, and squeezing
# and trimming spaces.
decodevalue () {
echo "$1" | tr -s '+' ' ' | sed \
-e 's/\\/%5C/g' \
-e 's/%0[dD]%0[aA]/%0A/g' \
-e 's/%\([0-9a-fA-F][0-9a-fA-F]\)/\\x\1/g' -e s/%/%%/g |
xargs -d '\n' printf | tr -s ',\t' ' ' | sed -e 's/^ //' -e 's/ $//'
}
# Apply conversions for the various degree, minute, and second
# symbols, following conversions in DMS.cpp. Add left/right guillemot
# symbols (used to quote examples) to the list of removed symbols.
# Translate UTF-8 and &#nnn; sequences first, then single character
# replacements, then ' ' -> ". This is the same as the order in
# DMS.cpp except for the addition of the &#nnn; sequences and the
# removal of left/right guillemots.
translate () {
echo "$1" |
sed \
-e 's/%C2%B0/d/g' -e 's/%26%23176%3B/d/g' \
-e 's/%C2%BA/d/g' -e 's/%26%23186%3B/d/g' \
-e 's/%E2%81%B0/d/g' -e 's/%26%238304%3B/d/g' \
-e 's/%CB%9A/d/g' -e 's/%26%23730%3B/d/g' \
-e 's/%E2%88%98/d/g' -e 's/%26%238728%3B/d/g' \
\
-e 's/%E2%80%B2/%27/g' -e 's/%26%238242%3B/%27/g' \
-e 's/%E2%80%B5/%27/g' -e 's/%26%238245%3B/%27/g' \
-e 's/%C2%B4/%27/g' -e 's/%26%23180%3B/%27/g' \
-e 's/%E2%80%98/%27/g' -e 's/%26%238216%3B/%27/g' \
-e 's/%E2%80%99/%27/g' -e 's/%26%238217%3B/%27/g' \
-e 's/%E2%80%9B/%27/g' -e 's/%26%238219%3B/%27/g' \
-e 's/%CA%B9/%27/g' -e 's/%26%23697%3B/%27/g' \
-e 's/%CB%8A/%27/g' -e 's/%26%23714%3B/%27/g' \
-e 's/%CB%8B/%27/g' -e 's/%26%23715%3B/%27/g' \
\
-e 's/%E2%80%B3/%22/g' -e 's/%26%238243%3B/%22/g' \
-e 's/%E2%80%B6/%22/g' -e 's/%26%238246%3B/%22/g' \
-e 's/%CB%9D/%22/g' -e 's/%26%23733%3B/%22/g' \
-e 's/%E2%80%9C/%22/g' -e 's/%26%238220%3B/%22/g' \
-e 's/%E2%80%9D/%22/g' -e 's/%26%238221%3B/%22/g' \
-e 's/%E2%80%9F/%22/g' -e 's/%26%238223%3B/%22/g' \
-e 's/%CA%BA/%22/g' -e 's/%26%23698%3B/%22/g' \
\
-e 's/%E2%9E%95/%2B/g' -e 's/%26%2310133%3B/%2B/g' \
-e 's/%E2%81%A4/%2B/g' -e 's/%26%238292%3B/%2B/g' \
\
-e 's/%E2%80%90/-/g' -e 's/%26%238208%3B/-/g' \
-e 's/%E2%80%91/-/g' -e 's/%26%238209%3B/-/g' \
-e 's/%E2%80%93/-/g' -e 's/%26%238211%3B/-/g' \
-e 's/%E2%80%94/-/g' -e 's/%26%238212%3B/-/g' \
-e 's/%E2%88%92/-/g' -e 's/%26%238722%3B/-/g' \
-e 's/%E2%9E%96/-/g' -e 's/%26%2310134%3B/-/g' \
\
-e 's/%C2%A0//g' -e 's/%26%23160%3B//g' \
-e 's/%E2%80%87//g' -e 's/%26%238199%3B//g' \
-e 's/%E2%80%89//g' -e 's/%26%238201%3B//g' \
-e 's/%E2%80%8A//g' -e 's/%26%238202%3B//g' \
-e 's/%E2%80%8B//g' -e 's/%26%238203%3B//g' \
-e 's/%E2%80%AF//g' -e 's/%26%238239%3B//g' \
-e 's/%C2%AB//g' -e 's/%26%23171%3B//g' \
-e 's/%C2%BB//g' -e 's/%26%23187%3B//g' \
-e 's/%E2%81%A3//g' -e 's/%26%238291%3B//g' \
\
-e 's/%B0/d/g' \
-e 's/%BA/d/g' \
-e 's/%2A/d/g' -e 's/\*/d/g' \
-e 's/%60/%27/g' -e 's/`/%27/g' \
-e 's/%B4/%27/g' \
-e 's/%91/%27/g' \
-e 's/%92/%27/g' \
-e 's/%93/%22/g' \
-e 's/%94/%22/g' \
-e 's/%96/-/g' \
-e 's/%97/-/g' \
-e 's/%A0//g' \
-e 's/%AB//g' \
-e 's/%BB//g' \
\
-e 's/%27%27/%22/g'
}
# Look up and decode a key
lookupkey () {
decodevalue `lookuprawkey "$1" "$2"`
}
# Look up, translate, and decode a key. If result has unprintable
# characters, log the raw value.
lookupcheckkey () {
RAWVAL=`lookuprawkey "$1" "$2"`
VALUE=`translate "$RAWVAL"`
VALUE=`decodevalue "$VALUE"`
test `echo "$VALUE" | tr -d '[ -~\n\t]' | wc -c` -ne 0 &&
echo `date +"%F %T"` Unprintable "$RAWVAL" >> ../persistent/utilities.log
echo "$VALUE"
}
# Look up ellipsoid parameter leaving only allowed characters (--/ -> -, ., /)
lookupellipsoid () {
VALUE=`lookuprawkey "$1" "$2"`
VALUE=`echo "$VALUE" | sed -e 's/%26%238722%3B/-/g'`
VALUE=`decodevalue "$VALUE"`
VALUE=`echo "$VALUE" | tr -cd '[0-9--/Ee]'`
echo "$VALUE"
}
# Encode a string for inclusion into HTML.
encodevalue () {
echo "$1" | sed -e 's/&/\&amp;/g' -e 's/"/\&quot;/g' \
-e 's/>/\&gt;/g' -e 's/</\&lt;/g' -e "s/'/\&#39;/g" -e 's/`/\&#96;/g'
}
# Encode and convert d to &deg;
convertdeg () {
encodevalue "$1" | sed -e 's/d/\&deg;/g'
}
# Generate GeoHack URL. $1 $2 are real position; $3 $4 is displayed
# postion; $5 is link color
geohack () {
echo "<a href=\"http://tools.wmflabs.org/geohack/geohack.php?params=$1;$2\" style=\"color:$5\">$(convertdeg "$3 $4")</a>"
}