forked from martindale/Geolib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeolib.min.js
11 lines (11 loc) · 8.7 KB
/
geolib.min.js
1
2
3
4
5
6
7
8
9
10
11
/**
* 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
*
*/(function(a,b){var c=6378137,d=/^([0-9]{1,3})°\s*([0-9]{1,3})'\s*(([0-9]{1,3}(\.([0-9]{1,2}))?)"\s*)?([NEOSW]?)$/,e={decimal:{},sexagesimal:{},distance:0,getKeys:function(a){var b=a.hasOwnProperty("lat")?"lat":"latitude",c=(a.hasOwnProperty("lng")?"lng":!1)||(a.hasOwnProperty("long")?"long":!1)||"longitude",d=(a.hasOwnProperty("alt")?"alt":!1)||(a.hasOwnProperty("altitude")?"altitude":!1)||(a.hasOwnProperty("elev")?"elev":!1)||"elevation";return{latitude:b,longitude:c,elevation:d}},getDistance:function(a,b,c){var d=e.getKeys(a),f=d.latitude,g=d.longitude,h=d.elevation;c=Math.floor(c)||1;var i={},j={};i[f]=e.useDecimal(a[f]),i[g]=e.useDecimal(a[g]),j[f]=e.useDecimal(b[f]),j[g]=e.useDecimal(b[g]);var k=6378137,l=6356752.314245,m=1/298.257223563,n=(j[g]-i[g]).toRad(),o=Math.atan((1-m)*Math.tan(parseFloat(i[f]).toRad())),p=Math.atan((1-m)*Math.tan(parseFloat(j[f]).toRad())),q=Math.sin(o),r=Math.cos(o),s=Math.sin(p),t=Math.cos(p),u=n,v,w=100;do{var x=Math.sin(u),y=Math.cos(u),z=Math.sqrt(t*x*t*x+(r*s-q*t*y)*(r*s-q*t*y));if(z==0)return e.distance=0;var A=q*s+r*t*y,B=Math.atan2(z,A),C=r*t*x/z,D=1-C*C,E=A-2*q*s/D;isNaN(E)&&(E=0);var F=m/16*D*(4+m*(4-3*D));v=u,u=n+(1-F)*m*C*(B+F*z*(E+F*A*(-1+2*E*E)))}while(Math.abs(u-v)>1e-12&&--w>0);if(w==0)return NaN;var G=D*(k*k-l*l)/(l*l),H=1+G/16384*(4096+G*(-768+G*(320-175*G))),I=G/1024*(256+G*(-128+G*(74-47*G))),J=I*z*(E+I/4*(A*(-1+2*E*E)-I/6*E*(-3+4*z*z)*(-3+4*E*E))),K=l*H*(B-J);K=K.toFixed(3);if(a.hasOwnProperty(h)&&b.hasOwnProperty(h)){var L=Math.abs(a[h]-b[h]);K=Math.sqrt(K*K+L*L)}return e.distance=Math.floor(Math.round(K/c)*c)},getDistanceSimple:function(a,b,d){var f=e.getKeys(a),g=f.latitude,h=f.longitude;d=Math.floor(d)||1;var i={},j={};i[g]=parseFloat(e.useDecimal(a[g])).toRad(),i[h]=parseFloat(e.useDecimal(a[h])).toRad(),j[g]=parseFloat(e.useDecimal(b[g])).toRad(),j[h]=parseFloat(e.useDecimal(b[h])).toRad();var k=Math.round(Math.acos(Math.sin(j[g])*Math.sin(i[g])+Math.cos(j[g])*Math.cos(i[g])*Math.cos(i[h]-j[h]))*c);return e.distance=Math.floor(Math.round(k/d)*d)},getCenter:function(a){if(!a.length)return!1;var b=e.getKeys(a[0]),c=b.latitude,d=b.longitude,f=function(a){return Math.max.apply(Math,a)},g=function(a){return Math.min.apply(Math,a)},h,i,j={lat:[],lng:[]};for(var k in a)j.lat.push(e.useDecimal(a[k][c])),j.lng.push(e.useDecimal(a[k][d]));var l=g(j.lat),m=g(j.lng),n=f(j.lat),o=f(j.lng);h=((l+n)/2).toFixed(6),i=((m+o)/2).toFixed(6);var p=e.convertUnit("km",e.getDistance({lat:l,lng:m},{lat:n,lng:o}));return{latitude:h,longitude:i,distance:p}},getBounds:function(a){if(!a.length)return!1;var b=e.getKeys(a[0]),c=b.latitude,d=b.longitude,f=b.elevation,g=a[0].hasOwnProperty(f),h={maxLat:0,minLat:Infinity,maxLng:0,minLng:Infinity};g&&(h.maxElev=0,h.minElev=Infinity);for(var i=0,j=a.length;i<j;++i)h.maxLat=Math.max(a[i][c],h.maxLat),h.minLat=Math.min(a[i][c],h.minLat),h.maxLng=Math.max(a[i][d],h.maxLng),h.minLng=Math.min(a[i][d],h.minLng),g&&(h.maxElev=Math.max(a[i][f],h.maxElev),h.minElev=Math.min(a[i][f],h.minElev));return h},isPointInside:function(a,b){var c=e.getKeys(a),d=c.latitude,f=c.longitude;for(var g=!1,h=-1,i=b.length,j=i-1;++h<i;j=h)(b[h][f]<=a[f]&&a[f]<b[j][f]||b[j][f]<=a[f]&&a[f]<b[h][f])&&a[d]<(b[j][d]-b[h][d])*(a[f]-b[h][f])/(b[j][f]-b[h][f])+b[h][d]&&(g=!g);return g},isPointInCircle:function(a,b,c){return e.getDistance(a,b)<c},getRhumbLineBearing:function(a,b){var c=e.getKeys(a),d=c.latitude,f=c.longitude,g=e.useDecimal(b[f]).toRad()-e.useDecimal(a[f]).toRad(),h=Math.log(Math.tan(e.useDecimal(b[d]).toRad()/2+Math.PI/4)/Math.tan(e.useDecimal(a[d]).toRad()/2+Math.PI/4));return Math.abs(g)>Math.PI&&(g>0?g=(2*Math.PI-g)*-1:g=2*Math.PI+g),(Math.atan2(g,h).toDeg()+360)%360},getBearing:function(a,b){var c=e.getKeys(a),d=c.latitude,f=c.longitude;b[d]=e.useDecimal(b[d]),b[f]=e.useDecimal(b[f]),a[d]=e.useDecimal(a[d]),a[f]=e.useDecimal(a[f]);var g=(Math.atan2(Math.sin(b[f].toRad()-a[f].toRad())*Math.cos(b[d].toRad()),Math.cos(a[d].toRad())*Math.sin(b[d].toRad())-Math.sin(a[d].toRad())*Math.cos(b[d].toRad())*Math.cos(b[f].toRad()-a[f].toRad())).toDeg()+360)%360;return g},getCompassDirection:function(a,b,c){var d;if(c=="circle")var f=e.getBearing(a,b);else var f=e.getRhumbLineBearing(a,b);switch(Math.round(f/22.5)){case 1:d={exact:"NNE",rough:"N"};break;case 2:d={exact:"NE",rough:"N"};break;case 3:d={exact:"ENE",rough:"E"};break;case 4:d={exact:"E",rough:"E"};break;case 5:d={exact:"ESE",rough:"E"};break;case 6:d={exact:"SE",rough:"E"};break;case 7:d={exact:"SSE",rough:"S"};break;case 8:d={exact:"S",rough:"S"};break;case 9:d={exact:"SSW",rough:"S"};break;case 10:d={exact:"SW",rough:"S"};break;case 11:d={exact:"WSW",rough:"W"};break;case 12:d={exact:"W",rough:"W"};break;case 13:d={exact:"WNW",rough:"W"};break;case 14:d={exact:"NW",rough:"W"};break;case 15:d={exact:"NNW",rough:"N"};break;default:d={exact:"N",rough:"N"}}return d},orderByDistance:function(a,b){var c=e.getKeys(a),d=c.latitude,f=c.longitude,g=[];for(var h in b){var i=e.getDistance(a,b[h]);g.push({key:h,latitude:b[h][d],longitude:b[h][f],distance:i})}return g.sort(function(a,b){return a.distance-b.distance})},findNearest:function(a,b,c){c=c||0;var d=e.orderByDistance(a,b);return d[c]},getPathLength:function(a){var b=0,c;for(var d=0,f=a.length;d<f;++d)c&&(b+=e.getDistance(a[d],c)),c=a[d];return b},getElevation:function(){typeof a.navigator!="undefined"?e.getElevationClient.apply(this,arguments):e.getElevationServer.apply(this,arguments)},getElevationClient:function(b,c){if(!a.google)throw new Error("Google maps api not loaded");if(b.length==0)return c(null,null);if(b.length==1)return c(new Error("getElevation requires at least 2 points."));var d=[],f=e.getKeys(b[0]),g=f.latitude,h=f.longitude;for(var i=0;i<b.length;i++)d.push(new google.maps.LatLng(e.useDecimal(b[i][g]),e.useDecimal(b[i][h])));var j={path:d,samples:d.length},k=new google.maps.ElevationService;k.getElevationAlongPath(j,function(a,d){e.elevationHandler(a,d,b,f,c)})},getElevationServer:function(a,b){if(a.length==0)return b(null,null);if(a.length==1)return b(new Error("getElevation requires at least 2 points."));var c=require("googlemaps"),d=[],f=e.getKeys(a[0]);a[0];var g=f.latitude,h=f.longitude;for(var i=0;i<a.length;i++)d.push(e.useDecimal(a[i][g])+","+e.useDecimal(a[i][h]));c.elevationFromPath(d.join("|"),d.length,function(c,d){e.elevationHandler(d.results,d.status,a,f,b)})},elevationHandler:function(a,b,c,d,e){var f=[],g=d.latitude,h=d.longitude;if(b=="OK"){for(var i=0;i<a.length;i++)f.push({lat:c[i][g],lng:c[i][h],elev:a[i].elevation});e(null,f)}else e(new Error("Could not get elevation using Google's API"),elevationResult.status)},getGrade:function(a){var b=e.getKeys(a[0]),c=b.elevation,d=Math.abs(a[a.length-1][c]-a[0][c]),f=e.getPathLength(a);return Math.floor(d/f*100)},getTotalElevationGainAndLoss:function(a){var b=e.getKeys(a[0]),c=b.elevation,d=0,f=0;for(var g=0;g<a.length-1;g++){var h=a[g][c]-a[g+1][c];h>0?f+=h:d+=Math.abs(h)}return{gain:d,loss:f}},convertUnit:function(a,b,c){if(b==0||typeof b=="undefined"){if(e.distance==0)return 0;b=e.distance}a=a||"m",c=c||4;switch(a){case"m":return e.round(b,c);case"km":return e.round(b/1e3,c);case"cm":return e.round(b*100,c);case"mm":return e.round(b*1e3,c);case"mi":return e.round(b*(1/1609.344),c);case"sm":return e.round(b*(1/1852.216),c);case"ft":return e.round(b*(100/30.48),c);case"in":return e.round(b*100/2.54,c);case"yd":return e.round(b*(1/.9144),c)}return b},useDecimal:function(a){a=a.toString().replace(/\s*/,"");if(!isNaN(parseFloat(a))&&parseFloat(a).toString()==a)return parseFloat(a);if(e.isSexagesimal(a)==1)return parseFloat(e.sexagesimal2decimal(a));throw"Unknown format."},decimal2sexagesimal:function(a){if(a in e.sexagesimal)return e.sexagesimal[a];var b=a.toString().split("."),c=Math.abs(b[0]),d=("0."+b[1])*60,f=d.toString().split(".");return d=Math.floor(d),f=(("0."+f[1])*60).toFixed(2),e.sexagesimal[a]=c+"° "+d+"' "+f+'"',e.sexagesimal[a]},sexagesimal2decimal:function(a){if(a in e.decimal)return e.decimal[a];var b=new RegExp(d),c=b.exec(a);if(c)var f=parseFloat(c[2]/60),g=parseFloat(c[4]/3600)||0;var h=(parseFloat(c[1])+f+g).toFixed(8);return h=c[7]=="S"||c[7]=="W"?h*-1:h,e.decimal[a]=h,h},isSexagesimal:function(a){return d.test(a)},round:function(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c}};typeof Number.prototype.toRad=="undefined"&&(Number.prototype.toRad=function(){return this*Math.PI/180}),typeof Number.prototype.toDeg=="undefined"&&(Number.prototype.toDeg=function(){return this*180/Math.PI}),typeof a.navigator!="undefined"?a.geolib=e:module.exports=e})(this);