@maplat/transform
Version:
A JavaScript library that performs coordinate transformation between two plane coordinate systems using transformation definitions generated by Maplat.
2 lines (1 loc) • 14.9 kB
JavaScript
(function(p,O){typeof exports=="object"&&typeof module<"u"?O(exports):typeof define=="function"&&define.amd?define(["exports"],O):(p=typeof globalThis<"u"?globalThis:p||self,O(p.maplat_transform={}))})(this,function(p){"use strict";var Ot=Object.defineProperty;var St=(p,O,S)=>O in p?Ot(p,O,{enumerable:!0,configurable:!0,writable:!0,value:S}):p[O]=S;var _=(p,O,S)=>St(p,typeof O!="symbol"?O+"":O,S);const O=11102230246251565e-32,S=134217729,ot=(3+8*O)*O;function D(e,t,n,r,a){let s,c,d,g,l=t[0],y=r[0],o=0,u=0;y>l==y>-l?(s=l,l=t[++o]):(s=y,y=r[++u]);let b=0;if(o<e&&u<n)for(y>l==y>-l?(c=l+s,d=s-(c-l),l=t[++o]):(c=y+s,d=s-(c-y),y=r[++u]),s=c,d!==0&&(a[b++]=d);o<e&&u<n;)y>l==y>-l?(c=s+l,g=c-s,d=s-(c-g)+(l-g),l=t[++o]):(c=s+y,g=c-s,d=s-(c-g)+(y-g),y=r[++u]),s=c,d!==0&&(a[b++]=d);for(;o<e;)c=s+l,g=c-s,d=s-(c-g)+(l-g),l=t[++o],s=c,d!==0&&(a[b++]=d);for(;u<n;)c=s+y,g=c-s,d=s-(c-g)+(y-g),y=r[++u],s=c,d!==0&&(a[b++]=d);return(s!==0||b===0)&&(a[b++]=s),b}function at(e,t){let n=t[0];for(let r=1;r<e;r++)n+=t[r];return n}function Y(e){return new Float64Array(e)}const ft=(3+16*O)*O,ct=(2+12*O)*O,ut=(9+64*O)*O*O,X=Y(4),G=Y(8),z=Y(12),J=Y(16),I=Y(4);function ht(e,t,n,r,a,s,c){let d,g,l,y,o,u,b,x,h,f,i,w,v,A,E,m,M,P;const k=e-a,N=n-a,C=t-s,U=r-s;A=k*U,u=S*k,b=u-(u-k),x=k-b,u=S*U,h=u-(u-U),f=U-h,E=x*f-(A-b*h-x*h-b*f),m=C*N,u=S*C,b=u-(u-C),x=C-b,u=S*N,h=u-(u-N),f=N-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,X[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,X[1]=v-(i+o)+(o-m),P=w+i,o=P-w,X[2]=w-(P-o)+(i-o),X[3]=P;let B=at(4,X),W=ct*c;if(B>=W||-B>=W||(o=e-k,d=e-(k+o)+(o-a),o=n-N,l=n-(N+o)+(o-a),o=t-C,g=t-(C+o)+(o-s),o=r-U,y=r-(U+o)+(o-s),d===0&&g===0&&l===0&&y===0)||(W=ut*c+ot*Math.abs(B),B+=k*y+U*d-(C*l+N*g),B>=W||-B>=W))return B;A=d*U,u=S*d,b=u-(u-d),x=d-b,u=S*U,h=u-(u-U),f=U-h,E=x*f-(A-b*h-x*h-b*f),m=g*N,u=S*g,b=u-(u-g),x=g-b,u=S*N,h=u-(u-N),f=N-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,I[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,I[1]=v-(i+o)+(o-m),P=w+i,o=P-w,I[2]=w-(P-o)+(i-o),I[3]=P;const Mt=D(4,X,4,I,G);A=k*y,u=S*k,b=u-(u-k),x=k-b,u=S*y,h=u-(u-y),f=y-h,E=x*f-(A-b*h-x*h-b*f),m=C*l,u=S*C,b=u-(u-C),x=C-b,u=S*l,h=u-(u-l),f=l-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,I[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,I[1]=v-(i+o)+(o-m),P=w+i,o=P-w,I[2]=w-(P-o)+(i-o),I[3]=P;const Et=D(Mt,G,4,I,z);A=d*y,u=S*d,b=u-(u-d),x=d-b,u=S*y,h=u-(u-y),f=y-h,E=x*f-(A-b*h-x*h-b*f),m=g*l,u=S*g,b=u-(u-g),x=g-b,u=S*l,h=u-(u-l),f=l-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,I[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,I[1]=v-(i+o)+(o-m),P=w+i,o=P-w,I[2]=w-(P-o)+(i-o),I[3]=P;const Tt=D(Et,z,4,I,J);return J[Tt-1]}function gt(e,t,n,r,a,s){const c=(t-s)*(n-a),d=(e-a)*(r-s),g=c-d,l=Math.abs(c+d);return Math.abs(g)>=ft*l?g:-ht(e,t,n,r,a,s,l)}function dt(e,t){var n,r,a=0,s,c,d,g,l,y,o,u=e[0],b=e[1],x=t.length;for(n=0;n<x;n++){r=0;var h=t[n],f=h.length-1;if(y=h[0],y[0]!==h[f][0]&&y[1]!==h[f][1])throw new Error("First and last coordinates in a ring must be the same");for(c=y[0]-u,d=y[1]-b,r;r<f;r++){if(o=h[r+1],g=o[0]-u,l=o[1]-b,d===0&&l===0){if(g<=0&&c>=0||c<=0&&g>=0)return 0}else if(l>=0&&d<=0||l<=0&&d>=0){if(s=gt(c,g,d,l,0,0),s===0)return 0;(s>0&&l>0&&d<=0||s<0&&l<=0&&d>0)&&a++}y=o,d=l,c=g}}return a%2!==0}function K(e,t,n={}){const r={type:"Feature"};return(n.id===0||n.id)&&(r.id=n.id),n.bbox&&(r.bbox=n.bbox),r.properties=t||{},r.geometry=e,r}function $(e,t,n={}){if(!e)throw new Error("coordinates is required");if(!Array.isArray(e))throw new Error("coordinates must be an Array");if(e.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!H(e[0])||!H(e[1]))throw new Error("coordinates must contain numbers");return K({type:"Point",coordinates:e},t,n)}function Q(e,t,n={}){for(const a of e){if(a.length<4)throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");if(a[a.length-1].length!==a[0].length)throw new Error("First and last Position are not equivalent.");for(let s=0;s<a[a.length-1].length;s++)if(a[a.length-1][s]!==a[0][s])throw new Error("First and last Position are not equivalent.")}return K({type:"Polygon",coordinates:e},t,n)}function F(e,t={}){const n={type:"FeatureCollection"};return t.id&&(n.id=t.id),t.bbox&&(n.bbox=t.bbox),n.features=e,n}function H(e){return!isNaN(e)&&e!==null&&!Array.isArray(e)}function lt(e){if(!e)throw new Error("coord is required");if(!Array.isArray(e)){if(e.type==="Feature"&&e.geometry!==null&&e.geometry.type==="Point")return[...e.geometry.coordinates];if(e.type==="Point")return[...e.coordinates]}if(Array.isArray(e)&&e.length>=2&&!Array.isArray(e[0])&&!Array.isArray(e[1]))return[...e];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function Z(e){if(Array.isArray(e))return e;if(e.type==="Feature"){if(e.geometry!==null)return e.geometry.coordinates}else if(e.coordinates)return e.coordinates;throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array")}function yt(e){return e.type==="Feature"?e.geometry:e}function bt(e,t,n={}){if(!e)throw new Error("point is required");if(!t)throw new Error("polygon is required");const r=lt(e),a=yt(t),s=a.type,c=t.bbox;let d=a.coordinates;if(c&&wt(r,c)===!1)return!1;s==="Polygon"&&(d=[d]);let g=!1;for(var l=0;l<d.length;++l){const y=dt(r,d[l]);if(y===0)return!n.ignoreBoundary;y&&(g=!0)}return g}function wt(e,t){return t[0]<=e[0]&&t[1]<=e[1]&&t[2]>=e[0]&&t[3]>=e[1]}var q=bt;function mt(e){const t=e.features;for(let n=0;n<t.length;n++){const r=t[n];`${r.properties.a.index}`.substring(0,1)==="b"&&`${r.properties.b.index}`.substring(0,1)==="b"?t[n]={geometry:{type:"Polygon",coordinates:[[r.geometry.coordinates[0][2],r.geometry.coordinates[0][0],r.geometry.coordinates[0][1],r.geometry.coordinates[0][2]]]},properties:{a:{geom:r.properties.c.geom,index:r.properties.c.index},b:{geom:r.properties.a.geom,index:r.properties.a.index},c:{geom:r.properties.b.geom,index:r.properties.b.index}},type:"Feature"}:`${r.properties.c.index}`.substring(0,1)==="b"&&`${r.properties.a.index}`.substring(0,1)==="b"&&(t[n]={geometry:{type:"Polygon",coordinates:[[r.geometry.coordinates[0][1],r.geometry.coordinates[0][2],r.geometry.coordinates[0][0],r.geometry.coordinates[0][1]]]},properties:{a:{geom:r.properties.b.geom,index:r.properties.b.index},b:{geom:r.properties.c.geom,index:r.properties.c.index},c:{geom:r.properties.a.geom,index:r.properties.a.index}},type:"Feature"})}return e}function xt(e){const t=["a","b","c","a"].map(s=>e.properties[s].geom),n=e.geometry.coordinates[0],r=e.properties,a={a:{geom:n[0],index:r.a.index},b:{geom:n[1],index:r.b.index},c:{geom:n[2],index:r.c.index}};return Q([t],a)}function _t(e){const t=[0,1,2,0].map(r=>e[r][0][0]),n={a:{geom:e[0][0][1],index:e[0][1]},b:{geom:e[1][0][1],index:e[1][1]},c:{geom:e[2][0][1],index:e[2][1]}};return Q([t],n)}function V(e,t,n,r,a,s=!1,c){const d=e.map(g=>{(!c||c<2.00703)&&(g=tt(g));const l=isFinite(g)?t[g]:g==="c"?r:g==="b0"?a[0]:g==="b1"?a[1]:g==="b2"?a[2]:g==="b3"?a[3]:function(){const y=g.match(/e(\d+)/);if(y){const o=parseInt(y[1]);return n[o]}throw"Bad index value for indexesToTri"}();return s?[[l[1],l[0]],g]:[[l[0],l[1]],g]});return _t(d)}function tt(e){return typeof e=="number"?e:e.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/,"$1$2")}function et(e,t){return t&&t>=2.00703||Array.isArray(e[0])?e:e.map(n=>[n.illstNodes,n.mercNodes,n.startEnd])}function rt(e,t){for(let n=0;n<t.features.length;n++)if(q(e,t.features[n]))return t.features[n]}function nt(e,t,n){const r=t.geometry.coordinates[0][0],a=t.geometry.coordinates[0][1],s=t.geometry.coordinates[0][2],c=e.geometry.coordinates,d=t.properties.a.geom,g=t.properties.b.geom,l=t.properties.c.geom,y=[a[0]-r[0],a[1]-r[1]],o=[s[0]-r[0],s[1]-r[1]],u=[c[0]-r[0],c[1]-r[1]],b=[g[0]-d[0],g[1]-d[1]],x=[l[0]-d[0],l[1]-d[1]];let h=(o[1]*u[0]-o[0]*u[1])/(y[0]*o[1]-y[1]*o[0]),f=(y[0]*u[1]-y[1]*u[0])/(y[0]*o[1]-y[1]*o[0]);if(n){const i=n[t.properties.a.index],w=n[t.properties.b.index],v=n[t.properties.c.index];let A;if(h<0||f<0||1-h-f<0){const E=h/(h+f),m=f/(h+f);A=h/w/(E/w+m/v),f=f/v/(E/w+m/v)}else A=h/w/(h/w+f/v+(1-h-f)/i),f=f/v/(h/w+f/v+(1-h-f)/i);h=A}return[h*b[0]+f*x[0]+d[0],h*b[1]+f*x[1]+d[1]]}function vt(e,t,n,r){const a=e.geometry.coordinates,s=n.geometry.coordinates,c=Math.atan2(a[0]-s[0],a[1]-s[1]),d=At(c,t[0]);if(d===void 0)throw new Error("Unable to determine vertex index");const g=t[1][d];return nt(e,g.features[0],r)}function st(e,t,n,r,a,s,c,d){let g;if(c&&(g=rt(e,F([c]))),!g){if(n){const l=e.geometry.coordinates,y=n.gridNum,o=n.xOrigin,u=n.yOrigin,b=n.xUnit,x=n.yUnit,h=n.gridCache,f=R(l[0],o,b,y),i=R(l[1],u,x,y),w=h[f]?h[f][i]?h[f][i]:[]:[];t=F(w.map(v=>t.features[v]))}g=rt(e,t)}return d&&d(g),g?nt(e,g,s):vt(e,r,a,s)}function R(e,t,n,r){let a=Math.floor((e-t)/n);return a>=r&&(a=r-1),a}function At(e,t){let n=it(e-t[0]),r=Math.PI*2,a;for(let s=0;s<t.length;s++){const c=(s+1)%t.length,d=it(e-t[c]),g=Math.min(Math.abs(n),Math.abs(d));n*d<=0&&g<r&&(r=g,a=s),n=d}return a}function it(e,t=!1){const n=t?function(r){return!(r>=0&&r<Math.PI*2)}:function(r){return!(r>-1*Math.PI&&r<=Math.PI)};for(;n(e);)e=e+2*Math.PI*(e>0?-1:1);return e}const L=2.00703,T=class T{constructor(){_(this,"points",[]);_(this,"pointsWeightBuffer");_(this,"strict_status");_(this,"vertices_params");_(this,"centroid");_(this,"edgeNodes");_(this,"edges");_(this,"tins");_(this,"kinks");_(this,"yaxisMode",T.YAXIS_INVERT);_(this,"strictMode",T.MODE_AUTO);_(this,"vertexMode",T.VERTEX_PLAIN);_(this,"bounds");_(this,"boundsPolygon");_(this,"wh");_(this,"xy");_(this,"indexedTins");_(this,"stateFull",!1);_(this,"stateTriangle");_(this,"stateBackward")}setCompiled(t){if(t.version||!t.tins&&t.points&&t.tins_points){this.points=t.points,this.pointsWeightBuffer=!t.version||t.version<2.00703?["forw","bakw"].reduce((r,a)=>{const s=t.weight_buffer[a];return s&&(r[a]=Object.keys(s).reduce((c,d)=>{const g=tt(d);return c[g]=s[d],c},{})),r},{}):t.weight_buffer,t.strict_status?this.strict_status=t.strict_status:t.kinks_points?this.strict_status=T.STATUS_ERROR:t.tins_points.length==2?this.strict_status=T.STATUS_LOOSE:this.strict_status=T.STATUS_STRICT,this.vertices_params={forw:[t.vertices_params[0]],bakw:[t.vertices_params[1]]},this.vertices_params.forw[1]=[0,1,2,3].map(r=>{const a=(r+1)%4,s=V(["c",`b${r}`,`b${a}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,L);return F([s])}),this.vertices_params.bakw[1]=[0,1,2,3].map(r=>{const a=(r+1)%4,s=V(["c",`b${r}`,`b${a}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,L);return F([s])}),this.centroid={forw:$(t.centroid_point[0],{target:{geom:t.centroid_point[1],index:"c"}}),bakw:$(t.centroid_point[1],{target:{geom:t.centroid_point[0],index:"c"}})},this.edges=et(t.edges||[]),this.edgeNodes=t.edgeNodes||[];const n=t.tins_points.length==1?0:1;this.tins={forw:F(t.tins_points[0].map(r=>V(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,t.version))),bakw:F(t.tins_points[n].map(r=>V(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,t.version)))},this.addIndexedTin(),t.kinks_points&&(this.kinks={bakw:F(t.kinks_points.map(r=>$(r)))}),t.yaxisMode?this.yaxisMode=t.yaxisMode:this.yaxisMode=T.YAXIS_INVERT,t.vertexMode&&(this.vertexMode=t.vertexMode),t.strictMode&&(this.strictMode=t.strictMode),t.bounds?(this.bounds=t.bounds,this.boundsPolygon=t.boundsPolygon,this.xy=t.xy,this.wh=t.wh):(this.xy=[0,0],t.wh&&(this.wh=t.wh),this.bounds=void 0,this.boundsPolygon=void 0)}else{t=JSON.parse(JSON.stringify(t).replace('"cent"','"c"').replace(/"bbox(\d+)"/g,'"b$1"')),this.tins=t.tins,this.addIndexedTin(),this.strict_status=t.strict_status,this.pointsWeightBuffer=t.weight_buffer,this.vertices_params=t.vertices_params,this.centroid=t.centroid,this.kinks=t.kinks;const n=[];for(let r=0;r<this.tins.forw.features.length;r++){const a=this.tins.forw.features[r];["a","b","c"].map((s,c)=>{const d=a.geometry.coordinates[0][c],g=a.properties[s].geom,l=a.properties[s].index;typeof l=="number"&&(n[l]=[d,g])})}this.points=n}}addIndexedTin(){const t=this.tins,n=t.forw,r=t.bakw,a=Math.ceil(Math.sqrt(n.features.length));if(a<3){this.indexedTins=void 0;return}let s=[],c=[];const d=n.features.map(h=>{let f=[];return Z(h)[0].map(i=>{s.length===0?s=[Array.from(i),Array.from(i)]:(i[0]<s[0][0]&&(s[0][0]=i[0]),i[0]>s[1][0]&&(s[1][0]=i[0]),i[1]<s[0][1]&&(s[0][1]=i[1]),i[1]>s[1][1]&&(s[1][1]=i[1])),f.length===0?f=[Array.from(i),Array.from(i)]:(i[0]<f[0][0]&&(f[0][0]=i[0]),i[0]>f[1][0]&&(f[1][0]=i[0]),i[1]<f[0][1]&&(f[0][1]=i[1]),i[1]>f[1][1]&&(f[1][1]=i[1]))}),f}),g=(s[1][0]-s[0][0])/a,l=(s[1][1]-s[0][1])/a,y=d.reduce((h,f,i)=>{const w=R(f[0][0],s[0][0],g,a),v=R(f[1][0],s[0][0],g,a),A=R(f[0][1],s[0][1],l,a),E=R(f[1][1],s[0][1],l,a);for(let m=w;m<=v;m++){h[m]||(h[m]=[]);for(let M=A;M<=E;M++)h[m][M]||(h[m][M]=[]),h[m][M].push(i)}return h},[]),o=r.features.map(h=>{let f=[];return Z(h)[0].map(i=>{c.length===0?c=[Array.from(i),Array.from(i)]:(i[0]<c[0][0]&&(c[0][0]=i[0]),i[0]>c[1][0]&&(c[1][0]=i[0]),i[1]<c[0][1]&&(c[0][1]=i[1]),i[1]>c[1][1]&&(c[1][1]=i[1])),f.length===0?f=[Array.from(i),Array.from(i)]:(i[0]<f[0][0]&&(f[0][0]=i[0]),i[0]>f[1][0]&&(f[1][0]=i[0]),i[1]<f[0][1]&&(f[0][1]=i[1]),i[1]>f[1][1]&&(f[1][1]=i[1]))}),f}),u=(c[1][0]-c[0][0])/a,b=(c[1][1]-c[0][1])/a,x=o.reduce((h,f,i)=>{const w=R(f[0][0],c[0][0],u,a),v=R(f[1][0],c[0][0],u,a),A=R(f[0][1],c[0][1],b,a),E=R(f[1][1],c[0][1],b,a);for(let m=w;m<=v;m++){h[m]||(h[m]=[]);for(let M=A;M<=E;M++)h[m][M]||(h[m][M]=[]),h[m][M].push(i)}return h},[]);this.indexedTins={forw:{gridNum:a,xOrigin:s[0][0],yOrigin:s[0][1],xUnit:g,yUnit:l,gridCache:y},bakw:{gridNum:a,xOrigin:c[0][0],yOrigin:c[0][1],xUnit:u,yUnit:b,gridCache:x}}}transform(t,n,r){if(n&&this.strict_status==T.STATUS_ERROR)throw'Backward transform is not allowed if strict_status == "strict_error"';this.yaxisMode==T.YAXIS_FOLLOW&&n&&(t=[t[0],-1*t[1]]);const a=$(t);if(this.bounds&&!n&&!r&&!q(a,this.boundsPolygon))return!1;const s=n?this.tins.bakw:this.tins.forw,c=n?this.indexedTins.bakw:this.indexedTins.forw,d=n?this.vertices_params.bakw:this.vertices_params.forw,g=n?this.centroid.bakw:this.centroid.forw,l=n?this.pointsWeightBuffer.bakw:this.pointsWeightBuffer.forw;let y,o;this.stateFull&&(this.stateBackward==n?y=this.stateTriangle:(this.stateBackward=n,this.stateTriangle=void 0),o=b=>{this.stateTriangle=b});let u=st(a,s,c,d,g,l,y,o);if(this.bounds&&n&&!r){const b=$(u);if(!q(b,this.boundsPolygon))return!1}else this.yaxisMode==T.YAXIS_FOLLOW&&!n&&(u=[u[0],-1*u[1]]);return u}};_(T,"VERTEX_PLAIN","plain"),_(T,"VERTEX_BIRDEYE","birdeye"),_(T,"MODE_STRICT","strict"),_(T,"MODE_AUTO","auto"),_(T,"MODE_LOOSE","loose"),_(T,"STATUS_STRICT","strict"),_(T,"STATUS_ERROR","strict_error"),_(T,"STATUS_LOOSE","loose"),_(T,"YAXIS_FOLLOW","follow"),_(T,"YAXIS_INVERT","invert");let j=T;p.Transform=j,p.counterTri=xt,p.format_version=L,p.normalizeEdges=et,p.rotateVerticesTriangle=mt,p.transformArr=st,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});