@maplat/transform 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (function(S,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(S=typeof globalThis<"u"?globalThis:S||self,T(S.maplat_transform={}))})(this,function(S){"use strict";const T=11102230246251565e-32,A=134217729,st=(3+8*T)*T;function Y(t,e,r,n,c){let i,f,g,h,l=e[0],y=n[0],o=0,u=0;y>l==y>-l?(i=l,l=e[++o]):(i=y,y=n[++u]);let b=0;if(o<t&&u<r)for(y>l==y>-l?(f=l+i,g=i-(f-l),l=e[++o]):(f=y+i,g=i-(f-y),y=n[++u]),i=f,g!==0&&(c[b++]=g);o<t&&u<r;)y>l==y>-l?(f=i+l,h=f-i,g=i-(f-h)+(l-h),l=e[++o]):(f=i+y,h=f-i,g=i-(f-h)+(y-h),y=n[++u]),i=f,g!==0&&(c[b++]=g);for(;o<t;)f=i+l,h=f-i,g=i-(f-h)+(l-h),l=e[++o],i=f,g!==0&&(c[b++]=g);for(;u<r;)f=i+y,h=f-i,g=i-(f-h)+(y-h),y=n[++u],i=f,g!==0&&(c[b++]=g);return(i!==0||b===0)&&(c[b++]=i),b}function ot(t,e){let r=e[0];for(let n=1;n<t;n++)r+=e[n];return r}function X(t){return new Float64Array(t)}const at=(3+16*T)*T,ct=(2+12*T)*T,ut=(9+64*T)*T*T,U=X(4),q=X(8),z=X(12),j=X(16),P=X(4);function ft(t,e,r,n,c,i,f){let g,h,l,y,o,u,b,x,d,a,s,m,_,p,M,w,v,E;const k=t-c,I=r-c,N=e-i,B=n-i;p=k*B,u=A*k,b=u-(u-k),x=k-b,u=A*B,d=u-(u-B),a=B-d,M=x*a-(p-b*d-x*d-b*a),w=N*I,u=A*N,b=u-(u-N),x=N-b,u=A*I,d=u-(u-I),a=I-d,v=x*a-(w-b*d-x*d-b*a),s=M-v,o=M-s,U[0]=M-(s+o)+(o-v),m=p+s,o=m-p,_=p-(m-o)+(s-o),s=_-w,o=_-s,U[1]=_-(s+o)+(o-w),E=m+s,o=E-m,U[2]=m-(E-o)+(s-o),U[3]=E;let R=ot(4,U),V=ct*f;if(R>=V||-R>=V||(o=t-k,g=t-(k+o)+(o-c),o=r-I,l=r-(I+o)+(o-c),o=e-N,h=e-(N+o)+(o-i),o=n-B,y=n-(B+o)+(o-i),g===0&&h===0&&l===0&&y===0)||(V=ut*f+st*Math.abs(R),R+=k*y+B*g-(N*l+I*h),R>=V||-R>=V))return R;p=g*B,u=A*g,b=u-(u-g),x=g-b,u=A*B,d=u-(u-B),a=B-d,M=x*a-(p-b*d-x*d-b*a),w=h*I,u=A*h,b=u-(u-h),x=h-b,u=A*I,d=u-(u-I),a=I-d,v=x*a-(w-b*d-x*d-b*a),s=M-v,o=M-s,P[0]=M-(s+o)+(o-v),m=p+s,o=m-p,_=p-(m-o)+(s-o),s=_-w,o=_-s,P[1]=_-(s+o)+(o-w),E=m+s,o=E-m,P[2]=m-(E-o)+(s-o),P[3]=E;const Ct=Y(4,U,4,P,q);p=k*y,u=A*k,b=u-(u-k),x=k-b,u=A*y,d=u-(u-y),a=y-d,M=x*a-(p-b*d-x*d-b*a),w=N*l,u=A*N,b=u-(u-N),x=N-b,u=A*l,d=u-(u-l),a=l-d,v=x*a-(w-b*d-x*d-b*a),s=M-v,o=M-s,P[0]=M-(s+o)+(o-v),m=p+s,o=m-p,_=p-(m-o)+(s-o),s=_-w,o=_-s,P[1]=_-(s+o)+(o-w),E=m+s,o=E-m,P[2]=m-(E-o)+(s-o),P[3]=E;const Rt=Y(Ct,q,4,P,z);p=g*y,u=A*g,b=u-(u-g),x=g-b,u=A*y,d=u-(u-y),a=y-d,M=x*a-(p-b*d-x*d-b*a),w=h*l,u=A*h,b=u-(u-h),x=h-b,u=A*l,d=u-(u-l),a=l-d,v=x*a-(w-b*d-x*d-b*a),s=M-v,o=M-s,P[0]=M-(s+o)+(o-v),m=p+s,o=m-p,_=p-(m-o)+(s-o),s=_-w,o=_-s,P[1]=_-(s+o)+(o-w),E=m+s,o=E-m,P[2]=m-(E-o)+(s-o),P[3]=E;const Ut=Y(Rt,z,4,P,j);return j[Ut-1]}function dt(t,e,r,n,c,i){const f=(e-i)*(r-c),g=(t-c)*(n-i),h=f-g,l=Math.abs(f+g);return Math.abs(h)>=at*l?h:-ft(t,e,r,n,c,i,l)}function ht(t,e){var r,n,c=0,i,f,g,h,l,y,o,u=t[0],b=t[1],x=e.length;for(r=0;r<x;r++){n=0;var d=e[r],a=d.length-1;if(y=d[0],y[0]!==d[a][0]&&y[1]!==d[a][1])throw new Error("First and last coordinates in a ring must be the same");for(f=y[0]-u,g=y[1]-b,n;n<a;n++){if(o=d[n+1],h=o[0]-u,l=o[1]-b,g===0&&l===0){if(h<=0&&f>=0||f<=0&&h>=0)return 0}else if(l>=0&&g<=0||l<=0&&g>=0){if(i=dt(f,h,g,l,0,0),i===0)return 0;(i>0&&l>0&&g<=0||i<0&&l<=0&&g>0)&&c++}y=o,g=l,f=h}}return c%2!==0}function G(t,e,r={}){const n={type:"Feature"};return(r.id===0||r.id)&&(n.id=r.id),r.bbox&&(n.bbox=r.bbox),n.properties=e||{},n.geometry=t,n}function W(t,e,r={}){if(!t)throw new Error("coordinates is required");if(!Array.isArray(t))throw new Error("coordinates must be an Array");if(t.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!K(t[0])||!K(t[1]))throw new Error("coordinates must contain numbers");return G({type:"Point",coordinates:t},e,r)}function J(t,e,r={}){for(const c of t){if(c.length<4)throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");if(c[c.length-1].length!==c[0].length)throw new Error("First and last Position are not equivalent.");for(let i=0;i<c[c.length-1].length;i++)if(c[c.length-1][i]!==c[0][i])throw new Error("First and last Position are not equivalent.")}return G({type:"Polygon",coordinates:t},e,r)}function F(t,e={}){const r={type:"FeatureCollection"};return e.id&&(r.id=e.id),e.bbox&&(r.bbox=e.bbox),r.features=t,r}function K(t){return!isNaN(t)&&t!==null&&!Array.isArray(t)}function gt(t){if(!t)throw new Error("coord is required");if(!Array.isArray(t)){if(t.type==="Feature"&&t.geometry!==null&&t.geometry.type==="Point")return[...t.geometry.coordinates];if(t.type==="Point")return[...t.coordinates]}if(Array.isArray(t)&&t.length>=2&&!Array.isArray(t[0])&&!Array.isArray(t[1]))return[...t];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function Q(t){if(Array.isArray(t))return t;if(t.type==="Feature"){if(t.geometry!==null)return t.geometry.coordinates}else if(t.coordinates)return t.coordinates;throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array")}function lt(t){return t.type==="Feature"?t.geometry:t}function yt(t,e,r={}){if(!t)throw new Error("point is required");if(!e)throw new Error("polygon is required");const n=gt(t),c=lt(e),i=c.type,f=e.bbox;let g=c.coordinates;if(f&&bt(n,f)===!1)return!1;i==="Polygon"&&(g=[g]);let h=!1;for(var l=0;l<g.length;++l){const y=ht(n,g[l]);if(y===0)return!r.ignoreBoundary;y&&(h=!0)}return h}function bt(t,e){return e[0]<=t[0]&&e[1]<=t[1]&&e[2]>=t[0]&&e[3]>=t[1]}var L=yt;function H(t,e){for(let r=0;r<e.features.length;r++)if(L(t,e.features[r]))return e.features[r]}function Z(t,e,r){const n=e.geometry.coordinates[0][0],c=e.geometry.coordinates[0][1],i=e.geometry.coordinates[0][2],f=t.geometry.coordinates,g=e.properties.a.geom,h=e.properties.b.geom,l=e.properties.c.geom,y=[c[0]-n[0],c[1]-n[1]],o=[i[0]-n[0],i[1]-n[1]],u=[f[0]-n[0],f[1]-n[1]],b=[h[0]-g[0],h[1]-g[1]],x=[l[0]-g[0],l[1]-g[1]];let d=(o[1]*u[0]-o[0]*u[1])/(y[0]*o[1]-y[1]*o[0]),a=(y[0]*u[1]-y[1]*u[0])/(y[0]*o[1]-y[1]*o[0]);if(r){const s=r[e.properties.a.index],m=r[e.properties.b.index],_=r[e.properties.c.index];let p;if(d<0||a<0||1-d-a<0){const M=d/(d+a),w=a/(d+a);p=d/m/(M/m+w/_),a=a/_/(M/m+w/_)}else p=d/m/(d/m+a/_+(1-d-a)/s),a=a/_/(d/m+a/_+(1-d-a)/s);d=p}return[d*b[0]+a*x[0]+g[0],d*b[1]+a*x[1]+g[1]]}function mt(t,e,r,n){const c=t.geometry.coordinates,i=r.geometry.coordinates,f=Math.atan2(c[0]-i[0],c[1]-i[1]),g=wt(f,e[0]);if(g===void 0)throw new Error("Unable to determine vertex index");const h=e[1][g];return Z(t,h.features[0],n)}function tt(t,e,r,n,c,i,f,g){let h;if(f&&(h=H(t,F([f]))),!h){if(r){const l=t.geometry.coordinates,y=r.gridNum,o=r.xOrigin,u=r.yOrigin,b=r.xUnit,x=r.yUnit,d=r.gridCache,a=C(l[0],o,b,y),s=C(l[1],u,x,y),m=d[a]?d[a][s]?d[a][s]:[]:[];e=F(m.map(_=>e.features[_]))}h=H(t,e)}return g&&g(h),h?Z(t,h,i):mt(t,n,c,i)}function C(t,e,r,n){let c=Math.floor((t-e)/r);return c>=n&&(c=n-1),c}function wt(t,e){let r=et(t-e[0]),n=Math.PI*2,c;for(let i=0;i<e.length;i++){const f=(i+1)%e.length,g=et(t-e[f]),h=Math.min(Math.abs(r),Math.abs(g));r*g<=0&&h<n&&(n=h,c=i),r=g}return c}function et(t,e=!1){const r=e?function(n){return!(n>=0&&n<Math.PI*2)}:function(n){return!(n>-1*Math.PI&&n<=Math.PI)};for(;r(t);)t=t+2*Math.PI*(t>0?-1:1);return t}function rt(t,e){return e&&e>=2.00703||Array.isArray(t[0])?t:t.map(r=>[r.illstNodes,r.mercNodes,r.startEnd])}function xt(t){const e=t.features;for(let r=0;r<e.length;r++){const n=e[r];`${n.properties.a.index}`.substring(0,1)==="b"&&`${n.properties.b.index}`.substring(0,1)==="b"?e[r]={geometry:{type:"Polygon",coordinates:[[n.geometry.coordinates[0][2],n.geometry.coordinates[0][0],n.geometry.coordinates[0][1],n.geometry.coordinates[0][2]]]},properties:{a:{geom:n.properties.c.geom,index:n.properties.c.index},b:{geom:n.properties.a.geom,index:n.properties.a.index},c:{geom:n.properties.b.geom,index:n.properties.b.index}},type:"Feature"}:`${n.properties.c.index}`.substring(0,1)==="b"&&`${n.properties.a.index}`.substring(0,1)==="b"&&(e[r]={geometry:{type:"Polygon",coordinates:[[n.geometry.coordinates[0][1],n.geometry.coordinates[0][2],n.geometry.coordinates[0][0],n.geometry.coordinates[0][1]]]},properties:{a:{geom:n.properties.b.geom,index:n.properties.b.index},b:{geom:n.properties.c.geom,index:n.properties.c.index},c:{geom:n.properties.a.geom,index:n.properties.a.index}},type:"Feature"})}return t}function _t(t){const e=["a","b","c","a"].map(i=>t.properties[i].geom),r=t.geometry.coordinates[0],n=t.properties,c={a:{geom:r[0],index:n.a.index},b:{geom:r[1],index:n.b.index},c:{geom:r[2],index:n.c.index}};return J([e],c)}function pt(t){const e=[0,1,2,0].map(n=>t[n][0][0]),r={a:{geom:t[0][0][1],index:t[0][1]},b:{geom:t[1][0][1],index:t[1][1]},c:{geom:t[2][0][1],index:t[2][1]}};return J([e],r)}function $(t,e,r,n,c,i=!1,f){const g=t.map(h=>{(!f||f<2.00703)&&(h=nt(h));const l=isFinite(h)?e[h]:h==="c"?n:h==="b0"?c[0]:h==="b1"?c[1]:h==="b2"?c[2]:h==="b3"?c[3]:function(){const y=h.match(/e(\d+)/);if(y){const o=parseInt(y[1]);return r[o]}throw"Bad index value for indexesToTri"}();return i?[[l[1],l[0]],h]:[[l[0],l[1]],h]});return pt(g)}function nt(t){return typeof t=="number"?t:t.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/,"$1$2")}const D=2.00703;function vt(t){return!!(t.version||!t.tins&&t.points&&t.tins_points)}function Mt(t){return{points:t.points,pointsWeightBuffer:Et(t),strictStatus:Pt(t),verticesParams:Tt(t),centroid:St(t),edges:rt(t.edges||[]),edgeNodes:t.edgeNodes||[],tins:Ot(t),kinks:kt(t.kinks_points),yaxisMode:t.yaxisMode??"invert",strictMode:t.strictMode??"auto",vertexMode:t.vertexMode,bounds:t.bounds,boundsPolygon:t.boundsPolygon,wh:t.wh,xy:t.bounds?t.xy:[0,0]}}function At(t){const e=It(t),r=e.tins;return{compiled:e,tins:r,points:Nt(r),strictStatus:e.strict_status,pointsWeightBuffer:e.weight_buffer,verticesParams:e.vertices_params,centroid:e.centroid,kinks:e.kinks}}function Et(t){return!t.version||t.version<D?["forw","bakw"].reduce((e,r)=>{const n=t.weight_buffer[r];return n&&(e[r]=Object.keys(n).reduce((c,i)=>{const f=nt(i);return c[f]=n[i],c},{})),e},{}):t.weight_buffer}function Pt(t){return t.strict_status?t.strict_status:t.kinks_points?"strict_error":t.tins_points.length===2?"loose":"strict"}function Tt(t){const e={forw:[t.vertices_params[0]],bakw:[t.vertices_params[1]]};return e.forw[1]=it(t,!1),e.bakw[1]=it(t,!0),e}function it(t,e){return[0,1,2,3].map(r=>{const n=(r+1)%4,c=$(["c",`b${r}`,`b${n}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,e,D);return F([c])})}function St(t){return{forw:W(t.centroid_point[0],{target:{geom:t.centroid_point[1],index:"c"}}),bakw:W(t.centroid_point[1],{target:{geom:t.centroid_point[0],index:"c"}})}}function Ot(t){const e=t.tins_points.length===1?0:1;return{forw:F(t.tins_points[0].map(r=>$(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,t.version))),bakw:F(t.tins_points[e].map(r=>$(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,t.version)))}}function kt(t){if(t)return{bakw:F(t.map(e=>W(e)))}}function It(t){return JSON.parse(JSON.stringify(t).replace('"cent"','"c"').replace(/"bbox(\d+)"/g,'"b$1"'))}function Nt(t){const e=[],r=t.forw.features;for(let n=0;n<r.length;n++){const c=r[n];["a","b","c"].map((i,f)=>{const g=c.geometry.coordinates[0][f],h=c.properties[i].geom,l=c.properties[i].index;typeof l=="number"&&(e[l]=[g,h])})}return e}const Bt=D;class O{static VERTEX_PLAIN="plain";static VERTEX_BIRDEYE="birdeye";static MODE_STRICT="strict";static MODE_AUTO="auto";static MODE_LOOSE="loose";static STATUS_STRICT="strict";static STATUS_ERROR="strict_error";static STATUS_LOOSE="loose";static YAXIS_FOLLOW="follow";static YAXIS_INVERT="invert";points=[];pointsWeightBuffer;strict_status;vertices_params;centroid;edgeNodes;edges;tins;kinks;yaxisMode=O.YAXIS_INVERT;strictMode=O.MODE_AUTO;vertexMode=O.VERTEX_PLAIN;bounds;boundsPolygon;wh;xy;indexedTins;stateFull=!1;stateTriangle;stateBackward;constructor(){}setCompiled(e){if(vt(e)){this.applyModernState(Mt(e));return}this.applyLegacyState(At(e))}applyModernState(e){this.points=e.points,this.pointsWeightBuffer=e.pointsWeightBuffer,this.strict_status=e.strictStatus,this.vertices_params=e.verticesParams,this.centroid=e.centroid,this.edges=e.edges,this.edgeNodes=e.edgeNodes||[],this.tins=e.tins,this.addIndexedTin(),this.kinks=e.kinks,this.yaxisMode=e.yaxisMode??O.YAXIS_INVERT,this.vertexMode=e.vertexMode??O.VERTEX_PLAIN,this.strictMode=e.strictMode??O.MODE_AUTO,e.bounds?(this.bounds=e.bounds,this.boundsPolygon=e.boundsPolygon,this.xy=e.xy,this.wh=e.wh):(this.bounds=void 0,this.boundsPolygon=void 0,this.xy=e.xy??[0,0],e.wh&&(this.wh=e.wh))}applyLegacyState(e){this.tins=e.tins,this.addIndexedTin(),this.strict_status=e.strictStatus,this.pointsWeightBuffer=e.pointsWeightBuffer,this.vertices_params=e.verticesParams,this.centroid=e.centroid,this.kinks=e.kinks,this.points=e.points}addIndexedTin(){const e=this.tins,r=e.forw,n=e.bakw,c=Math.ceil(Math.sqrt(r.features.length));if(c<3){this.indexedTins=void 0;return}let i=[],f=[];const g=r.features.map(d=>{let a=[];return Q(d)[0].map(s=>{i.length===0?i=[Array.from(s),Array.from(s)]:(s[0]<i[0][0]&&(i[0][0]=s[0]),s[0]>i[1][0]&&(i[1][0]=s[0]),s[1]<i[0][1]&&(i[0][1]=s[1]),s[1]>i[1][1]&&(i[1][1]=s[1])),a.length===0?a=[Array.from(s),Array.from(s)]:(s[0]<a[0][0]&&(a[0][0]=s[0]),s[0]>a[1][0]&&(a[1][0]=s[0]),s[1]<a[0][1]&&(a[0][1]=s[1]),s[1]>a[1][1]&&(a[1][1]=s[1]))}),a}),h=(i[1][0]-i[0][0])/c,l=(i[1][1]-i[0][1])/c,y=g.reduce((d,a,s)=>{const m=C(a[0][0],i[0][0],h,c),_=C(a[1][0],i[0][0],h,c),p=C(a[0][1],i[0][1],l,c),M=C(a[1][1],i[0][1],l,c);for(let w=m;w<=_;w++){d[w]||(d[w]=[]);for(let v=p;v<=M;v++)d[w][v]||(d[w][v]=[]),d[w][v].push(s)}return d},[]),o=n.features.map(d=>{let a=[];return Q(d)[0].map(s=>{f.length===0?f=[Array.from(s),Array.from(s)]:(s[0]<f[0][0]&&(f[0][0]=s[0]),s[0]>f[1][0]&&(f[1][0]=s[0]),s[1]<f[0][1]&&(f[0][1]=s[1]),s[1]>f[1][1]&&(f[1][1]=s[1])),a.length===0?a=[Array.from(s),Array.from(s)]:(s[0]<a[0][0]&&(a[0][0]=s[0]),s[0]>a[1][0]&&(a[1][0]=s[0]),s[1]<a[0][1]&&(a[0][1]=s[1]),s[1]>a[1][1]&&(a[1][1]=s[1]))}),a}),u=(f[1][0]-f[0][0])/c,b=(f[1][1]-f[0][1])/c,x=o.reduce((d,a,s)=>{const m=C(a[0][0],f[0][0],u,c),_=C(a[1][0],f[0][0],u,c),p=C(a[0][1],f[0][1],b,c),M=C(a[1][1],f[0][1],b,c);for(let w=m;w<=_;w++){d[w]||(d[w]=[]);for(let v=p;v<=M;v++)d[w][v]||(d[w][v]=[]),d[w][v].push(s)}return d},[]);this.indexedTins={forw:{gridNum:c,xOrigin:i[0][0],yOrigin:i[0][1],xUnit:h,yUnit:l,gridCache:y},bakw:{gridNum:c,xOrigin:f[0][0],yOrigin:f[0][1],xUnit:u,yUnit:b,gridCache:x}}}transform(e,r,n){if(r&&this.strict_status==O.STATUS_ERROR)throw'Backward transform is not allowed if strict_status == "strict_error"';this.yaxisMode==O.YAXIS_FOLLOW&&r&&(e=[e[0],-1*e[1]]);const c=W(e);if(this.bounds&&!r&&!n&&!L(c,this.boundsPolygon))return!1;const i=r?this.tins.bakw:this.tins.forw,f=r?this.indexedTins.bakw:this.indexedTins.forw,g=r?this.vertices_params.bakw:this.vertices_params.forw,h=r?this.centroid.bakw:this.centroid.forw,l=r?this.pointsWeightBuffer.bakw:this.pointsWeightBuffer.forw;let y,o;this.stateFull&&(this.stateBackward==r?y=this.stateTriangle:(this.stateBackward=r,this.stateTriangle=void 0),o=b=>{this.stateTriangle=b});let u=tt(c,i,f,g,h,l,y,o);if(this.bounds&&r&&!n){const b=W(u);if(!L(b,this.boundsPolygon))return!1}else this.yaxisMode==O.YAXIS_FOLLOW&&!r&&(u=[u[0],-1*u[1]]);return u}}S.Transform=O,S.counterTri=_t,S.format_version=Bt,S.normalizeEdges=rt,S.rotateVerticesTriangle=xt,S.transformArr=tt,Object.defineProperty(S,Symbol.toStringTag,{value:"Module"})});
1
+ (function(P,k){typeof exports=="object"&&typeof module<"u"?k(exports):typeof define=="function"&&define.amd?define(["exports"],k):(P=typeof globalThis<"u"?globalThis:P||self,k(P.maplat_transform={}))})(this,(function(P){"use strict";var Xt=Object.defineProperty;var Wt=(P,k,R)=>k in P?Xt(P,k,{enumerable:!0,configurable:!0,writable:!0,value:R}):P[k]=R;var x=(P,k,R)=>Wt(P,typeof k!="symbol"?k+"":k,R);function k(t,e,r={}){const n={type:"Feature"};return(r.id===0||r.id)&&(n.id=r.id),r.bbox&&(n.bbox=r.bbox),n.properties=e||{},n.geometry=t,n}function R(t,e,r={}){if(!t)throw new Error("coordinates is required");if(!Array.isArray(t))throw new Error("coordinates must be an Array");if(t.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!J(t[0])||!J(t[1]))throw new Error("coordinates must contain numbers");return k({type:"Point",coordinates:t},e,r)}function G(t,e,r={}){for(const c of t){if(c.length<4)throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");if(c[c.length-1].length!==c[0].length)throw new Error("First and last Position are not equivalent.");for(let i=0;i<c[c.length-1].length;i++)if(c[c.length-1][i]!==c[0][i])throw new Error("First and last Position are not equivalent.")}return k({type:"Polygon",coordinates:t},e,r)}function W(t,e={}){const r={type:"FeatureCollection"};return e.id&&(r.id=e.id),e.bbox&&(r.bbox=e.bbox),r.features=t,r}function J(t){return!isNaN(t)&&t!==null&&!Array.isArray(t)}function at(t){if(!t)throw new Error("coord is required");if(!Array.isArray(t)){if(t.type==="Feature"&&t.geometry!==null&&t.geometry.type==="Point")return[...t.geometry.coordinates];if(t.type==="Point")return[...t.coordinates]}if(Array.isArray(t)&&t.length>=2&&!Array.isArray(t[0])&&!Array.isArray(t[1]))return[...t];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function K(t){if(Array.isArray(t))return t;if(t.type==="Feature"){if(t.geometry!==null)return t.geometry.coordinates}else if(t.coordinates)return t.coordinates;throw new Error("coords must be GeoJSON Feature, Geometry Object or an Array")}function ct(t){return t.type==="Feature"?t.geometry:t}const F=11102230246251565e-32,S=134217729,ut=(3+8*F)*F;function $(t,e,r,n,c){let i,f,g,h,l=e[0],y=n[0],o=0,u=0;y>l==y>-l?(i=l,l=e[++o]):(i=y,y=n[++u]);let b=0;if(o<t&&u<r)for(y>l==y>-l?(f=l+i,g=i-(f-l),l=e[++o]):(f=y+i,g=i-(f-y),y=n[++u]),i=f,g!==0&&(c[b++]=g);o<t&&u<r;)y>l==y>-l?(f=i+l,h=f-i,g=i-(f-h)+(l-h),l=e[++o]):(f=i+y,h=f-i,g=i-(f-h)+(y-h),y=n[++u]),i=f,g!==0&&(c[b++]=g);for(;o<t;)f=i+l,h=f-i,g=i-(f-h)+(l-h),l=e[++o],i=f,g!==0&&(c[b++]=g);for(;u<r;)f=i+y,h=f-i,g=i-(f-h)+(y-h),y=n[++u],i=f,g!==0&&(c[b++]=g);return(i!==0||b===0)&&(c[b++]=i),b}function ft(t,e){let r=e[0];for(let n=1;n<t;n++)r+=e[n];return r}function Y(t){return new Float64Array(t)}const dt=(3+16*F)*F,ht=(2+12*F)*F,gt=(9+64*F)*F*F,V=Y(4),Q=Y(8),H=Y(12),Z=Y(16),T=Y(4);function lt(t,e,r,n,c,i,f){let g,h,l,y,o,u,b,p,d,a,s,m,v,M,_,w,A,O;const I=t-c,N=r-c,B=e-i,C=n-i;M=I*C,u=S*I,b=u-(u-I),p=I-b,u=S*C,d=u-(u-C),a=C-d,_=p*a-(M-b*d-p*d-b*a),w=B*N,u=S*B,b=u-(u-B),p=B-b,u=S*N,d=u-(u-N),a=N-d,A=p*a-(w-b*d-p*d-b*a),s=_-A,o=_-s,V[0]=_-(s+o)+(o-A),m=M+s,o=m-M,v=M-(m-o)+(s-o),s=v-w,o=v-s,V[1]=v-(s+o)+(o-w),O=m+s,o=O-m,V[2]=m-(O-o)+(s-o),V[3]=O;let X=ft(4,V),L=ht*f;if(X>=L||-X>=L||(o=t-I,g=t-(I+o)+(o-c),o=r-N,l=r-(N+o)+(o-c),o=e-B,h=e-(B+o)+(o-i),o=n-C,y=n-(C+o)+(o-i),g===0&&h===0&&l===0&&y===0)||(L=gt*f+ut*Math.abs(X),X+=I*y+C*g-(B*l+N*h),X>=L||-X>=L))return X;M=g*C,u=S*g,b=u-(u-g),p=g-b,u=S*C,d=u-(u-C),a=C-d,_=p*a-(M-b*d-p*d-b*a),w=h*N,u=S*h,b=u-(u-h),p=h-b,u=S*N,d=u-(u-N),a=N-d,A=p*a-(w-b*d-p*d-b*a),s=_-A,o=_-s,T[0]=_-(s+o)+(o-A),m=M+s,o=m-M,v=M-(m-o)+(s-o),s=v-w,o=v-s,T[1]=v-(s+o)+(o-w),O=m+s,o=O-m,T[2]=m-(O-o)+(s-o),T[3]=O;const Rt=$(4,V,4,T,Q);M=I*y,u=S*I,b=u-(u-I),p=I-b,u=S*y,d=u-(u-y),a=y-d,_=p*a-(M-b*d-p*d-b*a),w=B*l,u=S*B,b=u-(u-B),p=B-b,u=S*l,d=u-(u-l),a=l-d,A=p*a-(w-b*d-p*d-b*a),s=_-A,o=_-s,T[0]=_-(s+o)+(o-A),m=M+s,o=m-M,v=M-(m-o)+(s-o),s=v-w,o=v-s,T[1]=v-(s+o)+(o-w),O=m+s,o=O-m,T[2]=m-(O-o)+(s-o),T[3]=O;const Ut=$(Rt,Q,4,T,H);M=g*y,u=S*g,b=u-(u-g),p=g-b,u=S*y,d=u-(u-y),a=y-d,_=p*a-(M-b*d-p*d-b*a),w=h*l,u=S*h,b=u-(u-h),p=h-b,u=S*l,d=u-(u-l),a=l-d,A=p*a-(w-b*d-p*d-b*a),s=_-A,o=_-s,T[0]=_-(s+o)+(o-A),m=M+s,o=m-M,v=M-(m-o)+(s-o),s=v-w,o=v-s,T[1]=v-(s+o)+(o-w),O=m+s,o=O-m,T[2]=m-(O-o)+(s-o),T[3]=O;const Ft=$(Ut,H,4,T,Z);return Z[Ft-1]}function yt(t,e,r,n,c,i){const f=(e-i)*(r-c),g=(t-c)*(n-i),h=f-g,l=Math.abs(f+g);return Math.abs(h)>=dt*l?h:-lt(t,e,r,n,c,i,l)}function bt(t,e){var r,n,c=0,i,f,g,h,l,y,o,u=t[0],b=t[1],p=e.length;for(r=0;r<p;r++){n=0;var d=e[r],a=d.length-1;if(y=d[0],y[0]!==d[a][0]&&y[1]!==d[a][1])throw new Error("First and last coordinates in a ring must be the same");for(f=y[0]-u,g=y[1]-b,n;n<a;n++){if(o=d[n+1],h=o[0]-u,l=o[1]-b,g===0&&l===0){if(h<=0&&f>=0||f<=0&&h>=0)return 0}else if(l>=0&&g<=0||l<=0&&g>=0){if(i=yt(f,h,g,l,0,0),i===0)return 0;(i>0&&l>0&&g<=0||i<0&&l<=0&&g>0)&&c++}y=o,g=l,f=h}}return c%2!==0}function D(t,e,r={}){if(!t)throw new Error("point is required");if(!e)throw new Error("polygon is required");const n=at(t),c=ct(e),i=c.type,f=e.bbox;let g=c.coordinates;if(f&&mt(n,f)===!1)return!1;i==="Polygon"&&(g=[g]);let h=!1;for(var l=0;l<g.length;++l){const y=bt(n,g[l]);if(y===0)return!r.ignoreBoundary;y&&(h=!0)}return h}function mt(t,e){return e[0]<=t[0]&&e[1]<=t[1]&&e[2]>=t[0]&&e[3]>=t[1]}function tt(t,e){for(let r=0;r<e.features.length;r++)if(D(t,e.features[r]))return e.features[r]}function et(t,e,r){const n=e.geometry.coordinates[0][0],c=e.geometry.coordinates[0][1],i=e.geometry.coordinates[0][2],f=t.geometry.coordinates,g=e.properties.a.geom,h=e.properties.b.geom,l=e.properties.c.geom,y=[c[0]-n[0],c[1]-n[1]],o=[i[0]-n[0],i[1]-n[1]],u=[f[0]-n[0],f[1]-n[1]],b=[h[0]-g[0],h[1]-g[1]],p=[l[0]-g[0],l[1]-g[1]];let d=(o[1]*u[0]-o[0]*u[1])/(y[0]*o[1]-y[1]*o[0]),a=(y[0]*u[1]-y[1]*u[0])/(y[0]*o[1]-y[1]*o[0]);if(r){const s=r[e.properties.a.index],m=r[e.properties.b.index],v=r[e.properties.c.index];let M;if(d<0||a<0||1-d-a<0){const _=d/(d+a),w=a/(d+a);M=d/m/(_/m+w/v),a=a/v/(_/m+w/v)}else M=d/m/(d/m+a/v+(1-d-a)/s),a=a/v/(d/m+a/v+(1-d-a)/s);d=M}return[d*b[0]+a*p[0]+g[0],d*b[1]+a*p[1]+g[1]]}function wt(t,e,r,n){const c=t.geometry.coordinates,i=r.geometry.coordinates,f=Math.atan2(c[0]-i[0],c[1]-i[1]),g=xt(f,e[0]);if(g===void 0)throw new Error("Unable to determine vertex index");const h=e[1][g];return et(t,h.features[0],n)}function rt(t,e,r,n,c,i,f,g){let h;if(f&&(h=tt(t,W([f]))),!h){if(r){const l=t.geometry.coordinates,y=r.gridNum,o=r.xOrigin,u=r.yOrigin,b=r.xUnit,p=r.yUnit,d=r.gridCache,a=U(l[0],o,b,y),s=U(l[1],u,p,y),m=d[a]?d[a][s]?d[a][s]:[]:[];e=W(m.map(v=>e.features[v]))}h=tt(t,e)}return g&&g(h),h?et(t,h,i):wt(t,n,c,i)}function U(t,e,r,n){let c=Math.floor((t-e)/r);return c>=n&&(c=n-1),c}function xt(t,e){let r=nt(t-e[0]),n=Math.PI*2,c;for(let i=0;i<e.length;i++){const f=(i+1)%e.length,g=nt(t-e[f]),h=Math.min(Math.abs(r),Math.abs(g));r*g<=0&&h<n&&(n=h,c=i),r=g}return c}function nt(t,e=!1){const r=e?function(n){return!(n>=0&&n<Math.PI*2)}:function(n){return!(n>-1*Math.PI&&n<=Math.PI)};for(;r(t);)t=t+2*Math.PI*(t>0?-1:1);return t}function it(t,e){return e&&e>=2.00703||Array.isArray(t[0])?t:t.map(r=>[r.illstNodes,r.mercNodes,r.startEnd])}function pt(t){const e=t.features;for(let r=0;r<e.length;r++){const n=e[r];`${n.properties.a.index}`.substring(0,1)==="b"&&`${n.properties.b.index}`.substring(0,1)==="b"?e[r]={geometry:{type:"Polygon",coordinates:[[n.geometry.coordinates[0][2],n.geometry.coordinates[0][0],n.geometry.coordinates[0][1],n.geometry.coordinates[0][2]]]},properties:{a:{geom:n.properties.c.geom,index:n.properties.c.index},b:{geom:n.properties.a.geom,index:n.properties.a.index},c:{geom:n.properties.b.geom,index:n.properties.b.index}},type:"Feature"}:`${n.properties.c.index}`.substring(0,1)==="b"&&`${n.properties.a.index}`.substring(0,1)==="b"&&(e[r]={geometry:{type:"Polygon",coordinates:[[n.geometry.coordinates[0][1],n.geometry.coordinates[0][2],n.geometry.coordinates[0][0],n.geometry.coordinates[0][1]]]},properties:{a:{geom:n.properties.b.geom,index:n.properties.b.index},b:{geom:n.properties.c.geom,index:n.properties.c.index},c:{geom:n.properties.a.geom,index:n.properties.a.index}},type:"Feature"})}return t}function vt(t){const e=["a","b","c","a"].map(i=>t.properties[i].geom),r=t.geometry.coordinates[0],n=t.properties,c={a:{geom:r[0],index:n.a.index},b:{geom:r[1],index:n.b.index},c:{geom:r[2],index:n.c.index}};return G([e],c)}function Mt(t){const e=[0,1,2,0].map(n=>t[n][0][0]),r={a:{geom:t[0][0][1],index:t[0][1]},b:{geom:t[1][0][1],index:t[1][1]},c:{geom:t[2][0][1],index:t[2][1]}};return G([e],r)}function q(t,e,r,n,c,i=!1,f){const g=t.map(h=>{(!f||f<2.00703)&&(h=st(h));const l=isFinite(h)?e[h]:h==="c"?n:h==="b0"?c[0]:h==="b1"?c[1]:h==="b2"?c[2]:h==="b3"?c[3]:(function(){const y=h.match(/e(\d+)/);if(y){const o=parseInt(y[1]);return r[o]}throw"Bad index value for indexesToTri"})();return i?[[l[1],l[0]],h]:[[l[0],l[1]],h]});return Mt(g)}function st(t){return typeof t=="number"?t:t.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/,"$1$2")}const z=2.00703;function At(t){return!!(t.version||!t.tins&&t.points&&t.tins_points)}function _t(t){return{points:t.points,pointsWeightBuffer:Pt(t),strictStatus:St(t),verticesParams:Ot(t),centroid:Tt(t),edges:it(t.edges||[]),edgeNodes:t.edgeNodes||[],tins:kt(t),kinks:It(t.kinks_points),yaxisMode:t.yaxisMode??"invert",strictMode:t.strictMode??"auto",vertexMode:t.vertexMode,bounds:t.bounds,boundsPolygon:t.boundsPolygon,wh:t.wh,xy:t.bounds?t.xy:[0,0]}}function Et(t){const e=Nt(t),r=e.tins;return{compiled:e,tins:r,points:Bt(r),strictStatus:e.strict_status,pointsWeightBuffer:e.weight_buffer,verticesParams:e.vertices_params,centroid:e.centroid,kinks:e.kinks}}function Pt(t){return!t.version||t.version<z?["forw","bakw"].reduce((e,r)=>{const n=t.weight_buffer[r];return n&&(e[r]=Object.keys(n).reduce((c,i)=>{const f=st(i);return c[f]=n[i],c},{})),e},{}):t.weight_buffer}function St(t){return t.strict_status?t.strict_status:t.kinks_points?"strict_error":t.tins_points.length===2?"loose":"strict"}function Ot(t){const e={forw:[t.vertices_params[0]],bakw:[t.vertices_params[1]]};return e.forw[1]=ot(t,!1),e.bakw[1]=ot(t,!0),e}function ot(t,e){return[0,1,2,3].map(r=>{const n=(r+1)%4,c=q(["c",`b${r}`,`b${n}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,e,z);return W([c])})}function Tt(t){return{forw:R(t.centroid_point[0],{target:{geom:t.centroid_point[1],index:"c"}}),bakw:R(t.centroid_point[1],{target:{geom:t.centroid_point[0],index:"c"}})}}function kt(t){const e=t.tins_points.length===1?0:1;return{forw:W(t.tins_points[0].map(r=>q(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,t.version))),bakw:W(t.tins_points[e].map(r=>q(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,t.version)))}}function It(t){if(t)return{bakw:W(t.map(e=>R(e)))}}function Nt(t){return JSON.parse(JSON.stringify(t).replace('"cent"','"c"').replace(/"bbox(\d+)"/g,'"b$1"'))}function Bt(t){const e=[],r=t.forw.features;for(let n=0;n<r.length;n++){const c=r[n];["a","b","c"].map((i,f)=>{const g=c.geometry.coordinates[0][f],h=c.properties[i].geom,l=c.properties[i].index;typeof l=="number"&&(e[l]=[g,h])})}return e}const Ct=z,E=class E{constructor(){x(this,"points",[]);x(this,"pointsWeightBuffer");x(this,"strict_status");x(this,"vertices_params");x(this,"centroid");x(this,"edgeNodes");x(this,"edges");x(this,"tins");x(this,"kinks");x(this,"yaxisMode",E.YAXIS_INVERT);x(this,"strictMode",E.MODE_AUTO);x(this,"vertexMode",E.VERTEX_PLAIN);x(this,"bounds");x(this,"boundsPolygon");x(this,"wh");x(this,"xy");x(this,"indexedTins");x(this,"stateFull",!1);x(this,"stateTriangle");x(this,"stateBackward");x(this,"priority");x(this,"importance");x(this,"xyBounds");x(this,"mercBounds")}setCompiled(e){if(At(e)){this.applyModernState(_t(e));return}this.applyLegacyState(Et(e))}applyModernState(e){this.points=e.points,this.pointsWeightBuffer=e.pointsWeightBuffer,this.strict_status=e.strictStatus,this.vertices_params=e.verticesParams,this.centroid=e.centroid,this.edges=e.edges,this.edgeNodes=e.edgeNodes||[],this.tins=e.tins,this.addIndexedTin(),this.kinks=e.kinks,this.yaxisMode=e.yaxisMode??E.YAXIS_INVERT,this.vertexMode=e.vertexMode??E.VERTEX_PLAIN,this.strictMode=e.strictMode??E.MODE_AUTO,e.bounds?(this.bounds=e.bounds,this.boundsPolygon=e.boundsPolygon,this.xy=e.xy,this.wh=e.wh):(this.bounds=void 0,this.boundsPolygon=void 0,this.xy=e.xy??[0,0],e.wh&&(this.wh=e.wh))}applyLegacyState(e){this.tins=e.tins,this.addIndexedTin(),this.strict_status=e.strictStatus,this.pointsWeightBuffer=e.pointsWeightBuffer,this.vertices_params=e.verticesParams,this.centroid=e.centroid,this.kinks=e.kinks,this.points=e.points}addIndexedTin(){const e=this.tins,r=e.forw,n=e.bakw,c=Math.ceil(Math.sqrt(r.features.length));if(c<3){this.indexedTins=void 0;return}let i=[],f=[];const g=r.features.map(d=>{let a=[];return K(d)[0].map(s=>{i.length===0?i=[Array.from(s),Array.from(s)]:(s[0]<i[0][0]&&(i[0][0]=s[0]),s[0]>i[1][0]&&(i[1][0]=s[0]),s[1]<i[0][1]&&(i[0][1]=s[1]),s[1]>i[1][1]&&(i[1][1]=s[1])),a.length===0?a=[Array.from(s),Array.from(s)]:(s[0]<a[0][0]&&(a[0][0]=s[0]),s[0]>a[1][0]&&(a[1][0]=s[0]),s[1]<a[0][1]&&(a[0][1]=s[1]),s[1]>a[1][1]&&(a[1][1]=s[1]))}),a}),h=(i[1][0]-i[0][0])/c,l=(i[1][1]-i[0][1])/c,y=g.reduce((d,a,s)=>{const m=U(a[0][0],i[0][0],h,c),v=U(a[1][0],i[0][0],h,c),M=U(a[0][1],i[0][1],l,c),_=U(a[1][1],i[0][1],l,c);for(let w=m;w<=v;w++){d[w]||(d[w]=[]);for(let A=M;A<=_;A++)d[w][A]||(d[w][A]=[]),d[w][A].push(s)}return d},[]),o=n.features.map(d=>{let a=[];return K(d)[0].map(s=>{f.length===0?f=[Array.from(s),Array.from(s)]:(s[0]<f[0][0]&&(f[0][0]=s[0]),s[0]>f[1][0]&&(f[1][0]=s[0]),s[1]<f[0][1]&&(f[0][1]=s[1]),s[1]>f[1][1]&&(f[1][1]=s[1])),a.length===0?a=[Array.from(s),Array.from(s)]:(s[0]<a[0][0]&&(a[0][0]=s[0]),s[0]>a[1][0]&&(a[1][0]=s[0]),s[1]<a[0][1]&&(a[0][1]=s[1]),s[1]>a[1][1]&&(a[1][1]=s[1]))}),a}),u=(f[1][0]-f[0][0])/c,b=(f[1][1]-f[0][1])/c,p=o.reduce((d,a,s)=>{const m=U(a[0][0],f[0][0],u,c),v=U(a[1][0],f[0][0],u,c),M=U(a[0][1],f[0][1],b,c),_=U(a[1][1],f[0][1],b,c);for(let w=m;w<=v;w++){d[w]||(d[w]=[]);for(let A=M;A<=_;A++)d[w][A]||(d[w][A]=[]),d[w][A].push(s)}return d},[]);this.indexedTins={forw:{gridNum:c,xOrigin:i[0][0],yOrigin:i[0][1],xUnit:h,yUnit:l,gridCache:y},bakw:{gridNum:c,xOrigin:f[0][0],yOrigin:f[0][1],xUnit:u,yUnit:b,gridCache:p}}}transform(e,r,n){if(r&&this.strict_status==E.STATUS_ERROR)throw'Backward transform is not allowed if strict_status == "strict_error"';this.yaxisMode==E.YAXIS_FOLLOW&&r&&(e=[e[0],-1*e[1]]);const c=R(e);if(this.bounds&&!r&&!n&&!D(c,this.boundsPolygon))return!1;const i=r?this.tins.bakw:this.tins.forw,f=r?this.indexedTins.bakw:this.indexedTins.forw,g=r?this.vertices_params.bakw:this.vertices_params.forw,h=r?this.centroid.bakw:this.centroid.forw,l=r?this.pointsWeightBuffer.bakw:this.pointsWeightBuffer.forw;let y,o;this.stateFull&&(this.stateBackward==r?y=this.stateTriangle:(this.stateBackward=r,this.stateTriangle=void 0),o=b=>{this.stateTriangle=b});let u=rt(c,i,f,g,h,l,y,o);if(this.bounds&&r&&!n){const b=R(u);if(!D(b,this.boundsPolygon))return!1}else this.yaxisMode==E.YAXIS_FOLLOW&&!r&&(u=[u[0],-1*u[1]]);return u}};x(E,"VERTEX_PLAIN","plain"),x(E,"VERTEX_BIRDEYE","birdeye"),x(E,"MODE_STRICT","strict"),x(E,"MODE_AUTO","auto"),x(E,"MODE_LOOSE","loose"),x(E,"STATUS_STRICT","strict"),x(E,"STATUS_ERROR","strict_error"),x(E,"STATUS_LOOSE","loose"),x(E,"YAXIS_FOLLOW","follow"),x(E,"YAXIS_INVERT","invert");let j=E;P.Transform=j,P.counterTri=vt,P.format_version=Ct,P.normalizeEdges=it,P.rotateVerticesTriangle=pt,P.transformArr=rt,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -4,10 +4,13 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.3.0",
7
+ "version": "0.4.0",
8
8
  "description": "A JavaScript library that performs coordinate transformation between two plane coordinate systems using transformation definitions generated by Maplat.",
9
9
  "type": "module",
10
- "main": "./dist/maplat_transform.cjs",
10
+ "engines": {
11
+ "pnpm": ">=9",
12
+ "node": ">=20"
13
+ },
11
14
  "module": "./dist/maplat_transform.js",
12
15
  "browser": "./dist/maplat_transform.umd.js",
13
16
  "types": "./dist/index.d.ts",
@@ -16,7 +19,6 @@
16
19
  "types": "./dist/index.d.ts",
17
20
  "browser": "./dist/maplat_transform.umd.js",
18
21
  "import": "./dist/maplat_transform.js",
19
- "require": "./dist/maplat_transform.cjs",
20
22
  "default": "./dist/maplat_transform.js"
21
23
  }
22
24
  },
