Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mods to elevation and async service #11

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e477112
fixed bug with getBounds
regality Mar 15, 2012
fcca48d
Added ability to set business specific parameters. So you can enocde
grobot Apr 5, 2012
e668c43
made async methods pass error through callback
regality Apr 5, 2012
c17005c
Merge branch 'master' of github.com:ifit/Geolib
regality Apr 5, 2012
3328885
minified geolib.js
regality Apr 5, 2012
7c66e57
fixed bug with get compass direction
regality Apr 12, 2012
66d87ff
made grade so it can be negative
regality Apr 17, 2012
78b6a77
getGrade was returning the opposite of what we wanted. Changed
grobot Apr 18, 2012
8708d6a
Changed so we use the changes made in node-googlemaps.
grobot May 6, 2012
f9cb54b
set googlemaps version to >= 0.1.7
regality May 7, 2012
ee91749
fixed a herp derp in getGrade
regality May 7, 2012
9fcdf71
Merge branch 'master' of git://github.com/manuelbieh/Geolib
grobot Jul 17, 2012
5714d2b
change dependency
grobot Aug 20, 2012
a1ae728
herpderp
grobot Aug 20, 2012
d0d3bed
updating npm
cbrammer Oct 18, 2012
19f82d9
bundled
cbrammer Oct 19, 2012
5765720
Update package.json
Oct 19, 2012
71382ee
getting rid of modules for now
cbrammer Oct 19, 2012
629317b
getting rid of modules for now
cbrammer Oct 19, 2012
3a97861
Merge branch 'npmsucks'
cbrammer Oct 19, 2012
7e0a663
fixing git ignore
cbrammer Oct 21, 2012
488a9f0
logging out results from wonky google queries
grobot Nov 14, 2012
83a12d1
Merge branch 'master' of github.com:ifit/Geolib
grobot Nov 14, 2012
bd65be6
using haversine equation for getDistance
grobot Dec 17, 2013
33fca2b
updates test to reflect getDistance changes
grobot Dec 17, 2013
c9f40af
using toRad instead of custom deg2Rad
grobot Dec 17, 2013
b40ce49
adds in config options to set distance formula
grobot Dec 17, 2013
166037d
adds back in test I removed
grobot Dec 17, 2013
67e4b85
hur
grobot Dec 17, 2013
6a268f9
setting default to haversine
grobot Dec 17, 2013
a903a96
uses accuracy in the right way
grobot Dec 17, 2013
a735186
Merge pull request #1 from ifit/haversine
freddyC Dec 31, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,33 @@
lib-cov
*.seed
*.log
*.node
*.o
*.o.d
*.mk
*.gypi
*.cache.py
*.wafpickle-7
*.lock-wscript
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
.DS_Store
dump.rdb
.jshintrc

pids
logs
results

/public/js/app.js
/public/css/style.css
npm-debug.log
/client/config.js
.build
/docs

/node_modules
244 changes: 165 additions & 79 deletions geolib.js
100644 → 100755
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@


var radius = 6378137; // Earth radius var radius = 6378137; // Earth radius
var sexagesimalPattern = /^([0-9]{1,3})°\s*([0-9]{1,3})'\s*(([0-9]{1,3}(\.([0-9]{1,2}))?)"\s*)?([NEOSW]?)$/; var sexagesimalPattern = /^([0-9]{1,3})°\s*([0-9]{1,3})'\s*(([0-9]{1,3}(\.([0-9]{1,2}))?)"\s*)?([NEOSW]?)$/;
var googleClientId;
var googlePrivateKey;
if (typeof window.navigator === 'undefined') {
var gm = require('googlemaps');
}


var geolib = { var geolib = {
distanceFormula: 'haversine',


decimal: {}, decimal: {},


Expand Down Expand Up @@ -48,6 +54,37 @@
}; };
}, },


setDistanceFormula: function(formula) {
formula = formula ? formula.toLowerCase() : 'vincenty';
geolib.distanceFormula = formula;
},

/**
* Calculates geodetic distance between two points specified by latitude/longitude using
* haversine by default, but can be changed in config
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @param integer Accuracy (in meters)
* @return float Distance (in meters)
*/

