135 lines
3.5 KiB
JavaScript
135 lines
3.5 KiB
JavaScript
/* Optional elevation addon requires Googlemaps API JS */
|
|
|
|
/*global google:true geolib:true require:true module:true elevationResult*/
|
|
/**
|
|
* @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},....]}
|
|
*/
|
|
geolib.getElevation = function() {
|
|
if (typeof window.navigator !== 'undefined') {
|
|
geolib.getElevationClient.apply(this, arguments);
|
|
} else {
|
|
geolib.getElevationServer.apply(this, arguments);
|
|
}
|
|
};
|
|
|
|
geolib.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);
|
|
});
|
|
|
|
};
|
|
|
|
geolib.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);
|
|
});
|
|
|
|
},
|
|
|
|
geolib.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
|
|
*/
|
|
geolib.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}
|
|
*/
|
|
geolib.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
|
|
};
|
|
};
|