@@ -43,34 +45,32 @@
43
45
  "MaplatTransform"
44
46
  ],
45
47
  "devDependencies": {
46
- "@eslint/js": "^9.39.1",
47
- "@testing-library/jest-dom": "^6.9.1",
48
- "@types/geojson": "^7946.0.15",
49
- "@types/node": "^24.10.0",
50
- "@typescript-eslint/eslint-plugin": "^8.46.3",
51
- "@typescript-eslint/parser": "^8.46.3",
52
- "@vitest/coverage-v8": "^4.0.8",
48
+ "@eslint/js": "^9.39.2",
49
+ "@types/geojson": "^7946.0.16",
50
+ "@types/node": "^24.10.4",
51
+ "@typescript-eslint/eslint-plugin": "^8.50.1",
52
+ "@typescript-eslint/parser": "^8.50.1",
53
+ "@vitest/coverage-v8": "^3.2.4",
53
54
  "cross-env": "^10.1.0",
54
- "eslint": "^9.39.1",
55
+ "eslint": "^9.39.2",
55
56
  "eslint-config-prettier": "^10.1.8",
56
57
  "jest-matcher-deep-close-to": "^3.0.2",
57
- "jsdom": "^27.1.0",
58
- "prettier": "^3.4.2",
58
+ "jsdom": "^27.4.0",
59
+ "prettier": "^3.7.4",
59
60
  "typescript": "^5.9.3",
60
- "vite": "^7.2.2",
61
- "vite-plugin-dts": "^4.4.0",
62
- "vitest": "^4.0.8"
61
+ "vite": "^6.4.1",
62
+ "vite-plugin-dts": "^4.5.4",
63
+ "vitest": "^3.2.4"
63
64
  },
64
65
  "dependencies": {
65
- "@turf/boolean-point-in-polygon": "^7.2.0",
66
- "@turf/helpers": "^7.2.0",
67
- "@turf/invariant": "^7.2.0"
66
+ "@turf/turf": "^7.3.1"
68
67
  },
69
68
  "scripts": {
70
- "dev": "vite",
71
- "build": "npm run typecheck && cross-env BUILD_MODE=package vite build",
69
+ "dev": "vite --host",
70
+ "build": "pnpm run typecheck && cross-env BUILD_MODE=package vite build",
72
71
  "typecheck": "tsc --noEmit --allowImportingTsExtensions",
73
- "deploy": "cp public/*.html ./ && tsc && vite build",
72
+ "build:demo": "vite build",
73
+ "deploy": "pnpm run build:demo",
74
74
  "test": "vitest run",
75
75
  "test:watch": "vitest",
76
76
  "coverage": "vitest run --coverage",
@@ -1,211 +1,211 @@
1
- import { featureCollection, point } from "@turf/helpers";
2
- import type { Position } from "geojson";
3
- import { normalizeEdges } from "./edgeutils.ts";
4
- import { indexesToTri, normalizeNodeKey } from "./triangulation.ts";
5
- import type { PropertyTriKey } from "./geometry.ts";
6
- import type {
7
- BiDirectionKey,
8
- Compiled,
9
- CompiledLegacy,
10
- LegacyStatePayload,
11
- ModernStatePayload,
12
- PointSet,
13
- StrictStatus,
14
- TinsBD,
15
- VerticesParamsBD,
16
- WeightBufferBD
17
- } from "./types.ts";
18
- import type { WeightBuffer } from "./geometry.ts";
19
-
20
- export const FORMAT_VERSION = 2.00703;
21
-
22
- /**
23
- * Type guard for discriminating modern compiled payloads.
24
- */
25
- export function isModernCompiled(
26
- compiled: Compiled | CompiledLegacy
27
- ): compiled is Compiled {
28
- return Boolean(
29
- compiled.version ||
30
- (!(compiled as CompiledLegacy).tins && compiled.points && compiled.tins_points)
31
- );
32
- }
33
-
34
- /**
35
- * Restore the in-memory state produced by modern compiled payloads.
36
- */
37
- export function restoreModernState(compiled: Compiled): ModernStatePayload {
38
- return {
39
- points: compiled.points,
40
- pointsWeightBuffer: normalizeWeightBuffer(compiled),
41
- strictStatus: deriveStrictStatus(compiled),
42
- verticesParams: buildVerticesParams(compiled),
43
- centroid: buildCentroid(compiled),
44
- edges: normalizeEdges(compiled.edges || []),
45
- edgeNodes: compiled.edgeNodes || [],
46
- tins: buildTins(compiled),
47
- kinks: buildKinks(compiled.kinks_points),
48
- yaxisMode: compiled.yaxisMode ?? "invert",
49
- strictMode: compiled.strictMode ?? "auto",
50
- vertexMode: compiled.vertexMode,
51
- bounds: compiled.bounds,
52
- boundsPolygon: compiled.boundsPolygon,
53
- wh: compiled.wh,
54
- xy: compiled.bounds ? compiled.xy : [0, 0]
55
- };
56
- }
57
-
58
- /**
59
- * Restore the in-memory state produced by the legacy payloads.
60
- */
61
- export function restoreLegacyState(
62
- rawCompiled: CompiledLegacy
63
- ): LegacyStatePayload {
64
- const normalized = normalizeLegacyStructure(rawCompiled);
65
- const tins = normalized.tins!;
66
- return {
67
- compiled: normalized,
68
- tins,
69
- points: rebuildLegacyPoints(tins),
70
- strictStatus: normalized.strict_status,
71
- pointsWeightBuffer: normalized.weight_buffer,
72
- verticesParams: normalized.vertices_params as VerticesParamsBD,
73
- centroid: normalized.centroid,
74
- kinks: normalized.kinks
75
- };
76
- }
77
-
78
- function normalizeWeightBuffer(compiled: Compiled): WeightBufferBD {
79
- if (!compiled.version || compiled.version < FORMAT_VERSION) {
80
- return (["forw", "bakw"] as BiDirectionKey[]).reduce((bd, forb) => {
81
- const base = compiled.weight_buffer[forb];
82
- if (base) {
83
- bd[forb] = Object.keys(base).reduce((buffer, key) => {
84
- const normKey = normalizeNodeKey(key);
85
- buffer[normKey] = base[key];
86
- return buffer;
87
- }, {} as WeightBuffer);
88
- }
89
- return bd;
90
- }, {} as WeightBufferBD);
91
- }
92
- return compiled.weight_buffer;
93
- }
94
-
95
- function deriveStrictStatus(compiled: Compiled): StrictStatus {
96
- if (compiled.strict_status) return compiled.strict_status;
97
- if (compiled.kinks_points) return "strict_error";
98
- if (compiled.tins_points.length === 2) return "loose";
99
- return "strict";
100
- }
101
-
102
- function buildVerticesParams(compiled: Compiled): VerticesParamsBD {
103
- const params: VerticesParamsBD = {
104
- forw: [compiled.vertices_params[0]],
105
- bakw: [compiled.vertices_params[1]]
106
- };
107
- params.forw![1] = buildVertexTins(compiled, false);
108
- params.bakw![1] = buildVertexTins(compiled, true);
109
- return params;
110
- }
111
-
112
- function buildVertexTins(compiled: Compiled, bakw: boolean) {
113
- return [0, 1, 2, 3].map(idx => {
114
- const idxNxt = (idx + 1) % 4;
115
- const tri = indexesToTri(
116
- ["c", `b${idx}`, `b${idxNxt}`],
117
- compiled.points,
118
- compiled.edgeNodes || [],
119
- compiled.centroid_point,
120
- compiled.vertices_points,
121
- bakw,
122
- FORMAT_VERSION
123
- );
124
- return featureCollection([tri]);
125
- });
126
- }
127
-
128
- function buildCentroid(compiled: Compiled) {
129
- return {
130
- forw: point(compiled.centroid_point[0], {
131
- target: {
132
- geom: compiled.centroid_point[1],
133
- index: "c"
134
- }
135
- }),
136
- bakw: point(compiled.centroid_point[1], {
137
- target: {
138
- geom: compiled.centroid_point[0],
139
- index: "c"
140
- }
141
- })
142
- };
143
- }
144
-
145
- function buildTins(compiled: Compiled) {
146
- const bakwIndex = compiled.tins_points.length === 1 ? 0 : 1;
147
- return {
148
- forw: featureCollection(
149
- compiled.tins_points[0].map(idxes =>
150
- indexesToTri(
151
- idxes,
152
- compiled.points,
153
- compiled.edgeNodes || [],
154
- compiled.centroid_point,
155
- compiled.vertices_points,
156
- false,
157
- compiled.version
158
- )
159
- )
160
- ),
161
- bakw: featureCollection(
162
- compiled.tins_points[bakwIndex].map(idxes =>
163
- indexesToTri(
164
- idxes,
165
- compiled.points,
166
- compiled.edgeNodes || [],
167
- compiled.centroid_point,
168
- compiled.vertices_points,
169
- true,
170
- compiled.version
171
- )
172
- )
173
- )
174
- };
175
- }
176
-
177
- function buildKinks(kinksPoints?: Position[]) {
178
- if (!kinksPoints) return undefined;
179
- return {
180
- bakw: featureCollection(
181
- kinksPoints.map((coord: Position) => point(coord))
182
- )
183
- };
184
- }
185
-
186
- function normalizeLegacyStructure(
187
- compiled: CompiledLegacy
188
- ): CompiledLegacy {
189
- return JSON.parse(
190
- JSON.stringify(compiled)
191
- .replace('"cent"', '"c"')
192
- .replace(/"bbox(\d+)"/g, '"b$1"')
193
- );
194
- }
195
-
196
- function rebuildLegacyPoints(tins: TinsBD): PointSet[] {
197
- const points: PointSet[] = [];
198
- const features = tins.forw!.features;
199
- for (let i = 0; i < features.length; i++) {
200
- const tri = features[i];
201
- (["a", "b", "c"] as PropertyTriKey[]).map((key, idx) => {
202
- const forw = tri.geometry!.coordinates[0][idx];
203
- const bakw = tri.properties![key].geom;
204
- const pIdx = tri.properties![key].index;
205
- if (typeof pIdx === "number") {
206
- points[pIdx] = [forw, bakw];
207
- }
208
- });
209
- }
210
- return points;
211
- }
1
+ import { featureCollection, point } from "@turf/turf";
2
+ import type { Position } from "geojson";
3
+ import { normalizeEdges } from "./edgeutils.ts";
4
+ import { indexesToTri, normalizeNodeKey } from "./triangulation.ts";
5
+ import type { PropertyTriKey } from "./geometry.ts";
6
+ import type {
7
+ BiDirectionKey,
8
+ Compiled,
9
+ CompiledLegacy,
10
+ LegacyStatePayload,
11
+ ModernStatePayload,
12
+ PointSet,
13
+ StrictStatus,
14
+ TinsBD,
15
+ VerticesParamsBD,
16
+ WeightBufferBD
17
+ } from "./types.ts";
18
+ import type { WeightBuffer } from "./geometry.ts";
19
+
20
+ export const FORMAT_VERSION = 2.00703;
21
+
22
+ /**
23
+ * Type guard for discriminating modern compiled payloads.
24
+ */
25
+ export function isModernCompiled(
26
+ compiled: Compiled | CompiledLegacy
27
+ ): compiled is Compiled {
28
+ return Boolean(
29
+ compiled.version ||
30
+ (!(compiled as CompiledLegacy).tins && compiled.points && compiled.tins_points)
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Restore the in-memory state produced by modern compiled payloads.
36
+ */
37
+ export function restoreModernState(compiled: Compiled): ModernStatePayload {
38
+ return {
39
+ points: compiled.points,
40
+ pointsWeightBuffer: normalizeWeightBuffer(compiled),
41
+ strictStatus: deriveStrictStatus(compiled),
42
+ verticesParams: buildVerticesParams(compiled),
43
+ centroid: buildCentroid(compiled),
44
+ edges: normalizeEdges(compiled.edges || []),
45
+ edgeNodes: compiled.edgeNodes || [],
46
+ tins: buildTins(compiled),
47
+ kinks: buildKinks(compiled.kinks_points),
48
+ yaxisMode: compiled.yaxisMode ?? "invert",
49
+ strictMode: compiled.strictMode ?? "auto",
50
+ vertexMode: compiled.vertexMode,
51
+ bounds: compiled.bounds,
52
+ boundsPolygon: compiled.boundsPolygon,
53
+ wh: compiled.wh,
54
+ xy: compiled.bounds ? compiled.xy : [0, 0]
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Restore the in-memory state produced by the legacy payloads.
60
+ */
61
+ export function restoreLegacyState(
62
+ rawCompiled: CompiledLegacy
63
+ ): LegacyStatePayload {
64
+ const normalized = normalizeLegacyStructure(rawCompiled);
65
+ const tins = normalized.tins!;
66
+ return {
67
+ compiled: normalized,
68
+ tins,
69
+ points: rebuildLegacyPoints(tins),
70
+ strictStatus: normalized.strict_status,
71
+ pointsWeightBuffer: normalized.weight_buffer,
72
+ verticesParams: normalized.vertices_params as VerticesParamsBD,
73
+ centroid: normalized.centroid,
74
+ kinks: normalized.kinks
75
+ };
76
+ }
77
+
78
+ function normalizeWeightBuffer(compiled: Compiled): WeightBufferBD {
79
+ if (!compiled.version || compiled.version < FORMAT_VERSION) {
80
+ return (["forw", "bakw"] as BiDirectionKey[]).reduce((bd, forb) => {
81
+ const base = compiled.weight_buffer[forb];
82
+ if (base) {
83
+ bd[forb] = Object.keys(base).reduce((buffer, key) => {
84
+ const normKey = normalizeNodeKey(key);
85
+ buffer[normKey] = base[key];
86
+ return buffer;
87
+ }, {} as WeightBuffer);
88
+ }
89
+ return bd;
90
+ }, {} as WeightBufferBD);
91
+ }
92
+ return compiled.weight_buffer;
93
+ }
94
+
95
+ function deriveStrictStatus(compiled: Compiled): StrictStatus {
96
+ if (compiled.strict_status) return compiled.strict_status;
97
+ if (compiled.kinks_points) return "strict_error";
98
+ if (compiled.tins_points.length === 2) return "loose";
99
+ return "strict";
100
+ }
101
+
102
+ function buildVerticesParams(compiled: Compiled): VerticesParamsBD {
103
+ const params: VerticesParamsBD = {
104
+ forw: [compiled.vertices_params[0]],
105
+ bakw: [compiled.vertices_params[1]]
106
+ };
107
+ params.forw![1] = buildVertexTins(compiled, false);
108
+ params.bakw![1] = buildVertexTins(compiled, true);
109
+ return params;
110
+ }
111
+
112
+ function buildVertexTins(compiled: Compiled, bakw: boolean) {
113
+ return [0, 1, 2, 3].map(idx => {
114
+ const idxNxt = (idx + 1) % 4;
115
+ const tri = indexesToTri(
116
+ ["c", `b${idx}`, `b${idxNxt}`],
117
+ compiled.points,
118
+ compiled.edgeNodes || [],
119
+ compiled.centroid_point,
120
+ compiled.vertices_points,
121
+ bakw,
122
+ FORMAT_VERSION
123
+ );
124
+ return featureCollection([tri]);
125
+ });
126
+ }
127
+
128
+ function buildCentroid(compiled: Compiled) {
129
+ return {
130
+ forw: point(compiled.centroid_point[0], {
131
+ target: {
132
+ geom: compiled.centroid_point[1],
133
+ index: "c"
134
+ }
135
+ }),
136
+ bakw: point(compiled.centroid_point[1], {
137
+ target: {
138
+ geom: compiled.centroid_point[0],
139
+ index: "c"
140
+ }
141
+ })
142
+ };
143
+ }
144
+
145
+ function buildTins(compiled: Compiled) {
146
+ const bakwIndex = compiled.tins_points.length === 1 ? 0 : 1;
147
+ return {
148
+ forw: featureCollection(
149
+ compiled.tins_points[0].map(idxes =>
150
+ indexesToTri(
151
+ idxes,
152
+ compiled.points,
153
+ compiled.edgeNodes || [],
154
+ compiled.centroid_point,
155
+ compiled.vertices_points,
156
+ false,
157
+ compiled.version
158
+ )
159
+ )
160
+ ),
161
+ bakw: featureCollection(
162
+ compiled.tins_points[bakwIndex].map(idxes =>
163
+ indexesToTri(
164
+ idxes,
165
+ compiled.points,
166
+ compiled.edgeNodes || [],
167
+ compiled.centroid_point,
168
+ compiled.vertices_points,
169
+ true,
170
+ compiled.version
171
+ )
172
+ )
173
+ )
174
+ };
175
+ }
176
+
177
+ function buildKinks(kinksPoints?: Position[]) {
178
+ if (!kinksPoints) return undefined;
179
+ return {
180
+ bakw: featureCollection(
181
+ kinksPoints.map((coord: Position) => point(coord))
182
+ )
183
+ };
184
+ }
185
+
186
+ function normalizeLegacyStructure(
187
+ compiled: CompiledLegacy
188
+ ): CompiledLegacy {
189
+ return JSON.parse(
190
+ JSON.stringify(compiled)
191
+ .replace('"cent"', '"c"')
192
+ .replace(/"bbox(\d+)"/g, '"b$1"')
193
+ );
194
+ }
195
+
196
+ function rebuildLegacyPoints(tins: TinsBD): PointSet[] {
197
+ const points: PointSet[] = [];
198
+ const features = tins.forw!.features;
199
+ for (let i = 0; i < features.length; i++) {
200
+ const tri = features[i];
201
+ (["a", "b", "c"] as PropertyTriKey[]).map((key, idx) => {
202
+ const forw = tri.geometry!.coordinates[0][idx];
203
+ const bakw = tri.properties![key].geom;
204
+ const pIdx = tri.properties![key].index;
205
+ if (typeof pIdx === "number") {
206
+ points[pIdx] = [forw, bakw];
207
+ }
208
+ });
209
+ }
210
+ return points;
211
+ }