getDistance: function(start, end, accuracy) {
switch (geolib.distanceFormula) {
case 'haversine':
return geolib.getDistanceHaversine(start, end, accuracy);
break;
case 'simple':
return geolib.getDistanceSimple(start, end, accuracy);
break;
case 'vincenty':
default:
return geolib.getDistanceVincenty(start, end, accuracy);
break;
}
},


/** /**
* Calculates geodetic distance between two points specified by latitude/longitude using * Calculates geodetic distance between two points specified by latitude/longitude using
* Vincenty inverse formula for ellipsoids * Vincenty inverse formula for ellipsoids
Expand All @@ -60,7 +97,7 @@
* @return integer Distance (in meters) * @return integer Distance (in meters)
*/ */


getDistance: function(start, end, accuracy) { getDistanceVincenty: function(start, end, accuracy) {


var keys = geolib.getKeys(start); var keys = geolib.getKeys(start);
var latitude = keys.latitude; var latitude = keys.latitude;
Expand Down Expand Up @@ -204,6 +241,41 @@


}, },


/**
* Calculates geodetic distance between two points specified by latitude/longitude using
* haversine equation
*
* @param object Start position {latitude: 123, longitude: 123}
* @param object End position {latitude: 123, longitude: 123}
* @return float Distance (in meters)
*/

