Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

geolib

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

geolib - npm Package Compare versions

Comparing version 1.1.7 to 1.1.8

671

geolib.js
/**
* A small library to provide some basic geo functions like distance calculation,
* conversion of decimal coordinates to sexagesimal and vice versa, etc.
* WGS 84 (World Geodetic System 1984)
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version 1.1.7
* @license http://www.gnu.org/licenses/lgpl-3.0.txt LGPL
*
*/
* A small library to provide some basic geo functions like distance calculation,
* conversion of decimal coordinates to sexagesimal and vice versa, etc.
* WGS 84 (World Geodetic System 1984)
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version 1.1.8
* @license LGPL
**/

@@ -27,29 +26,62 @@ (function (window, undefined) {

/**
* Calculates geodetic distance between two points specified by latitude/longitude using
* Vincenty inverse formula for ellipsoids
* Vincenty Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2010
* (Licensed under CC BY 3.0)
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @param integer Accuracy (in meters)
* @return integer Distance (in meters)
*/
* Get the key names for a geo point.
*
* @param object Point position {latitude: 123, longitude: 123, elevation: 123}
* @return object {
* longitude: 'lng|long|longitude',
* latitude: 'lat|latitude',
* elevation: 'alt|altitude|elev|elevation'
* }
*/
getKeys: function(point) {
var latitude = point.hasOwnProperty('lat') ? 'lat' : 'latitude';
var longitude = (point.hasOwnProperty('lng') ? 'lng' : false) ||
(point.hasOwnProperty('long') ? 'long' : false) ||
'longitude';
var elevation = (point.hasOwnProperty('alt') ? 'alt' : false) ||
(point.hasOwnProperty('altitude') ? 'altitude' : false) ||
(point.hasOwnProperty('elev') ? 'elev' : false) ||
'elevation';
return {
latitude: latitude,
longitude: longitude,
elevation: elevation
};
},
/**
* Calculates geodetic distance between two points specified by latitude/longitude using
* Vincenty inverse formula for ellipsoids
* Vincenty Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2010
* (Licensed under CC BY 3.0)
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @param integer Accuracy (in meters)
* @return integer Distance (in meters)
*/
getDistance: function(start, end, accuracy) {
accuracy = parseInt(accuracy, 10) || 1;
var keys = geolib.getKeys(start);
var latitude = keys.latitude;
var longitude = keys.longitude;
var elevation = keys.elevation;
accuracy = Math.floor(accuracy) || 1;
var coord1 = {}, coord2 = {};
coord1.latitude = geolib.useDecimal(start.latitude);
coord1.longitude = geolib.useDecimal(start.longitude);
coord1[latitude] = geolib.useDecimal(start[latitude]);
coord1[longitude] = geolib.useDecimal(start[longitude]);
coord2.latitude = geolib.useDecimal(end.latitude);
coord2.longitude = geolib.useDecimal(end.longitude);
coord2[latitude] = geolib.useDecimal(end[latitude]);
coord2[longitude] = geolib.useDecimal(end[longitude]);
var a = 6378137, b = 6356752.314245, f = 1/298.257223563; // WGS-84 ellipsoid params
var L = (coord2.longitude-coord1.longitude).toRad();
var L = (coord2[longitude]-coord1[longitude]).toRad();
var U1 = Math.atan((1-f) * Math.tan(parseFloat(coord1.latitude).toRad()));
var U2 = Math.atan((1-f) * Math.tan(parseFloat(coord2.latitude).toRad()));
var cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM, sinSigma;
var U1 = Math.atan((1-f) * Math.tan(parseFloat(coord1[latitude]).toRad()));
var U2 = Math.atan((1-f) * Math.tan(parseFloat(coord2[latitude]).toRad()));
var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);

@@ -61,3 +93,3 @@ var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);

var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);
var sinSigma = (
sinSigma = (
Math.sqrt(

@@ -75,10 +107,12 @@ (

);
if (sinSigma==0) {
if (sinSigma === 0) {
return geolib.distance = 0; // co-incident points
}
var cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
var sigma = Math.atan2(sinSigma, cosSigma);
var sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
var cosSqAlpha = 1 - sinAlpha * sinAlpha;
var cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
sigma = Math.atan2(sinSigma, cosSigma);
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
cosSqAlpha = 1 - sinAlpha * sinAlpha;
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
if (isNaN(cos2SigmaM)) {

@@ -109,4 +143,4 @@ cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)

if (iterLimit==0) {
return NaN // formula failed to converge
if (iterLimit === 0) {
return NaN; // formula failed to converge
}

@@ -159,4 +193,10 @@

distance = distance.toFixed(3); // round to 1mm precision
return geolib.distance = parseInt(Math.round(distance/accuracy)*accuracy, 10)
if (start.hasOwnProperty(elevation) && end.hasOwnProperty(elevation)) {
var climb = Math.abs(start[elevation] - end[elevation]);
distance = Math.sqrt(distance*distance + climb*climb);
}
return geolib.distance = Math.floor(Math.round(distance/accuracy)*accuracy);
/*

@@ -174,20 +214,24 @@ // note: to return initial/final bearings in addition to distance, use something like:

/**
* Calculates the distance between two spots.
* This method is more simple but also more inaccurate
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @param integer Accuracy (in meters)
* @return integer Distance (in meters)
*/
* Calculates the distance between two spots.
* This method is more simple but also more inaccurate
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @param integer Accuracy (in meters)
* @return integer Distance (in meters)
*/
getDistanceSimple: function(start, end, accuracy) {
accuracy = parseInt(accuracy, 10) || 1;
var keys = geolib.getKeys(start);
var latitude = keys.latitude;
var longitude = keys.longitude;
accuracy = Math.floor(accuracy) || 1;
var coord1 = {}, coord2 = {};
coord1.latitude = parseFloat(geolib.useDecimal(start.latitude)).toRad();
coord1.longitude = parseFloat(geolib.useDecimal(start.longitude)).toRad();
coord1[latitude] = parseFloat(geolib.useDecimal(start[latitude])).toRad();
coord1[longitude] = parseFloat(geolib.useDecimal(start[longitude])).toRad();
coord2.latitude = parseFloat(geolib.useDecimal(end.latitude)).toRad();
coord2.longitude = parseFloat(geolib.useDecimal(end.longitude)).toRad();
coord2[latitude] = parseFloat(geolib.useDecimal(end[latitude])).toRad();
coord2[longitude] = parseFloat(geolib.useDecimal(end[longitude])).toRad();

@@ -198,15 +242,15 @@ var distance =

Math.sin(
coord2.latitude
coord2[latitude]
) *
Math.sin(
coord1.latitude
coord1[latitude]
) +
Math.cos(
coord2.latitude
coord2[latitude]
) *
Math.cos(
coord1.latitude
coord1[latitude]
) *
Math.cos(
coord1.longitude - coord2.longitude
coord1[longitude] - coord2[longitude]
)

@@ -216,3 +260,3 @@ ) * radius

return geolib.distance = parseInt(Math.round(distance/accuracy)*accuracy, 10);
return geolib.distance = Math.floor(Math.round(distance/accuracy)*accuracy);

@@ -223,9 +267,17 @@ },

/**
* Calculates the center of a collection of geo coordinates
*
* @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
* @return object {latitude: centerLat, longitude: centerLng, distance: diagonalDistance}
*/
* Calculates the center of a collection of geo coordinates
*
* @param array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
* @return object {latitude: centerLat, longitude: centerLng, distance: diagonalDistance}
*/
getCenter: function(coords) {
if (!coords.length) {
return false;
}
var keys = geolib.getKeys(coords[0]);
var latitude = keys.latitude;
var longitude = keys.longitude;
var max = function( array ){

@@ -242,4 +294,4 @@ return Math.max.apply( Math, array );

for(var coord in coords) {
splitCoords.lat.push(geolib.useDecimal(coords[coord].latitude));
splitCoords.lng.push(geolib.useDecimal(coords[coord].longitude));
splitCoords.lat.push(geolib.useDecimal(coords[coord][latitude]));
splitCoords.lng.push(geolib.useDecimal(coords[coord][longitude]));
}

@@ -256,3 +308,3 @@

// distance from the deepest left to the highest right point (diagonal distance)
var distance = geolib.convertUnit('km', geolib.getDistance(minLat, minLng, maxLat, maxLng));
var distance = geolib.convertUnit('km', geolib.getDistance({lat:minLat, lng:minLng}, {lat:maxLat, lng:maxLng}));

@@ -263,23 +315,78 @@ return {"latitude": lat, "longitude": lng, "distance": distance};

/**
* Gets the max and min, latitude, longitude, and elevation (if provided).
* @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return object {maxLat: maxLat,
* minLat: minLat
* maxLng: maxLng,
* minLng: minLng,
* maxElev: maxElev,
* minElev: minElev}
*/
getBounds: function(coords) {
if (!coords.length) {
return false;
}
var keys = geolib.getKeys(coords[0]);
var latitude = keys.latitude;
var longitude = keys.longitude;
var elevation = keys.elevation;
var useElevation = coords[0].hasOwnProperty(elevation);
var stats = {
maxLat: 0,
minLat: Infinity,
maxLng: 0,
minLng: Infinity
};
if (useElevation) {
stats.maxElev = 0;
stats.minElev = Infinity;
}
for (var i = 0, l = coords.length; i < l; ++i) {
stats.maxLat = Math.max(coords[i][latitude], stats.maxLat);
stats.minLat = Math.min(coords[i][latitude], stats.minLat);
stats.maxLng = Math.max(coords[i][longitude], stats.maxLng);
stats.minLng = Math.min(coords[i][longitude], stats.minLng);
if (useElevation) {
stats.maxElev = Math.max(coords[i][elevation], stats.maxElev);
stats.minElev = Math.min(coords[i][elevation], stats.minElev);
}
}
return stats;
},
/**
* Checks whether a point is inside of a polygon or not.
* Note that the polygon coords must be in correct order!
*
* @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
* @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return bool true if the coordinate is inside the given polygon
*/
* Checks whether a point is inside of a polygon or not.
* Note that the polygon coords must be in correct order!
*
* @param object coordinate to check e.g. {latitude: 51.5023, longitude: 7.3815}
* @param array array with coords e.g. [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return bool true if the coordinate is inside the given polygon
*/
isPointInside: function(latlng, coords) {
var keys = geolib.getKeys(latlng);
var latitude = keys.latitude;
var longitude = keys.longitude;
for(var c = false, i = -1, l = coords.length, j = l - 1; ++i < l; j = i) {
(
(coords[i].longitude <= latlng.longitude && latlng.longitude < coords[j].longitude) ||
(coords[j].longitude <= latlng.longitude && latlng.longitude < coords[i].longitude)
)
&& (latlng.latitude < (coords[j].latitude - coords[i].latitude)
* (latlng.longitude - coords[i].longitude)
/ (coords[j].longitude - coords[i].longitude) + coords[i].latitude)
&& (c = !c);
if(
(
(coords[i][longitude] <= latlng[longitude] && latlng[longitude] < coords[j][longitude]) ||
(coords[j][longitude] <= latlng[longitude] && latlng[longitude] < coords[i][longitude])
) &&
(
latlng[latitude] < (coords[j][latitude] - coords[i][latitude]) *
(latlng[longitude] - coords[i][longitude]) /
(coords[j][longitude] - coords[i][longitude]) +
coords[i][latitude]
)
) {
c = !c;
}

@@ -294,9 +401,9 @@ }

/**
* Checks whether a point is inside of a circle or not.
*
* @param object coordinate to check (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object coordinate of the circle's center (e.g. {latitude: 51.4812, longitude: 7.4025})
* @param integer maximum radius in meters
* @return bool true if the coordinate is inside the given radius
*/
* Checks whether a point is inside of a circle or not.
*
* @param object coordinate to check (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object coordinate of the circle's center (e.g. {latitude: 51.4812, longitude: 7.4025})
* @param integer maximum radius in meters
* @return bool true if the coordinate is inside the given radius
*/
isPointInCircle: function(latlng, center, radius) {

@@ -310,21 +417,25 @@

/**
* Gets rhumb line bearing of two points. Find out about the difference between rhumb line and
* great circle bearing on Wikipedia. It's quite complicated. Rhumb line should be fine in most cases:
*
* http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description
*
* Function heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0)
* http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @return integer calculated bearing
*/
* Gets rhumb line bearing of two points. Find out about the difference between rhumb line and
* great circle bearing on Wikipedia. It's quite complicated. Rhumb line should be fine in most cases:
*
* http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description
*
* Function heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0)
* http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @return integer calculated bearing
*/
getRhumbLineBearing: function(originLL, destLL) {
var keys = geolib.getKeys(originLL);
var latitude = keys.latitude;
var longitude = keys.longitude;
// difference of longitude coords
var diffLon = geolib.useDecimal(destLL.longitude).toRad() - geolib.useDecimal(originLL.longitude).toRad();
var diffLon = geolib.useDecimal(destLL[longitude]).toRad() - geolib.useDecimal(originLL[longitude]).toRad();
// difference latitude coords phi
var diffPhi = Math.log(Math.tan(geolib.useDecimal(destLL.latitude).toRad() / 2 + Math.PI / 4) / Math.tan(geolib.useDecimal(originLL.latitude).toRad() / 2 + Math.PI / 4));
var diffPhi = Math.log(Math.tan(geolib.useDecimal(destLL[latitude]).toRad() / 2 + Math.PI / 4) / Math.tan(geolib.useDecimal(originLL[latitude]).toRad() / 2 + Math.PI / 4));

@@ -348,15 +459,19 @@ // recalculate diffLon if it is greater than pi

/**
* Gets great circle bearing of two points. See description of getRhumbLineBearing for more information
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @return integer calculated bearing
*/
* Gets great circle bearing of two points. See description of getRhumbLineBearing for more information
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @return integer calculated bearing
*/
getBearing: function(originLL, destLL) {
destLL.latitude = geolib.useDecimal(destLL.latitude);
destLL.longitude = geolib.useDecimal(destLL.longitude);
originLL.latitude = geolib.useDecimal(originLL.latitude);
originLL.longitude = geolib.useDecimal(originLL.longitude);
var keys = geolib.getKeys(originLL);
var latitude = keys.latitude;
var longitude = keys.longitude;
destLL[latitude] = geolib.useDecimal(destLL[latitude]);
destLL[longitude] = geolib.useDecimal(destLL[longitude]);
originLL[latitude] = geolib.useDecimal(originLL[latitude]);
originLL[longitude] = geolib.useDecimal(originLL[longitude]);
var bearing = (

@@ -366,22 +481,22 @@ (

Math.sin(
destLL.longitude.toRad() -
originLL.longitude.toRad()
destLL[longitude].toRad() -
originLL[longitude].toRad()
) *
Math.cos(
destLL.latitude.toRad()
destLL[latitude].toRad()
),
Math.cos(
originLL.latitude.toRad()
originLL[latitude].toRad()
) *
Math.sin(
destLL.latitude.toRad()
destLL[latitude].toRad()
) -
Math.sin(
originLL.latitude.toRad()
originLL[latitude].toRad()
) *
Math.cos(
destLL.latitude.toRad()
destLL[latitude].toRad()
) *
Math.cos(
destLL.longitude.toRad() - originLL.longitude.toRad()
destLL[longitude].toRad() - originLL[longitude].toRad()
)

@@ -398,16 +513,16 @@ )

/**
* Gets the compass direction from an origin coordinate to a destination coordinate.
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @param string Bearing mode. Can be either circle or rhumbline
* @return object Returns an object with a rough (NESW) and an exact direction (NNE, NE, ENE, E, ESE, etc).
*/
* Gets the compass direction from an origin coordinate to a destination coordinate.
*
* @param object origin coordinate (e.g. {latitude: 51.5023, longitude: 7.3815})
* @param object destination coordinate
* @param string Bearing mode. Can be either circle or rhumbline
* @return object Returns an object with a rough (NESW) and an exact direction (NNE, NE, ENE, E, ESE, etc).
*/
getCompassDirection: function(originLL, destLL, bearingMode) {
var direction;
var direction, bearing;
if(bearingMode == 'circle') { // use great circle bearing
var bearing = geolib.getBearing(originLL, destLL);
bearing = geolib.getBearing(originLL, destLL);
} else { // default is rhumb line bearing
var bearing = geolib.getRhumbLineBearing(originLL, destLL);
bearing = geolib.getRhumbLineBearing(originLL, destLL);
}

@@ -420,45 +535,45 @@

case 2:
direction = {exact: "NE", rough: "N"}
direction = {exact: "NE", rough: "N"};
break;
case 3:
direction = {exact: "ENE", rough: "E"}
direction = {exact: "ENE", rough: "E"};
break;
case 4:
direction = {exact: "E", rough: "E"}
direction = {exact: "E", rough: "E"};
break;
case 5:
direction = {exact: "ESE", rough: "E"}
direction = {exact: "ESE", rough: "E"};
break;
case 6:
direction = {exact: "SE", rough: "E"}
direction = {exact: "SE", rough: "E"};
break;
case 7:
direction = {exact: "SSE", rough: "S"}
direction = {exact: "SSE", rough: "S"};
break;
case 8:
direction = {exact: "S", rough: "S"}
direction = {exact: "S", rough: "S"};
break;
case 9:
direction = {exact: "SSW", rough: "S"}
direction = {exact: "SSW", rough: "S"};
break;
case 10:
direction = {exact: "SW", rough: "S"}
direction = {exact: "SW", rough: "S"};
break;
case 11:
direction = {exact: "WSW", rough: "W"}
direction = {exact: "WSW", rough: "W"};
break;
case 12:
direction = {exact: "W", rough: "W"}
direction = {exact: "W", rough: "W"};
break;
case 13:
direction = {exact: "WNW", rough: "W"}
direction = {exact: "WNW", rough: "W"};
break;
case 14:
direction = {exact: "NW", rough: "W"}
direction = {exact: "NW", rough: "W"};
break;
case 15:
direction = {exact: "NNW", rough: "N"}
direction = {exact: "NNW", rough: "N"};
break;
default:
direction = {exact: "N", rough: "N"}
direction = {exact: "N", rough: "N"};
}

@@ -472,14 +587,18 @@

/**
* Sorts an array of coords by distance from a reference coordinate
*
* @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return array ordered array
*/
* Sorts an array of coords by distance from a reference coordinate
*
* @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return array ordered array
*/
orderByDistance: function(latlng, coords) {
var keys = geolib.getKeys(latlng);
var latitude = keys.latitude;
var longitude = keys.longitude;
var coordsArray = [];
for(var coord in coords) {
var d = geolib.getDistance(latlng, coords[coord]);
coordsArray.push({key: coord, latitude: coords[coord].latitude, longitude: coords[coord].longitude, distance: d});
coordsArray.push({key: coord, latitude: coords[coord][latitude], longitude: coords[coord][longitude], distance: d});
}

@@ -493,8 +612,8 @@

/**
* Finds the nearest coordinate to a reference coordinate
*
* @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return array ordered array
*/
* Finds the nearest coordinate to a reference coordinate
*
* @param object reference coordinate e.g. {latitude: 51.5023, longitude: 7.3815}
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return array ordered array
*/
findNearest: function(latlng, coords, offset) {

@@ -510,33 +629,165 @@

/**
* Calculates the length of a given path
*
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return integer length of the path (in meters)
*/
* Calculates the length of a given path
*
* @param mixed array or object with coords [{latitude: 51.5143, longitude: 7.4138}, {latitude: 123, longitude: 123}, ...]
* @return integer length of the path (in meters)
*/
getPathLength: function(coords) {
var l = 0, last;
for(var coord in coords) {
var dist = 0, last;
for (var i = 0, l = coords.length; i < l; ++i) {
if(last) {
l += geolib.getDistance(coords[coord], last);
dist += geolib.getDistance(coords[i], last);
}
last = coords[coord];
last = coords[i];
}
return l;
return dist;
},
/*global google:true require:true module:true elevationResult*/
/**
* Converts a distance from meters to km, mm, cm, mi, ft, in or yd
*
* @param string Format to be converted in
* @param float Distance
* @return float Converted distance
*/
* @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
*
* @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*/
getElevation: function() {
if (typeof window.navigator !== 'undefined') {
geolib.getElevationClient.apply(this, arguments);
} else {
geolib.getElevationServer.apply(this, arguments);
}
},
getElevationClient: function(coords, cb) {
if (!window.google) {
throw new Error("Google maps api not loaded");
}
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var path = [];
var keys = geolib.getKeys(coords[0]);
var latitude = keys.latitude;
var longitude = keys.longitude;
for(var i = 0; i < coords.length; i++) {
path.push(new google.maps.LatLng(
geolib.useDecimal(coords[i][latitude]),
geolib.useDecimal(coords[i][longitude])
));
}
var positionalRequest = {
'path': path,
'samples': path.length
};
var elevationService = new google.maps.ElevationService();
elevationService.getElevationAlongPath(positionalRequest,function (results, status){
geolib.elevationHandler(results, status, coords, keys, cb);
});
},
getElevationServer: function(coords, cb) {
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var gm = require('googlemaps');
var path = [];
var keys = geolib.getKeys(coords[0]);
//coords[0]
var latitude = keys.latitude;
var longitude = keys.longitude;
for(var i = 0; i < coords.length; i++) {
path.push(geolib.useDecimal(coords[i][latitude]) + ',' +
geolib.useDecimal(coords[i][longitude]));
}
gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
geolib.elevationHandler(results.results, results.status, coords, keys, cb);
});
},
elevationHandler: function(results, status, coords, keys, cb){
var latsLngsElevs = [];
var latitude = keys.latitude;
var longitude = keys.longitude;
if (status == "OK" ) {
for (var i = 0; i < results.length; i++) {
latsLngsElevs.push({
"lat":coords[i][latitude],
"lng":coords[i][longitude],
"elev":results[i].elevation
});
}
cb(null, latsLngsElevs);
} else {
cb(new Error("Could not get elevation using Google's API"), elevationResult.status);
}
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*
* @return Number % grade
*/
getGrade: function(coords){
var keys = geolib.getKeys(coords[0]);
var elevation = keys.elevation;
var rise = Math.abs(coords[coords.length-1][elevation] - coords[0][elevation]);
var run = geolib.getPathLength(coords);
return Math.floor((rise/run)*100);
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*
* @return Object {gain:#gain, loss:#loss}
*/
getTotalElevationGainAndLoss: function(coords){
var keys = geolib.getKeys(coords[0]);
var elevation = keys.elevation;
var gain = 0;
var loss = 0;
for(var i = 0; i < coords.length - 1; i++){
var deltaElev = coords[i][elevation] - coords[i + 1][elevation];
if (deltaElev > 0) {
loss += deltaElev;
} else {
gain += Math.abs(deltaElev);
}
}
return {
"gain": gain,
"loss": loss
};
},
/**
* Converts a distance from meters to km, mm, cm, mi, ft, in or yd
*
* @param string Format to be converted in
* @param float Distance in meters
* @param float Decimal places for rounding (default: 4)
* @return float Converted distance
*/
convertUnit: function(unit, distance, round) {
if(distance == 0 || typeof distance == 'undefined') {
if(distance === 0 || typeof distance == 'undefined') {
if(geolib.distance == 0) {
if(geolib.distance === 0) {
// throw 'No distance given.';

@@ -551,3 +802,3 @@ return 0;

unit = unit || 'm';
round = round || 4;
round = (null == round ? 4 : round);

@@ -558,27 +809,18 @@ switch(unit) {

return geolib.round(distance, round);
break;
case 'km': // Kilometer
return geolib.round(distance / 1000, round);
break;
case 'cm': // Centimeter
return geolib.round(distance * 100, round);
break;
case 'mm': // Millimeter
return geolib.round(distance * 1000, round);
break;
case 'mi': // Miles
return geolib.round(distance * (1 / 1609.344), round);
break;
case 'sm': // Seamiles
return geolib.round(distance * (1 / 1852.216), round);
break;
case 'ft': // Feet
return geolib.round(distance * (100 / 30.48), round);
break;
case 'in': // Inch
return geolib.round(distance * 100 / 2.54, round);
break;
case 'yd': // Yards
return geolib.round(distance * (1 / 0.9144), round);
break;
}

@@ -592,7 +834,7 @@

/**
* Checks if a value is in decimal format or, if neccessary, converts to decimal
*
* @param mixed Value to be checked/converted
* @return float Coordinate in decimal format
*/
* Checks if a value is in decimal format or, if neccessary, converts to decimal
*
* @param mixed Value to be checked/converted
* @return float Coordinate in decimal format
*/
useDecimal: function(value) {

@@ -607,3 +849,3 @@

// checks if it's sexagesimal format (HHH° MM' SS" (NESW))
} else if(geolib.isSexagesimal(value) == true) {
} else if(geolib.isSexagesimal(value) === true) {
return parseFloat(geolib.sexagesimal2decimal(value));

@@ -618,7 +860,7 @@ } else {

/**
* Converts a decimal coordinate value to sexagesimal format
*
* @param float decimal
* @return string Sexagesimal value (XX° YY' ZZ")
*/
* Converts a decimal coordinate value to sexagesimal format
*
* @param float decimal
* @return string Sexagesimal value (XX° YY' ZZ")
*/
decimal2sexagesimal: function(dec) {

@@ -632,7 +874,7 @@

var deg = tmp[0];
var deg = Math.abs(tmp[0]);
var min = ('0.' + tmp[1])*60;
var sec = min.toString().split('.');
min = parseInt(min, 10);
min = Math.floor(min);
sec = (('0.' + sec[1]) * 60).toFixed(2);

@@ -648,7 +890,7 @@

/**
* Converts a sexagesimal coordinate to decimal format
*
* @param float Sexagesimal coordinate
* @return string Decimal value (XX.XXXXXXXX)
*/
* Converts a sexagesimal coordinate to decimal format
*
* @param float Sexagesimal coordinate
* @return string Decimal value (XX.XXXXXXXX)
*/
sexagesimal2decimal: function(sexagesimal) {

@@ -662,6 +904,7 @@

var data = regEx.exec(sexagesimal);
var min = 0, sec = 0;
if(data) {
var min = parseFloat(data[2]/60);
var sec = parseFloat(data[4]/3600) || 0;
min = parseFloat(data[2]/60);
sec = parseFloat(data[4]/3600) || 0;
}

@@ -681,7 +924,7 @@

/**
* Checks if a value is in sexagesimal format
*
* @param string Value to be checked
* @return bool True if in sexagesimal format
*/
* Checks if a value is in sexagesimal format
*
* @param string Value to be checked
* @return bool True if in sexagesimal format
*/
isSexagesimal: function(value) {

@@ -698,3 +941,3 @@

}
};

@@ -704,3 +947,3 @@ if (typeof(Number.prototype.toRad) === "undefined") {

return this * Math.PI / 180;
}
};
}

@@ -711,3 +954,3 @@

return this * 180 / Math.PI;
}
};
}

@@ -724,2 +967,2 @@

})(this);
}(this));

@@ -5,17 +5,35 @@ {

"author": {
"name": "Manuel Bieh",
"url": "http://www.manuelbieh.com/"
"name": "Manuel Bieh",
"url": "http://www.manuelbieh.com/"
},
"bin": {
"geolib" : "./geolib.js"
"geolib": "./geolib.js"
},
"repository": {
"type" : "git",
"url" : "http://github.com/manuelbieh/geolib.git"
},
"files": ["geolib.js"],
"description": "Growing library to perform geo specific tasks",
"keywords": ["geolocation", "geo", "distance"],
"version": "1.1.7",
"type": "git",
"url": "http://github.com/manuelbieh/geolib.git"
},
"dependencies": {
"googlemaps": ">= 0.1.6"
},
"devDependencies": {
"mocha": "*"
},
"licenses": [
{
"type": "LGPL",
"url": "http://www.gnu.org/licenses/lgpl-3.0.txt"
}
],
"files": [
"geolib.js"
],
"description": "Library to perform geo specific tasks",
"keywords": [
"geolocation",
"geo",
"distance"
],
"version": "1.1.8",
"main": "./geolib"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc