@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 7.23 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import e from"../../core/Error.js";import{convertUnit as t}from"../../core/unitUtils.js";import{ensureClass as n}from"../../core/accessorSupport/ensureType.js";import s from"../Point.js";import i from"../Polygon.js";import r from"../Polyline.js";import a from"../SpatialReference.js";import{toRadians as o,spheroids as c,wktSpheroidRegex as h}from"./geodesicConstants.js";import{isGeographic as l,isWebMercator as p,equals as f}from"./spatialReferenceUtils.js";function u(e){if(!e)return null;const t=e.wkid;if(t)return c[t];const n=e.wkt2??e.wkt;return n?m(n):null}function m(e){const t=h.exec(e);if(!t||2!==t.length)return null;const n=t[1].split(",");if(!n||n.length<3)return null;const s=parseFloat(n[1]),i=parseFloat(n[2]);if(isNaN(s)||isNaN(i))return null;return{a:s,f:0===i?0:1/i}}function d(e){const t=u(e);if(g(t))return t;const n=t.a*(1-t.f);return Object.assign(t,{b:n,eSq:1-(n/t.a)**2,radius:(2*t.a+n)/3,densificationRatio:1e4/((2*t.a+n)/3)})}function g(e){return null!=e&&"b"in e&&"eSq"in e&&"radius"in e}function M(e){return null!=e&&e<0?e+360:e}function w(e,t,n){const{a:s,eSq:i}=d(n),r=Math.sqrt(i),a=Math.sin(t[1]*o),c=s*t[0]*o;let h;if(i>0){h=s*((1-i)*(a/(1-i*(a*a))-1/(2*r)*Math.log((1-r*a)/(1+r*a))))*.5}else h=s*a;return e[0]=c,e[1]=h,e}function y(e){return l(e)&&!!u(e)}function v(n,s="square-meters"){if(n.some((e=>!y(e.spatialReference))))throw new e("geodesic-areas:invalid-spatial-reference","the input geometries spatial reference is not supported");const i=[];for(let e=0;e<n.length;e++){const t=n[e],s=t.spatialReference,{radius:r,densificationRatio:a}=d(s),o=r*a;i.push(z(t,o))}const r=[],a=[0,0],o=[0,0];for(let e=0;e<i.length;e++){const{rings:n,spatialReference:c}=i[e];let h=0;for(let e=0;e<n.length;e++){const t=n[e];w(a,t[0],c),w(o,t[t.length-1],c);let s=o[0]*a[1]-a[0]*o[1];for(let e=0;e<t.length-1;e++)w(a,t[e+1],c),w(o,t[e],c),s+=o[0]*a[1]-a[0]*o[1];h+=s}h=t(h,"square-meters",s),r.push(h/-2)}return r}function R(n,s="meters"){if(!n)throw new e("geodesic-lengths:invalid-geometries","the input geometries type is not supported");if(n.some((e=>!y(e.spatialReference))))throw new e("geodesic-lengths:invalid-spatial-reference","the input geometries spatial reference is not supported");const i=[];for(let e=0;e<n.length;e++){const r=n[e],{spatialReference:a}=r,o="polyline"===r.type?r.paths:r.rings;let c=0;for(let e=0;e<o.length;e++){const t=o[e];let n=0;for(let e=1;e<t.length;e++){const s=t[e-1][0],i=t[e][0],r=t[e-1][1],o=t[e][1];if(r!==o||s!==i){const e=new b;q(e,[s,r],[i,o],a),n+=e.distance}}c+=n}c=t(c,"meters",s),i.push(c)}return i}function z(t,s){if("polyline"!==t.type&&"polygon"!==t.type)throw new e("geodesic-densify:invalid-geometry","the input geometry is neither polyline nor polygon");const{spatialReference:o}=t;if(!y(o))throw new e("geodesic-densify:invalid-spatial-reference","the input geometry spatial reference is not supported");const c="polyline"===t.type?t.paths:t.rings,h=[],l=[0,0],p=new b;for(const e of c){const t=[];h.push(t),t.push([e[0][0],e[0][1]]);let n,i,r=e[0][0],a=e[0][1];for(let c=0;c<e.length-1;c++){if(n=e[c+1][0],i=e[c+1][1],r===n&&a===i)continue;const h=[r,a];q(p,[r,a],[n,i],o);const{azimuth:f,distance:u}=p,m=u/s;if(m>1){for(let e=1;e<=m-1;e++){j(l,h,f,e*s,o),t.push(l.slice())}j(l,h,f,(u+Math.floor(m-1)*s)/2,o),t.push(l.slice())}j(l,h,f,u,o),t.push(l.slice()),r=l[0],a=l[1]}}const f=n(a,o);return"polyline"===t.type?new r({paths:h,spatialReference:f}):new i({rings:h,spatialReference:f})}class b{constructor(e=0,t=void 0,n=void 0){this.distance=e,this.azimuth=t,this.reverseAzimuth=n}}function j(e,t,n,s,i){const r=t[0],a=t[1],c=r*o,h=a*o,l=(n??0)*o,{a:p,b:f,f:u}=d(i),m=Math.sin(l),g=Math.cos(l),M=(1-u)*Math.tan(h),w=1/Math.sqrt(1+M*M),y=M*w,v=Math.atan2(M,g),R=w*m,z=R*R,b=1-z,j=b*(p*p-f*f)/(f*f),q=1+j/16384*(4096+j*(j*(320-175*j)-768)),x=j/1024*(256+j*(j*(74-47*j)-128));let A,N,S,P=s/(f*q),k=2*Math.PI;for(;Math.abs(P-k)>1e-12;){S=Math.cos(2*v+P),A=Math.sin(P),N=Math.cos(P);k=P,P=s/(f*q)+x*A*(S+x/4*(N*(2*S*S-1)-x/6*S*(4*A*A-3)*(4*S*S-3)))}const F=y*A-w*N*g,U=Math.atan2(y*N+w*A*g,(1-u)*Math.sqrt(z+F*F)),C=u/16*b*(4+u*(4-3*b)),E=Math.atan2(A*m,w*N-y*A*g)-(1-C)*u*R*(P+C*A*(S+C*N*(2*S*S-1)));return e[0]=(c+E)/o,e[1]=U/o,e}function q(e,t,n,s){const i=t[0]*o,r=t[1]*o,a=n[0]*o,c=n[1]*o,{a:h,b:l,f:p,radius:f}=d(s),u=a-i,m=Math.atan((1-p)*Math.tan(r)),g=Math.atan((1-p)*Math.tan(c)),M=Math.sin(m),w=Math.cos(m),y=Math.sin(g),v=Math.cos(g);let R,z,b,j,q,x,A,N,S,P,k=1e3,F=u;do{if(A=Math.sin(F),N=Math.cos(F),b=Math.sqrt(v*A*(v*A)+(w*y-M*v*N)*(w*y-M*v*N)),0===b)return e.distance=0,e.azimuth=void 0,e.reverseAzimuth=void 0,e;q=M*y+w*v*N,x=Math.atan2(b,q),S=w*v*A/b,z=1-S*S,j=q-2*M*y/z,isNaN(j)&&(j=0),P=p/16*z*(4+p*(4-3*z)),R=F,F=u+(1-P)*p*S*(x+P*b*(j+P*q*(2*j*j-1)))}while(Math.abs(F-R)>1e-12&&--k>0);if(0===k){const t=f,n=Math.acos(Math.sin(r)*Math.sin(c)+Math.cos(r)*Math.cos(c)*Math.cos(a-i))*t,s=a-i,h=Math.sin(s)*Math.cos(c),l=Math.cos(r)*Math.sin(c)-Math.sin(r)*Math.cos(c)*Math.cos(s),p=Math.atan2(h,l);return e.azimuth=p/o,e.distance=n,e.reverseAzimuth=void 0,e}const U=z*(h*h-l*l)/(l*l),C=U/1024*(256+U*(U*(74-47*U)-128)),E=l*(1+U/16384*(4096+U*(U*(320-175*U)-768)))*(x-C*b*(j+C/4*(q*(2*j*j-1)-C/6*j*(4*b*b-3)*(4*j*j-3)))),G=Math.atan2(v*Math.sin(F),w*y-M*v*Math.cos(F)),I=Math.atan2(w*Math.sin(F),w*y*Math.cos(F)-M*v);return e.azimuth=G/o,e.distance=E,e.reverseAzimuth=I/o,e}function x(n,s,i="meters"){if(!n||!s)throw new e("geodesic-distance:missing-parameters","one or both input parameters are missing");if(!n.spatialReference||!s.spatialReference)throw new e("geodesic-distance:invalid-parameters","one or both input points do not have a spatial reference");if(!f(n.spatialReference,s.spatialReference))throw new e("geodesic-distance:invalid-parameters","spatial references of input parameters do not match");const{spatialReference:r}=n;if(!y(r))throw new e("geodesic-distance:not-supported","input geometry spatial reference is not supported");if(n.x===s.x&&n.y===s.y)return new b(0,0,0);const a=new b;return q(a,[n.x,n.y],[s.x,s.y],r),a.distance=t(a.distance,"meters",i),a.azimuth=M(a.azimuth),a.reverseAzimuth=M(a.reverseAzimuth),a}function A(t,n,i){if(!t||null==n||null==i)throw new e("point-from-distance:missing-parameters","one or more input parameters are missing or undefined");if(i<0||i>360)throw new e("point-from-distance:-of-bounds","azimuth is restricted to angles between, and including, 0° to 360° degrees");if(!t.spatialReference)throw new e("point-from-distance:missing-spatial-reference","the input point must have a spatial reference");const{spatialReference:r}=t;if(!y(r))throw new e("geodesic-distance:not-supported","input geometry spatial reference is not supported");const a=[0,0];return j(a,[t.x,t.y],i,n,r),new s({x:a[0],y:a[1],spatialReference:r})}function N(e){return y(e)?e:p(e)?a.WGS84:null}export{b as InverseGeodeticSolverResult,j as directGeodeticSolver,v as geodesicAreas,N as geodesicCompatibleSpatialReference,z as geodesicDensify,x as geodesicDistance,R as geodesicLengths,q as inverseGeodeticSolver,y as isSupported,A as pointFromDistance};