mgrs
Version:
Utility for converting between WGS84 lat/lng and MGRS coordinates
3 lines (2 loc) • 5.92 kB
JavaScript
const t=65,e=73,r=79;function n(n,o){if(o="number"==typeof o?o:5,!Array.isArray(n))throw new TypeError("forward did not receive an array");if("string"==typeof n[0]||"string"==typeof n[1])throw new TypeError("forward received an array of strings, but it only accepts an array of numbers.");const[a,s]=n;if(a<-180||a>180)throw new TypeError("forward received an invalid longitude of "+a);if(s<-90||s>90)throw new TypeError("forward received an invalid latitude of "+s);if(s<-80||s>84)throw new TypeError(`forward received a latitude of ${s}, but this library does not support conversions of points in polar regions below 80°S and above 84°N`);return function(n,o){const a="00000"+n.easting,i="00000"+n.northing;return n.zoneNumber+n.zoneLetter+function(n,o,a){const i=f(a),s=Math.floor(n/1e5),c=Math.floor(o/1e5)%20;return function(n,o,a){const i=a-1,s="AJSAJS".charCodeAt(i),c="AFAFAF".charCodeAt(i);let h=s+n-1,f=c+o,l=!1;h>90&&(h=h-90+t-1,l=!0);(h===e||s<e&&h>e||(h>e||s<e)&&l)&&h++;(h===r||s<r&&h>r||(h>r||s<r)&&l)&&(h++,h===e&&h++);h>90&&(h=h-90+t-1);f>86?(f=f-86+t-1,l=!0):l=!1;(f===e||c<e&&f>e||(f>e||c<e)&&l)&&f++;(f===r||c<r&&f>r||(f>r||c<r)&&l)&&(f++,f===e&&f++);f>86&&(f=f-86+t-1);return String.fromCharCode(h)+String.fromCharCode(f)}(s,c,i)}(n.easting,n.northing,n.zoneNumber)+a.substr(a.length-5,o)+i.substr(i.length-5,o)}(function(t){const e=t.lat,r=t.lon,n=6378137,o=i(e),a=i(r);let s;s=Math.floor((r+180)/6)+1,180===r&&(s=60);e>=56&&e<64&&r>=3&&r<12&&(s=32);e>=72&&e<84&&(r>=0&&r<9?s=31:r>=9&&r<21?s=33:r>=21&&r<33?s=35:r>=33&&r<42&&(s=37));const c=i(6*(s-1)-180+3),f=n/Math.sqrt(1-.00669438*Math.sin(o)*Math.sin(o)),l=Math.tan(o)*Math.tan(o),u=.006739496752268451*Math.cos(o)*Math.cos(o),b=Math.cos(o)*(a-c),M=n*(.9983242984503243*o-.002514607064228144*Math.sin(2*o)+2639046602129982e-21*Math.sin(4*o)-3.418046101696858e-9*Math.sin(6*o)),d=.9996*f*(b+(1-l+u)*b*b*b/6+(5-18*l+l*l+72*u-.39089081163157013)*b*b*b*b*b/120)+5e5;let g=.9996*(M+f*Math.tan(o)*(b*b/2+(5-l+9*u+4*u*u)*b*b*b*b/24+(61-58*l+l*l+600*u-2.2240339282485886)*b*b*b*b*b*b/720));e<0&&(g+=1e7);return{northing:Math.trunc(g),easting:Math.trunc(d),zoneNumber:s,zoneLetter:h(e)}}({lat:s,lon:a}),o)}function o(t){const e=c(l(t.toUpperCase()));return"number"==typeof e.lat&&"number"==typeof e.lon?[e.lon,e.lat,e.lon,e.lat]:[e.left,e.bottom,e.right,e.top]}function a(t){if(""===t)throw new TypeError("toPoint received a blank string");const e=c(l(t.toUpperCase()));return"number"==typeof e.lat&&"number"==typeof e.lon?[e.lon,e.lat]:[(e.left+e.right)/2,(e.top+e.bottom)/2]}function i(t){return t*(Math.PI/180)}function s(t){return t/Math.PI*180}function c(t){const e=t.northing,r=t.easting,{zoneLetter:n,zoneNumber:o}=t;if(o<0||o>60)return null;const a=6378137,i=(1-Math.sqrt(.99330562))/(1+Math.sqrt(.99330562)),h=r-5e5;let f=e;n<"N"&&(f-=1e7);const l=6*(o-1)-180+3,u=f/.9996/6367449.145945056,b=u+(3*i/2-27*i*i*i/32)*Math.sin(2*u)+(21*i*i/16-55*i*i*i*i/32)*Math.sin(4*u)+151*i*i*i/96*Math.sin(6*u),M=a/Math.sqrt(1-.00669438*Math.sin(b)*Math.sin(b)),d=Math.tan(b)*Math.tan(b),g=.006739496752268451*Math.cos(b)*Math.cos(b),w=.99330562*a/Math.pow(1-.00669438*Math.sin(b)*Math.sin(b),1.5),p=h/(.9996*M);let y=b-M*Math.tan(b)/w*(p*p/2-(5+3*d+10*g-4*g*g-.06065547077041606)*p*p*p*p/24+(61+90*d+298*g+45*d*d-1.6983531815716497-3*g*g)*p*p*p*p*p*p/720);y=s(y);let m,A=(p-(1+2*d+g)*p*p*p/6+(5-2*g+28*d-3*g*g+.05391597401814761+24*d*d)*p*p*p*p*p/120)/Math.cos(b);if(A=l+s(A),"number"==typeof t.accuracy){const e=c({northing:t.northing+t.accuracy,easting:t.easting+t.accuracy,zoneLetter:t.zoneLetter,zoneNumber:t.zoneNumber});m={top:e.lat,right:e.lon,bottom:y,left:A}}else m={lat:y,lon:A};return m}function h(t){if(t<=84&&t>=72)return"X";if(t<72&&t>=-80){const e=8,r=-80;return"CDEFGHJKLMNPQRSTUVWX"[Math.floor((t-r)/e)]}return t>84||t<-80?"Z":void 0}function f(t){let e=t%6;return 0===e&&(e=6),e}function l(n){if(n&&0===n.length)throw new TypeError("MGRSPoint coverting from nothing");n=n.replace(/ /g,"");const{length:o}=n;let a,i=null,s="",c=0;for(;!/[A-Z]/.test(a=n.charAt(c));){if(c>=2)throw new Error("MGRSPoint bad conversion from: "+n);s+=a,c++}const h=parseInt(s,10);if(0===c||c+3>o)throw new Error("MGRSPoint bad conversion from "+n);const l=n.charAt(c++);if(l<="A"||"B"===l||"Y"===l||l>="Z"||"I"===l||"O"===l)throw new Error(`MGRSPoint zone letter ${l} not handled: ${n}`);i=n.substring(c,c+=2);const b=f(h),M=function(n,o){let a="AJSAJS".charCodeAt(o-1),i=1e5,s=!1;for(;a!==n.charCodeAt(0);){if(a++,a===e&&a++,a===r&&a++,a>90){if(s)throw new Error("Bad character: "+n);a=t,s=!0}i+=1e5}return i}(i.charAt(0),b);let d=function(n,o){if(n>"V")throw new TypeError("MGRSPoint given invalid Northing "+n);let a="AFAFAF".charCodeAt(o-1),i=0,s=!1;for(;a!==n.charCodeAt(0);){if(a++,a===e&&a++,a===r&&a++,a>86){if(s)throw new Error("Bad character: "+n);a=t,s=!0}i+=1e5}return i}(i.charAt(1),b);for(;d<u(l);)d+=2e6;const g=o-c;if(g%2!=0)throw new Error("MGRSPoint has to have an even number\nof digits after the zone letter and two 100km letters - front\nhalf for easting meters, second half for\nnorthing meters "+n);const w=g/2;let p,y,m,A=0,k=0;w>0&&(p=1e5/Math.pow(10,w),y=n.substring(c,c+w),A=parseFloat(y)*p,m=n.substring(c+w),k=parseFloat(m)*p);return{easting:A+M,northing:k+d,zoneLetter:l,zoneNumber:h,accuracy:p}}function u(t){let e;switch(t){case"C":e=11e5;break;case"D":e=2e6;break;case"E":e=28e5;break;case"F":e=37e5;break;case"G":e=46e5;break;case"H":e=55e5;break;case"J":e=64e5;break;case"K":e=73e5;break;case"L":e=82e5;break;case"M":e=91e5;break;case"N":e=0;break;case"P":e=8e5;break;case"Q":e=17e5;break;case"R":e=26e5;break;case"S":e=35e5;break;case"T":e=44e5;break;case"U":e=53e5;break;case"V":e=62e5;break;case"W":e=7e6;break;case"X":e=79e5;break;default:e=-1}if(e>=0)return e;throw new TypeError("Invalid zone letter: "+t)}export{n as forward,h as getLetterDesignator,o as inverse,a as toPoint};
//# sourceMappingURL=mgrs.esm.js.map