ffffng/app/bower_components/geolib/src/geolib.elevation.js

190 lines
No EOL
3.8 KiB
JavaScript

/*! geolib.elevation $version$ by Manuel Bieh
*
* Elevation Addon for Geolib.js
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version $version$
* @license MIT
*/
;(function(global, geolib, undefined) {
var elevation = {
/*global google:true geolib:true require:true module:true elevationResult:true */
/**
* @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 global.navigator !== 'undefined') {
this.getElevationClient.apply(this, arguments);
} else {
this.getElevationServer.apply(this, arguments);
}
},
/* Optional elevation addon requires Googlemaps API JS */
getElevationClient: function(coords, cb) {
if (!global.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 = [];
for(var i = 0; i < coords.length; i++) {
path.push(new google.maps.LatLng(
this.latitude(coords[i]),
this.longitude(coords[i])
));
}
var positionalRequest = {
'path': path,
'samples': path.length
};
var elevationService = new google.maps.ElevationService();
var geolib = this;
elevationService.getElevationAlongPath(positionalRequest, function (results, status) {
geolib.elevationHandler(results, status, coords, 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 = [];
for(var i = 0; i < coords.length; i++) {
path.push(
this.latitude(coords[i]) + ',' + this.longitude(coords[i])
);
}
var geolib = this;
gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
geolib.elevationHandler(results.results, results.status, coords, cb);
});
},
elevationHandler: function(results, status, coords, cb) {
var latsLngsElevs = [];
if (status == "OK" ) {
for (var i = 0; i < results.length; i++) {
latsLngsElevs.push({
"lat": this.latitude(coords[i]),
"lng": this.longitude(coords[i]),
"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 rise = Math.abs(
this.elevation(coords[coords.length-1]) - this.elevation(coords[0])
);
var run = this.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 gain = 0;
var loss = 0;
for(var i = 0; i < coords.length - 1; i++) {
var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);
if (deltaElev > 0) {
loss += deltaElev;
} else {
gain += Math.abs(deltaElev);
}
}
return {
"gain": gain,
"loss": loss
};
}
};
// Node module
if (typeof module !== 'undefined' &&
typeof module.exports !== 'undefined') {
geolib = require('geolib');
geolib.extend(elevation);
// AMD module
} else if (typeof define === "function" && define.amd) {
define(["geolib"], function (geolib) {
geolib.extend(elevation);
return geolib;
});
// we're in a browser
} else {
geolib.extend(elevation);
}
}(this, this.geolib));