Last active
August 29, 2015 13:57
-
-
Save tuxite/9811748 to your computer and use it in GitHub Desktop.
Some formulas to computes coordinates, distance and bearing on a rhumb line.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Changed correction of bearing thanks to @navugo remarks.