#! /bin/sh # # RhumbSolve.cgi # cgi script for rhumb line calculations # # Copyright (c) Charles Karney (2014-2022) 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='' G='' 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 < Online rhumb line calculator

Online rhumb line calculations using the RhumbSolve utility

Rhumb Line calculation:
    lat1 lon1 lat2 lon2 azi12 s12
    lat1 lon1 azi12 s12 lat2 lon2

Input (ex. «40.6 -73.8 49°01'N 2°33'E» [inverse], «40d38'23"N 073d46'44"W 53d30' 5850e3» [direct]):
   

EOF while read c desc; do CHECKED= test "$c" = "$FORMAT" && CHECKED=CHECKED echo "" done <
Output format:  " echo "
Output precision:  
Equatorial radius: meters
Flattening:

Select action:
   

Rhumb Line (input in black, output in ${F}blue${G}):

    ellipsoid (a f) = `encodevalue "$RADIUS"` `encodevalue "$FLATTENING"`$TAG
    status          = `encodevalue "$STATUS"`

    lat1 lon1 (°)   = $POSITION1
    lat2 lon2 (°)   = $POSITION2
    azi12 (°)       = $AZIMUTH
    s12 (m)         = $DIST12

    S12 (m^2)       = $F$S12$G


RhumbSolve (version $VERSION) performs rhumb line calculations for an arbitrary ellipsoid of revolution. The path with a constant heading between two points on the ellipsoid at (lat1, lon1) and (lat2, lon2) is called the rhumb line (or loxodrome); its length is s12 and the rhumb line has a forward azimuth azi12 along its length. NOTE: the rhumb line is not the shortest path between two points; that is the geodesic and it is calculated by GeodSolve.

There are two standard rhumb line problems:

Latitudes and longitudes can be given in various formats, for example (these all refer to the position of Timbuktu):
        16.776 -3.009
        16d47' -3d1'
        W3°0'34" N16°46'33"
        3:0:34W 16:46:33N
Azimuths are given in degrees clockwise from north. The distance s12 is in meters.

The additional quantity computed is:

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.

The ellipsoid is specified by its equatorial radius, a, and its flattening, f = (a − b)/a, where b is the polar semi-axis. The default values for these parameters correspond to the WGS84 ellipsoid. The method is accurate for −99 ≤ f ≤ 0.99 (corresponding to 0.01 ≤ b/a ≤ 100). Note that f is negative for a prolate ellipsoid (b > a) and that it can be entered as a fraction, e.g., 1/297.

RhumbSolve is accurate to about 15 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 lon2 and S12 in this case.

RhumbSolve, which is a simple wrapper of the GeographicLib::Rhumb class, is one of the utilities provided with GeographicLib. See also the section of the GeographicLib documentation on Rhumb lines and the Wikipedia page, Rhumb line.


Charles Karney <charles@karney.com> (2022-04-10)
GeographicLib home page EOF