getDistanceHaversine: function(start, end, accuracy) {
var keys = geolib.getKeys(start);
var latitude = keys.latitude;
var longitude = keys.longitude;
var elevation = keys.elevation;

var coord1 = {}, coord2 = {};
coord1[latitude] = geolib.useDecimal(start[latitude]);
coord1[longitude] = geolib.useDecimal(start[longitude]);

coord2[latitude] = geolib.useDecimal(end[latitude]);
coord2[longitude] = geolib.useDecimal(end[longitude]);

accuracy = accuracy || 0.00000001;

var R = 6378137 // Radius of earth in meters
var dLat = (coord2[latitude] - coord1[latitude]).toRad()
var dLng = (coord2[longitude] - coord1[longitude]).toRad()
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos((coord1[latitude]).toRad()) * Math.cos((coord2[latitude].toRad())) *
Math.sin(dLng/2) * Math.sin(dLng/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in meters
return geolib.distance = Math.round(d/accuracy)*accuracy;
},



/** /**
* Calculates the distance between two spots. * Calculates the distance between two spots.
Expand Down Expand Up @@ -323,14 +395,14 @@


var useElevation = coords[0].hasOwnProperty(elevation); var useElevation = coords[0].hasOwnProperty(elevation);
var stats = { var stats = {
maxLat: 0, maxLat: Infinity * -1,
minLat: Infinity, minLat: Infinity,
maxLng: 0, maxLng: Infinity * -1,
minLng: Infinity minLng: Infinity,
}; };


if (useElevation) { if (useElevation) {
stats.maxElev = 0; stats.maxElev = Infinity * -1;
stats.minElev = Infinity; stats.minElev = Infinity;
} }


Expand Down Expand Up @@ -627,10 +699,20 @@


/*global google:true require:true module:true elevationResult*/ /*global google:true require:true module:true elevationResult*/
/** /**
* @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...] * @params client_id and private_key for Google Enterprise Accounts
* *
* @return Array [{lat:#lat, lng:#lng, elev:#elev},....]} * @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*/ */
setBusinessSpecificParameters: function(clientId, privateKey){
gm.config('google-client-id', clientId);
gm.config('google-private-key', privateKey);
},

/**
* @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() { getElevation: function() {
if (typeof window.navigator !== 'undefined') { if (typeof window.navigator !== 'undefined') {
geolib.getElevationClient.apply(this, arguments); geolib.getElevationClient.apply(this, arguments);
Expand All @@ -640,65 +722,63 @@
}, },


getElevationClient: function(coords, cb) { getElevationClient: function(coords, cb) {

try {
if (!window.google) { if (!window.google) {
throw new Error("Google maps api not loaded"); return cb(new Error("Geolib: Google maps api not loaded"));
} }

if (coords.length == 0) {
if (coords.length === 0) { return cb(null, null);
return cb(null, null); }
} if (coords.length == 1) {

return cb(new Error("Geolib: getElevation requires at least 2 points."));
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 path = []; var longitude = keys.longitude;
var keys = geolib.getKeys(coords[0]);
var latitude = keys.latitude; for(var i = 0; i < coords.length; i++) {
var longitude = keys.longitude; path.push(new google.maps.LatLng(

geolib.useDecimal(coords[i][latitude]),
for(var i = 0; i < coords.length; i++) { geolib.useDecimal(coords[i][longitude])
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);
});
} catch (e) {
return cb(e);
} }

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) { getElevationServer: function(coords, cb) {

try {
if (coords.length === 0) { if (coords.length == 0) {
return cb(null, null); return cb(null, null);
} }

if (coords.length == 1) {
if (coords.length === 1) { return cb(new Error("Geolib: getElevation requires at least 2 points."));
return cb(new Error("getElevation requires at least 2 points.")); }
} var path = [];

var keys = geolib.getKeys(coords[0]);
var gm = require('googlemaps'); coords[0]
var path = []; var latitude = keys.latitude;
var keys = geolib.getKeys(coords[0]); var longitude = keys.longitude;
//coords[0] for (var i = 0; i < coords.length; i++) {
var latitude = keys.latitude; path.push(geolib.useDecimal(coords[i][latitude]) + ',' +
var longitude = keys.longitude; geolib.useDecimal(coords[i][longitude]));
for(var i = 0; i < coords.length; i++) { }
path.push(geolib.useDecimal(coords[i][latitude]) + ',' + gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
geolib.useDecimal(coords[i][longitude])); geolib.elevationHandler(results.results, results.status, coords, keys, cb)
});
} catch (e) {
return cb(e);
} }
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){ elevationHandler: function(results, status, coords, keys, cb){
Expand All @@ -715,29 +795,36 @@
} }
cb(null, latsLngsElevs); cb(null, latsLngsElevs);
} else { } else {
cb(new Error("Could not get elevation using Google's API"), elevationResult.status); console.log('RESULTS FROM WONKY GOOGLE REQUEST' + results);
cb(new Error("Geolib: Could not get elevation using Google's API: Status: " + status));
} }
}, },


/** /**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]} * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* * @param integer digits Decimal places to round to
* @return Number % grade *
*/ * @return Number % grade
getGrade: function(coords){ */
getGrade: function(coords, digits) {
var keys = geolib.getKeys(coords[0]); var keys = geolib.getKeys(coords[0]);
var elevation = keys.elevation; var elevation = keys.elevation;
var rise = Math.abs(coords[coords.length-1][elevation] - coords[0][elevation]); var rise = coords[coords.length-1][elevation] - coords[0][elevation];
var run = geolib.getPathLength(coords); var run = geolib.getPathLength(coords);
return Math.floor((rise/run)*100); var grade = (rise/run)*100;
if (typeof digits === "number") {
var d = Math.pow(10,digits);
grade = Math.floor(grade * d) / d;
}
return grade;
}, },


/** /**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]} * @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* *
* @return Object {gain:#gain, loss:#loss} * @return Object {gain:#gain, loss:#loss}
*/ */
getTotalElevationGainAndLoss: function(coords){ getTotalElevationGainAndLoss: function(coords) {
var keys = geolib.getKeys(coords[0]); var keys = geolib.getKeys(coords[0]);
var elevation = keys.elevation; var elevation = keys.elevation;
var gain = 0; var gain = 0;
Expand Down Expand Up @@ -768,8 +855,7 @@


if(distance === 0 || typeof distance == 'undefined') { if(distance === 0 || typeof distance == 'undefined') {


if(geolib.distance === 0) { if(geolib.distance == 0) {
// throw 'No distance given.';
return 0; return 0;
} else { } else {
distance = geolib.distance; distance = geolib.distance;
Expand Down Expand Up @@ -825,7 +911,7 @@
} else if(geolib.isSexagesimal(value) === true) { } else if(geolib.isSexagesimal(value) === true) {
return parseFloat(geolib.sexagesimal2decimal(value)); return parseFloat(geolib.sexagesimal2decimal(value));
} else { } else {
throw 'Unknown format.'; throw new Error('Geolib: Unknown format.');
} }


}, },
Expand Down
Loading