Skip to content

Instantly share code, notes, and snippets.

@tuxite
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuxite/9811748 to your computer and use it in GitHub Desktop.
Save tuxite/9811748 to your computer and use it in GitHub Desktop.
Some formulas to computes coordinates, distance and bearing on a rhumb line.
/* jshint indent: 4 */
/* General functions */
function modulo180(val) {
if (Math.abs(val) > 180) {
val = -(val % 180);
}
return val;
}
function inc_lat(lat) {
var result = Math.log(Math.tan(toRad(45 + lat / 2)));
return toDeg(result);
}
function toDeg(rad) {
return 180 * rad / Math.PI;
}
function toRad(deg) {
return Math.PI * deg / 180;
}
/**
* Returns the distance from two points, in M, travelling along a rhumb line
*
* Exact formula (longitude W negative)
*
* @param {lat, lon} point: Latitude/longitude of departure point
* {lat, lon} point: Latitude/longitude of arrival point
* @returns {Number} Distance in M between this point and destination point
* {Number} Bearing of the segment
*/
function RhumbLine(pointA, pointB) {
// Differences latLon
var dlat = pointB.lat - pointA.lat,
dlon = modulo180(parseFloat(-pointB.lon) + parseFloat(pointA.lon));
var bearing = 0,
distance = 0;
// Computes the bearing
// Increasing latitudes
var inc_latA = inc_lat(pointA.lat),
inc_latB = inc_lat(pointB.lat);
// Special cases
if (dlat === 0) {
// East-West track
bearing = 90;
} else if (dlon === 0) {
// North-South track
bearing = 0;
} else {
// Default case
bearing = toDeg(Math.atan(dlon / (inc_latA - inc_latB)));
}
// Applying correction depending of relative position of A vs. B
if ((dlon > 0) and (bearing <0) {
// Case North West
bearing += 360;
} else {
bearing += 180;
}
// Computes the distance
// No horizontal track
if (dlat !== 0) {
distance = Math.abs(dlat / Math.cos(toRad(bearing)));
} else {
// Horizontal track
distance = Math.abs(dlon * Math.cos(toRad(pointA.lat)));
}
distance *= 60;
// Return
return {
bearing: bearing,
distance: distance
};
}
/**
* Returns the coordinates of the arrival point, in M, travelling along a rhumb line.
*
* Exact formula (longitude W negative)
*
* @param {distance} Distance of the track
* {bearing} Bearing of the track
* {bearing} point: Latitude/longitude of departure point
* @returns {lat, lon} point: Latitude/longitude of arrival point
*/
function ArrivalPoint(bearing, distance, start) {
// Computing the arrival latitude
var point = {};
var dlat = distance * Math.cos(toRad(bearing)) / 60;
point.lat = start.lat + dlat;
// Computing the arrival longitude
var dlon = 0;
if (dlat !== 0) {
// Increasing latitudes
var inc_latA = inc_lat(start.lat),
inc_latB = inc_lat(point.lat);
dlon = (inc_latA - inc_latB) * Math.tan(toRad(bearing));
} else {
// East-West track
dlon = distance / Math.cos(toRad(start.lat));
}
// Special case: South departure point
if (start.lat < 0) {
dlon *= -1;
}
point.lon = start.lon - dlon;
return point;
}
@tuxite
Copy link
Author

tuxite commented Apr 9, 2014

Changed correction of bearing thanks to @navugo remarks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment