UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) 5.96 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import t from"../../core/PriorityQueue.js";import{create as e}from"./aaBoundingRect.js";import{getCursorBoundsXY as n,getCursorPathBounds as i}from"./boundsUtils.js";import{ringCentroidCursorXY as r,ringsCentroidCursor as a}from"./centroid.js";import{projectPointOnLineSeg as o,distanceFromPointToPolygon as s}from"./coordsUtils.js";import{segmentIntersects as c}from"./intersectsBase.js";const N=100*222045e-21;function l(t){if(0===t.totalSize)return null;const a=n(t);if(!a)return null;const o=4*(Math.abs(a[0])+Math.abs(a[2])+Math.abs(a[1])+Math.abs(a[3])+1)*N;let s=0,c=0;t.reset();for(let e=0;t.nextPath();e++){const n=t.getCurrentRingArea();n>c&&(c=n,s=e)}if(t.seekPath(s),0===t.pathSize)return null;t.seekPathStart();const l=i(t);if(Math.abs(c)<=2*o*o)return[(l[0]+l[2])/2,(l[1]+l[3])/2];t.seekPathStart();const x=r(t,e());if(null===x)return null;if(t.totalPoints<4)return x;const m=[[NaN,NaN],[NaN,NaN],[NaN,NaN],[NaN,NaN]],d=[NaN,NaN,NaN,NaN],P=[NaN,NaN,NaN,NaN];let y=!1,M=f(x,t,!0);0===M.distance&&(y=!0,m[0][0]=x[0],m[0][1]=x[1],M=f(x,t,!1)),d[0]=M.distance,P[0]=0;const b=[NaN,NaN];let S=!1,k=.25,z=-1,g=NaN;do{if(g=NaN,m[1]=h(t,w(l[0],l[2],k),o,a),isNaN(m[1][0])||isNaN(m[1][1])||(M=f(m[1],t,!1),g=M.distance),!isNaN(g)&&g>o&&u(m[1],t))S=!0,d[1]=g,P[1]=p(m[1],x);else if(!isNaN(g)&&g>z&&(z=g,b[0]=m[1][0],b[1]=m[1][1]),k-=.01,k<.1){if(!(z>=0))break;S=!0,d[1]=z,m[1][0]=b[0],m[1][1]=b[1],P[1]=p(m[1],x)}}while(!S);S=!1,k=.5,z=-1;let q=.01,j=1;do{if(g=NaN,m[2]=h(t,w(l[0],l[2],k),o,a),isNaN(m[2][0])||isNaN(m[2][1])||(M=f(m[2],t,!1),g=M.distance),!isNaN(g)&&g>o&&u(m[2],t))S=!0,d[2]=g,P[2]=p(m[2],x);else if(!isNaN(g)&&g>z)z=g,b[0]=m[2][0],b[1]=m[2][1];else if(g>z&&(z=g,b[0]=m[2][0],b[1]=m[2][1]),k=.5+q*j,q+=.01,j*=-1,k<.3||k>.7){if(!(z>=0))break;S=!0,d[2]=z,m[2][0]=b[0],m[2][1]=b[1],P[2]=p(m[2],x)}}while(!S);S=!1,k=.75,z=-1;do{if(g=NaN,m[3]=h(t,w(l[0],l[2],k),o,a),isNaN(m[3][0])||isNaN(m[3][1])||(M=f(m[3],t,!1),g=M.distance),!isNaN(g)&&g>o&&u(m[3],t))S=!0,d[3]=g,P[3]=p(m[3],x);else if(g>z&&(z=g,b[0]=m[3][0],b[1]=m[3][1]),k+=.01,k>.9){if(!(z>=0))break;S=!0,d[3]=z,m[3][0]=b[0],m[3][1]=b[1],P[3]=p(m[3],x)}}while(!S);const T=[0,1,2,3],D=y?0:1;let R;for(let e=D;e<4;e++)for(let t=D;t<3;t++){const e=P[t],n=P[t+1];C(e,n)>0&&(R=T[t],T[t]=T[t+1],T[t+1]=R,P[t]=n,P[t+1]=e)}let B=D,Q=0,U=0;for(let e=D;e<4;e++){switch(e){case 0:U=2*d[T[e]];break;case 1:U=1.66666666*d[T[e]];break;case 2:U=1.33333333*d[T[e]];break;case 3:U=d[T[e]]}U>Q&&(Q=U,B=T[e])}return m[B]}function u(t,e){let n,i,r,a,o=0;for(e.reset();e.nextPath()&&e.nextPoint();)for(n=e.x,i=e.y;e.nextPoint();n=r,i=a){if(r=e.x,a=e.y,i>t[1]==a>t[1])continue;(r-n)*(t[1]-i)-(a-i)*(t[0]-n)>0?o++:o--}return 0!==o}function f(t,e,n){if(n&&u(t,e))return{coord:t,distance:0};let i=1/0,r=0,a=0,s=[0,0],c=[0,0];const N=[0,0];for(e.reset();e.nextPath()&&e.nextPoint();)if(!(e.pathSize<2))for(s[0]=e.x,s[1]=e.y;e.nextPoint();s=c){c=[e.x,e.y],o(N,t,s,c);const n=p(t,N);n<i&&(i=n,r=N[0],a=N[1])}return{coord:[r,a],distance:Math.sqrt(i)}}function h(t,n,i,r){const a=[n,0];let o=1/0,s=1/0,N=!1,l=!1;const u=[[n,r[1]-1],[n,r[3]+1]],f=[0,0],h=[0,0],m=[0,0],d=[[0,0],[0,0]],P=e();for(t.reset();t.nextPath()&&t.nextPoint();)if(!(t.pathSize<2))for(d[0][0]=t.x,d[0][1]=t.y;t.nextPoint();d[0][0]=d[1][0],d[0][1]=d[1][1]){if(d[1][0]=t.x,d[1][1]=t.y,null===x(P,d))continue;if(h[0]=u[0][0],h[1]=u[0][1],m[0]=u[1][0],m[1]=u[1][1],0===M(P,h,m))continue;if(!c(u[0],u[1],d[0],d[1],f))continue;const e=f[1];o>s?e<o&&(o=e,N=!0):e<s&&(s=e,l=!0)}return N&&l?a[1]=(o+s)/2:a[0]=a[1]=NaN,a}function x(t,n){if(n.length<2)return null;t||(t=e());const[i,r]=n[0],[a,o]=n[1];return t[0]=Math.min(i,a),t[1]=Math.min(r,o),t[2]=Math.max(i,a),t[3]=Math.max(r,o),t}const m=1,d=4,P=3,y=12;function M(t,e,n){let i=b(e,t),r=b(n,t);const a=t[0],o=t[1],s=t[2],c=t[3];if(i&r)return 0;if(!(i|r))return 4;const N=(i?1:0)|(r?2:0);do{const N=n[0]-e[0],l=n[1]-e[1];if(N>l)i&P?(i&m?(e[1]+=l*(a-e[0])/N,e[0]=a):(e[1]+=l*(s-e[0])/N,e[0]=s),i=b(e,t)):r&P?(r&m?(n[1]+=l*(a-n[0])/N,n[0]=a):(n[1]+=l*(s-n[0])/N,n[0]=s),r=b(n,t)):i?(i&d?(e[0]+=N*(o-e[1])/l,e[1]=o):(e[0]+=N*(c-e[1])/l,e[1]=c),i=b(e,t)):(r&d?(n[0]+=N*(o-n[1])/l,n[1]=o):(n[0]+=N*(c-n[1])/l,n[1]=c),r=b(n,t));else if(i&y?(i&d?(e[0]+=N*(o-e[1])/l,e[1]=o):(e[0]+=N*(c-e[1])/l,e[1]=c),i=b(e,t)):r&y?(r&d?(n[0]+=N*(o-n[1])/l,n[1]=o):(n[0]+=N*(c-n[1])/l,n[1]=c),r=b(n,t)):i?(i&m?(e[1]+=l*(a-e[0])/N,e[0]=a):(e[1]+=l*(s-e[0])/N,e[0]=s),i=b(e,t)):(r&m?(n[1]+=l*(a-n[0])/N,n[0]=a):(n[1]+=l*(s-n[0])/N,n[0]=s),r=b(n,t)),i&r)return 0}while(i|r);return N}function b(t,e){return(t[0]<e[0]?1:0)|(t[0]>e[2]?1:0)<<1|(t[1]<e[1]?1:0)<<2|(t[1]>e[3]?1:0)<<3}function w(t,e,n){return t+(e-t)*n}function p(t,e){return(t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1])}function C(t,e){if(t<e)return-1;if(t>e)return 1;if(t===e)return 0;const n=isNaN(t),i=isNaN(e);return n<i?-1:n>i?1:0}class S{constructor(t,e,n,i){this.x=t,this.y=e,this.cellSize=n,this.distancefromCellCenter=s(t,e,i),this.maxDistanceToPolygon=this.distancefromCellCenter+this.cellSize*Math.SQRT2}}const k=1,z=100;function g(e){if(!e.nextPath()||!e.pathSize)return null;const n=i(e),r=n[2]-n[0],o=n[3]-n[1];if(0===r||0===o)return[n[0]+r/2,n[1]+o/2];const s=Math.max(Math.min(r,o)/z,k),c=new t(((t,e)=>e.maxDistanceToPolygon-t.maxDistanceToPolygon)),N=Math.min(r,o);let l=N/2,u=0,f=0;for(u=n[0];u<n[2];u+=N)for(f=n[1];f<n[3];f+=N)c.enqueue(new S(u+l,f+l,l,e));e.reset(),e.nextPath();const h=a(e);if(null===h)return null;let x,m=new S(h[0],h[1],0,e);for(;c.size>0;)x=c.dequeue(),x.distancefromCellCenter>m.distancefromCellCenter&&(m=x),x.maxDistanceToPolygon-m.distancefromCellCenter<=s||(l=x.cellSize/2,c.enqueue(new S(x.x-l,x.y-l,l,e)),c.enqueue(new S(x.x+l,x.y-l,l,e)),c.enqueue(new S(x.x-l,x.y+l,l,e)),c.enqueue(new S(x.x+l,x.y+l,l,e)));return[m.x,m.y]}export{l as getLabelPoint,g as getPolylabelPoint};