Files
SimCore/libs/geographiclib/cgi-bin/RhumbSolve.cgi

350 lines
12 KiB
Bash

#! /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