@maplat/transform 0.2.3 → 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,180 +1,180 @@
1
- import { polygon } from "@turf/helpers";
2
- import type { Position } from "geojson";
3
- import { PropertyTriKey, Tri, Tins } from "./geometry.ts";
4
-
5
- /**
6
- * 三角形の頂点の順序を修正する
7
- * 地図外郭の頂点を含む三角形について、頂点の順序を統一する
8
- * @param tins 三角形群
9
- * @returns 頂点順序が修正された三角形群
10
- */
11
- function rotateVerticesTriangle(tins: Tins): Tins {
12
- const features = tins.features;
13
- for (let i = 0; i < features.length; i++) {
14
- const feature = features[i];
15
- if (
16
- `${feature.properties!.a.index}`.substring(0, 1) === "b" &&
17
- `${feature.properties!.b.index}`.substring(0, 1) === "b"
18
- ) {
19
- features[i] = {
20
- geometry: {
21
- type: "Polygon",
22
- coordinates: [
23
- [
24
- feature.geometry!.coordinates[0][2],
25
- feature.geometry!.coordinates[0][0],
26
- feature.geometry!.coordinates[0][1],
27
- feature.geometry!.coordinates[0][2]
28
- ]
29
- ]
30
- },
31
- properties: {
32
- a: {
33
- geom: feature.properties!.c.geom,
34
- index: feature.properties!.c.index
35
- },
36
- b: {
37
- geom: feature.properties!.a.geom,
38
- index: feature.properties!.a.index
39
- },
40
- c: {
41
- geom: feature.properties!.b.geom,
42
- index: feature.properties!.b.index
43
- }
44
- },
45
- type: "Feature"
46
- };
47
- } else if (
48
- `${feature.properties!.c.index}`.substring(0, 1) === "b" &&
49
- `${feature.properties!.a.index}`.substring(0, 1) === "b"
50
- ) {
51
- features[i] = {
52
- geometry: {
53
- type: "Polygon",
54
- coordinates: [
55
- [
56
- feature.geometry!.coordinates[0][1],
57
- feature.geometry!.coordinates[0][2],
58
- feature.geometry!.coordinates[0][0],
59
- feature.geometry!.coordinates[0][1]
60
- ]
61
- ]
62
- },
63
- properties: {
64
- a: {
65
- geom: feature.properties!.b.geom,
66
- index: feature.properties!.b.index
67
- },
68
- b: {
69
- geom: feature.properties!.c.geom,
70
- index: feature.properties!.c.index
71
- },
72
- c: {
73
- geom: feature.properties!.a.geom,
74
- index: feature.properties!.a.index
75
- }
76
- },
77
- type: "Feature"
78
- };
79
- }
80
- }
81
- return tins;
82
- }
83
-
84
- /**
85
- * 三角形の頂点の座標系を反転する
86
- * @param tri 元の三角形
87
- * @returns 座標系が反転された三角形
88
- */
89
- function counterTri(tri: Tri): Tri {
90
- const coordinates = (["a", "b", "c", "a"] as PropertyTriKey[]).map(
91
- key => tri.properties![key].geom
92
- );
93
- const geoms = tri.geometry!.coordinates[0];
94
- const props = tri.properties!;
95
- const properties = {
96
- a: { geom: geoms[0], index: props["a"].index },
97
- b: { geom: geoms[1], index: props["b"].index },
98
- c: { geom: geoms[2], index: props["c"].index }
99
- };
100
- return polygon([coordinates], properties);
101
- }
102
-
103
- /**
104
- * 頂点座標群から三角形を生成する
105
- * @param points 頂点座標群 [座標, インデックス][]
106
- * @returns 生成された三角形
107
- */
108
- function buildTri(points: [Position[], string | number][]): Tri {
109
- const coordinates = [0, 1, 2, 0].map(i => points[i][0][0]);
110
- const properties = {
111
- a: { geom: points[0][0][1], index: points[0][1] },
112
- b: { geom: points[1][0][1], index: points[1][1] },
113
- c: { geom: points[2][0][1], index: points[2][1] }
114
- };
115
- return polygon([coordinates], properties);
116
- }
117
-
118
- /**
119
- * インデックス配列から三角形を生成する
120
- * @param indexes インデックス配列
121
- * @param points 点群座標
122
- * @param edgeNodes エッジノード座標
123
- * @param cent 重心座標
124
- * @param bboxes バウンディングボックス座標
125
- * @param bakw 座標系を反転するかどうか
126
- * @param version バージョン番号(オプション)
127
- * @returns 生成された三角形
128
- */
129
- function indexesToTri(
130
- indexes: (number | string)[],
131
- points: Position[][],
132
- edgeNodes: Position[][],
133
- cent: Position[],
134
- bboxes: Position[][],
135
- bakw = false,
136
- version?: number
137
- ): Tri {
138
- const points_: [Position[], string | number][] = indexes.map(
139
- (index: number | string) => {
140
- if (!version || version < 2.00703) index = normalizeNodeKey(index);
141
- const point_base = isFinite(index as number)
142
- ? points[index as number]
143
- : index === "c"
144
- ? cent
145
- : index === "b0"
146
- ? bboxes[0]
147
- : index === "b1"
148
- ? bboxes[1]
149
- : index === "b2"
150
- ? bboxes[2]
151
- : index === "b3"
152
- ? bboxes[3]
153
- : (function () {
154
- const match = (index as string).match(/e(\d+)/);
155
- if (match) {
156
- const nodeIndex = parseInt(match[1]);
157
- return edgeNodes[nodeIndex];
158
- }
159
- throw "Bad index value for indexesToTri";
160
- })();
161
- return bakw
162
- ? [[point_base![1], point_base![0]], index]
163
- : [[point_base![0], point_base![1]], index];
164
- }
165
- );
166
- return buildTri(points_);
167
- }
168
-
169
- // After 7.0.3 Normalizing node index key
170
- function normalizeNodeKey(index: number | string) {
171
- if (typeof index === "number") return index;
172
- return index.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/, "$1$2");
173
- }
174
-
175
- export {
176
- rotateVerticesTriangle,
177
- counterTri,
178
- indexesToTri,
179
- normalizeNodeKey
1
+ import { polygon } from "@turf/turf";
2
+ import type { Position } from "geojson";
3
+ import { PropertyTriKey, Tri, Tins } from "./geometry.ts";
4
+
5
+ /**
6
+ * 三角形の頂点の順序を修正する
7
+ * 地図外郭の頂点を含む三角形について、頂点の順序を統一する
8
+ * @param tins 三角形群
9
+ * @returns 頂点順序が修正された三角形群
10
+ */
11
+ function rotateVerticesTriangle(tins: Tins): Tins {
12
+ const features = tins.features;
13
+ for (let i = 0; i < features.length; i++) {
14
+ const feature = features[i];
15
+ if (
16
+ `${feature.properties!.a.index}`.substring(0, 1) === "b" &&
17
+ `${feature.properties!.b.index}`.substring(0, 1) === "b"
18
+ ) {
19
+ features[i] = {
20
+ geometry: {
21
+ type: "Polygon",
22
+ coordinates: [
23
+ [
24
+ feature.geometry!.coordinates[0][2],
25
+ feature.geometry!.coordinates[0][0],
26
+ feature.geometry!.coordinates[0][1],
27
+ feature.geometry!.coordinates[0][2]
28
+ ]
29
+ ]
30
+ },
31
+ properties: {
32
+ a: {
33
+ geom: feature.properties!.c.geom,
34
+ index: feature.properties!.c.index
35
+ },
36
+ b: {
37
+ geom: feature.properties!.a.geom,
38
+ index: feature.properties!.a.index
39
+ },
40
+ c: {
41
+ geom: feature.properties!.b.geom,
42
+ index: feature.properties!.b.index
43
+ }
44
+ },
45
+ type: "Feature"
46
+ };
47
+ } else if (
48
+ `${feature.properties!.c.index}`.substring(0, 1) === "b" &&
49
+ `${feature.properties!.a.index}`.substring(0, 1) === "b"
50
+ ) {
51
+ features[i] = {
52
+ geometry: {
53
+ type: "Polygon",
54
+ coordinates: [
55
+ [
56
+ feature.geometry!.coordinates[0][1],
57
+ feature.geometry!.coordinates[0][2],
58
+ feature.geometry!.coordinates[0][0],
59
+ feature.geometry!.coordinates[0][1]
60
+ ]
61
+ ]
62
+ },
63
+ properties: {
64
+ a: {
65
+ geom: feature.properties!.b.geom,
66
+ index: feature.properties!.b.index
67
+ },
68
+ b: {
69
+ geom: feature.properties!.c.geom,
70
+ index: feature.properties!.c.index
71
+ },
72
+ c: {
73
+ geom: feature.properties!.a.geom,
74
+ index: feature.properties!.a.index
75
+ }
76
+ },
77
+ type: "Feature"
78
+ };
79
+ }
80
+ }
81
+ return tins;
82
+ }
83
+
84
+ /**
85
+ * 三角形の頂点の座標系を反転する
86
+ * @param tri 元の三角形
87
+ * @returns 座標系が反転された三角形
88
+ */
89
+ function counterTri(tri: Tri): Tri {
90
+ const coordinates = (["a", "b", "c", "a"] as PropertyTriKey[]).map(
91
+ key => tri.properties![key].geom
92
+ );
93
+ const geoms = tri.geometry!.coordinates[0];
94
+ const props = tri.properties!;
95
+ const properties = {
96
+ a: { geom: geoms[0], index: props["a"].index },
97
+ b: { geom: geoms[1], index: props["b"].index },
98
+ c: { geom: geoms[2], index: props["c"].index }
99
+ };
100
+ return polygon([coordinates], properties);
101
+ }
102
+
103
+ /**
104
+ * 頂点座標群から三角形を生成する
105
+ * @param points 頂点座標群 [座標, インデックス][]
106
+ * @returns 生成された三角形
107
+ */
108
+ function buildTri(points: [Position[], string | number][]): Tri {
109
+ const coordinates = [0, 1, 2, 0].map(i => points[i][0][0]);
110
+ const properties = {
111
+ a: { geom: points[0][0][1], index: points[0][1] },
112
+ b: { geom: points[1][0][1], index: points[1][1] },
113
+ c: { geom: points[2][0][1], index: points[2][1] }
114
+ };
115
+ return polygon([coordinates], properties);
116
+ }
117
+
118
+ /**
119
+ * インデックス配列から三角形を生成する
120
+ * @param indexes インデックス配列
121
+ * @param points 点群座標
122
+ * @param edgeNodes エッジノード座標
123
+ * @param cent 重心座標
124
+ * @param bboxes バウンディングボックス座標
125
+ * @param bakw 座標系を反転するかどうか
126
+ * @param version バージョン番号(オプション)
127
+ * @returns 生成された三角形
128
+ */
129
+ function indexesToTri(
130
+ indexes: (number | string)[],
131
+ points: Position[][],
132
+ edgeNodes: Position[][],
133
+ cent: Position[],
134
+ bboxes: Position[][],
135
+ bakw = false,
136
+ version?: number
137
+ ): Tri {
138
+ const points_: [Position[], string | number][] = indexes.map(
139
+ (index: number | string) => {
140
+ if (!version || version < 2.00703) index = normalizeNodeKey(index);
141
+ const point_base = isFinite(index as number)
142
+ ? points[index as number]
143
+ : index === "c"
144
+ ? cent
145
+ : index === "b0"
146
+ ? bboxes[0]
147
+ : index === "b1"
148
+ ? bboxes[1]
149
+ : index === "b2"
150
+ ? bboxes[2]
151
+ : index === "b3"
152
+ ? bboxes[3]
153
+ : (function () {
154
+ const match = (index as string).match(/e(\d+)/);
155
+ if (match) {
156
+ const nodeIndex = parseInt(match[1]);
157
+ return edgeNodes[nodeIndex];
158
+ }
159
+ throw "Bad index value for indexesToTri";
160
+ })();
161
+ return bakw
162
+ ? [[point_base![1], point_base![0]], index]
163
+ : [[point_base![0], point_base![1]], index];
164
+ }
165
+ );
166
+ return buildTri(points_);
167
+ }
168
+
169
+ // After 7.0.3 Normalizing node index key
170
+ function normalizeNodeKey(index: number | string) {
171
+ if (typeof index === "number") return index;
172
+ return index.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/, "$1$2");
173
+ }
174
+
175
+ export {
176
+ rotateVerticesTriangle,
177
+ counterTri,
178
+ indexesToTri,
179
+ normalizeNodeKey
180
180
  };
package/src/types.ts ADDED
@@ -0,0 +1,122 @@
1
+ import type { Feature, FeatureCollection, Polygon, Point, Position } from "geojson";
2
+ import type {
3
+ IndexedTins,
4
+ Tins,
5
+ VerticesParams,
6
+ WeightBuffer
7
+ } from "./geometry.ts";
8
+ import type { EdgeSet, EdgeSetLegacy } from "./edgeutils.ts";
9
+
10
+ /**
11
+ * Two-way coordinate pair: [source, target].
12
+ */
13
+ export type PointSet = [Position, Position];
14
+
15
+ /**
16
+ * Directional selector shared across the codebase.
17
+ */
18
+ export type BiDirectionKey = "forw" | "bakw";
19
+
20
+ /**
21
+ * Weight buffers indexed by node id for both directions.
22
+ */
23
+ export type WeightBufferBD = { [key in BiDirectionKey]?: WeightBuffer };
24
+
25
+ /**
26
+ * Vertex interpolation modes.
27
+ */
28
+ export type VertexMode = "plain" | "birdeye";
29
+
30
+ /**
31
+ * Strictness flags supported during transformation.
32
+ */
33
+ export type StrictMode = "strict" | "auto" | "loose";
34
+
35
+ /**
36
+ * Result of strictness evaluation.
37
+ */
38
+ export type StrictStatus = "strict" | "strict_error" | "loose";
39
+
40
+ /**
41
+ * Y-axis handling directive.
42
+ */
43
+ export type YaxisMode = "follow" | "invert";
44
+
45
+ export type Centroid = Feature<Point>;
46
+ export type CentroidBD = { [key in BiDirectionKey]?: Centroid };
47
+ export type TinsBD = { [key in BiDirectionKey]?: Tins };
48
+ export type Kinks = FeatureCollection<Point>;
49
+ export type KinksBD = { [key in BiDirectionKey]?: Kinks };
50
+ export type VerticesParamsBD = { [key in BiDirectionKey]?: VerticesParams };
51
+ export type IndexedTinsBD = { [key in BiDirectionKey]?: IndexedTins };
52
+
53
+ /**
54
+ * Serialized structure generated by MaplatTin and consumed by Transform.
55
+ */
56
+ export interface Compiled {
57
+ version?: number;
58
+ points: PointSet[];
59
+ tins_points: (number | string)[][][];
60
+ weight_buffer: WeightBufferBD;
61
+ strict_status?: StrictStatus;
62
+ centroid_point: Position[];
63
+ edgeNodes?: PointSet[];
64
+ kinks_points?: Position[];
65
+ yaxisMode?: YaxisMode;
66
+ vertexMode?: VertexMode;
67
+ strictMode?: StrictMode;
68
+ vertices_params: number[][];
69
+ vertices_points: PointSet[];
70
+ edges: EdgeSet[];
71
+ bounds?: number[][];
72
+ boundsPolygon?: Feature<Polygon>;
73
+ wh?: number[];
74
+ xy?: number[];
75
+ }
76
+
77
+ /**
78
+ * Historical serialization format prior to 2.00703.
79
+ */
80
+ export interface CompiledLegacy extends Compiled {
81
+ tins?: TinsBD;
82
+ centroid?: CentroidBD;
83
+ kinks?: KinksBD;
84
+ vertices_params: number[][] & VerticesParamsBD;
85
+ edges: EdgeSet[] & EdgeSetLegacy[];
86
+ }
87
+
88
+ /**
89
+ * Normalized state derived from modern compiled payloads.
90
+ */
91
+ export interface ModernStatePayload {
92
+ points: PointSet[];
93
+ pointsWeightBuffer: WeightBufferBD;
94
+ strictStatus: StrictStatus;
95
+ verticesParams: VerticesParamsBD;
96
+ centroid: CentroidBD;
97
+ edges: EdgeSet[];
98
+ edgeNodes?: PointSet[];
99
+ tins: TinsBD;
100
+ kinks?: KinksBD;
101
+ yaxisMode: YaxisMode;
102
+ strictMode: StrictMode;
103
+ vertexMode?: VertexMode;
104
+ bounds?: number[][];
105
+ boundsPolygon?: Feature<Polygon>;
106
+ wh?: number[];
107
+ xy?: number[];
108
+ }
109
+
110
+ /**
111
+ * Normalized snapshot captured from legacy payloads.
112
+ */
113
+ export interface LegacyStatePayload {
114
+ compiled: CompiledLegacy;
115
+ tins: TinsBD;
116
+ points: PointSet[];
117
+ strictStatus?: StrictStatus;
118
+ pointsWeightBuffer: WeightBufferBD;
119
+ verticesParams: VerticesParamsBD;
120
+ centroid?: CentroidBD;
121
+ kinks?: KinksBD;
122
+ }
package/dist/index.html DELETED
@@ -1,39 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="ja">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>MaplatTransform Test</title>
6
- </head>
7
- <body>
8
- <h1>MaplatTransform Test</h1>
9
- <div id="output"></div>
10
- <script type="module">
11
- import { Transform as Tin } from '/src/index.ts';
12
-
13
- const tin = new Tin({
14
- bounds: [[100, 50], [150, 150], [150, 200], [60, 190], [50, 100]],
15
- strictMode: Tin.MODE_STRICT
16
- });
17
-
18
- tin.setPoints([
19
- [[80, 90], [160, -90]],
20
- [[120, 120], [240, -120]],
21
- [[100, 140], [200, -140]],
22
- [[130, 180], [260, -180]],
23
- [[70, 150], [140, -150]]
24
- ]);
25
-
26
- tin.updateTinAsync().then(() => {
27
- const output = document.getElementById('output');
28
- const result1 = tin.transform([140, 150]);
29
- const result2 = tin.transform(result1, true);
30
-
31
- output.innerHTML = `
32
- <h2>Test Results:</h2>
33
- <p>Forward transform [140, 150] => [${result1.join(', ')}]</p>
34
- <p>Backward transform [${result1.join(', ')}] => [${result2.join(', ')}]</p>
35
- `;
36
- });
37
- </script>
38
- </body>
39
- </html>
@@ -1 +0,0 @@
1
- "use strict";var ft=Object.defineProperty;var ct=(e,t,s)=>t in e?ft(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var _=(e,t,s)=>ct(e,typeof t!="symbol"?t+"":t,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=11102230246251565e-32,S=134217729,ut=(3+8*R)*R;function V(e,t,s,r,a){let n,c,l,g,d=t[0],y=r[0],o=0,u=0;y>d==y>-d?(n=d,d=t[++o]):(n=y,y=r[++u]);let b=0;if(o<e&&u<s)for(y>d==y>-d?(c=d+n,l=n-(c-d),d=t[++o]):(c=y+n,l=n-(c-y),y=r[++u]),n=c,l!==0&&(a[b++]=l);o<e&&u<s;)y>d==y>-d?(c=n+d,g=c-n,l=n-(c-g)+(d-g),d=t[++o]):(c=n+y,g=c-n,l=n-(c-g)+(y-g),y=r[++u]),n=c,l!==0&&(a[b++]=l);for(;o<e;)c=n+d,g=c-n,l=n-(c-g)+(d-g),d=t[++o],n=c,l!==0&&(a[b++]=l);for(;u<s;)c=n+y,g=c-n,l=n-(c-g)+(y-g),y=r[++u],n=c,l!==0&&(a[b++]=l);return(n!==0||b===0)&&(a[b++]=n),b}function ht(e,t){let s=t[0];for(let r=1;r<e;r++)s+=t[r];return s}function $(e){return new Float64Array(e)}const gt=(3+16*R)*R,lt=(2+12*R)*R,dt=(9+64*R)*R*R,F=$(4),G=$(8),j=$(12),z=$(16),P=$(4);function yt(e,t,s,r,a,n,c){let l,g,d,y,o,u,b,x,h,f,i,w,v,A,E,m,M,O;const I=e-a,p=s-a,k=t-n,N=r-n;A=I*N,u=S*I,b=u-(u-I),x=I-b,u=S*N,h=u-(u-N),f=N-h,E=x*f-(A-b*h-x*h-b*f),m=k*p,u=S*k,b=u-(u-k),x=k-b,u=S*p,h=u-(u-p),f=p-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,F[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,F[1]=v-(i+o)+(o-m),O=w+i,o=O-w,F[2]=w-(O-o)+(i-o),F[3]=O;let U=ht(4,F),X=lt*c;if(U>=X||-U>=X||(o=e-I,l=e-(I+o)+(o-a),o=s-p,d=s-(p+o)+(o-a),o=t-k,g=t-(k+o)+(o-n),o=r-N,y=r-(N+o)+(o-n),l===0&&g===0&&d===0&&y===0)||(X=dt*c+ut*Math.abs(U),U+=I*y+N*l-(k*d+p*g),U>=X||-U>=X))return U;A=l*N,u=S*l,b=u-(u-l),x=l-b,u=S*N,h=u-(u-N),f=N-h,E=x*f-(A-b*h-x*h-b*f),m=g*p,u=S*g,b=u-(u-g),x=g-b,u=S*p,h=u-(u-p),f=p-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,P[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,P[1]=v-(i+o)+(o-m),O=w+i,o=O-w,P[2]=w-(O-o)+(i-o),P[3]=O;const it=V(4,F,4,P,G);A=I*y,u=S*I,b=u-(u-I),x=I-b,u=S*y,h=u-(u-y),f=y-h,E=x*f-(A-b*h-x*h-b*f),m=k*d,u=S*k,b=u-(u-k),x=k-b,u=S*d,h=u-(u-d),f=d-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,P[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,P[1]=v-(i+o)+(o-m),O=w+i,o=O-w,P[2]=w-(O-o)+(i-o),P[3]=O;const ot=V(it,G,4,P,j);A=l*y,u=S*l,b=u-(u-l),x=l-b,u=S*y,h=u-(u-y),f=y-h,E=x*f-(A-b*h-x*h-b*f),m=g*d,u=S*g,b=u-(u-g),x=g-b,u=S*d,h=u-(u-d),f=d-h,M=x*f-(m-b*h-x*h-b*f),i=E-M,o=E-i,P[0]=E-(i+o)+(o-M),w=A+i,o=w-A,v=A-(w-o)+(i-o),i=v-m,o=v-i,P[1]=v-(i+o)+(o-m),O=w+i,o=O-w,P[2]=w-(O-o)+(i-o),P[3]=O;const at=V(ot,j,4,P,z);return z[at-1]}function bt(e,t,s,r,a,n){const c=(t-n)*(s-a),l=(e-a)*(r-n),g=c-l,d=Math.abs(c+l);return Math.abs(g)>=gt*d?g:-yt(e,t,s,r,a,n,d)}function wt(e,t){var s,r,a=0,n,c,l,g,d,y,o,u=e[0],b=e[1],x=t.length;for(s=0;s<x;s++){r=0;var h=t[s],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,l=y[1]-b,r;r<f;r++){if(o=h[r+1],g=o[0]-u,d=o[1]-b,l===0&&d===0){if(g<=0&&c>=0||c<=0&&g>=0)return 0}else if(d>=0&&l<=0||d<=0&&l>=0){if(n=bt(c,g,l,d,0,0),n===0)return 0;(n>0&&d>0&&l<=0||n<0&&d<=0&&l>0)&&a++}y=o,l=d,c=g}}return a%2!==0}function Z(e,t,s={}){const r={type:"Feature"};return(s.id===0||s.id)&&(r.id=s.id),s.bbox&&(r.bbox=s.bbox),r.properties=t||{},r.geometry=e,r}function Y(e,t,s={}){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(!J(e[0])||!J(e[1]))throw new Error("coordinates must contain numbers");return Z({type:"Point",coordinates:e},t,s)}function tt(e,t,s={}){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 n=0;n<a[a.length-1].length;n++)if(a[a.length-1][n]!==a[0][n])throw new Error("First and last Position are not equivalent.")}return Z({type:"Polygon",coordinates:e},t,s)}function B(e,t={}){const s={type:"FeatureCollection"};return t.id&&(s.id=t.id),t.bbox&&(s.bbox=t.bbox),s.features=e,s}function J(e){return!isNaN(e)&&e!==null&&!Array.isArray(e)}function mt(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 K(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 xt(e){return e.type==="Feature"?e.geometry:e}function _t(e,t,s={}){if(!e)throw new Error("point is required");if(!t)throw new Error("polygon is required");const r=mt(e),a=xt(t),n=a.type,c=t.bbox;let l=a.coordinates;if(c&&vt(r,c)===!1)return!1;n==="Polygon"&&(l=[l]);let g=!1;for(var d=0;d<l.length;++d){const y=wt(r,l[d]);if(y===0)return!s.ignoreBoundary;y&&(g=!0)}return g}function vt(e,t){return t[0]<=e[0]&&t[1]<=e[1]&&t[2]>=e[0]&&t[3]>=e[1]}var D=_t;function At(e){const t=e.features;for(let s=0;s<t.length;s++){const r=t[s];`${r.properties.a.index}`.substring(0,1)==="b"&&`${r.properties.b.index}`.substring(0,1)==="b"?t[s]={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[s]={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 Mt(e){const t=["a","b","c","a"].map(n=>e.properties[n].geom),s=e.geometry.coordinates[0],r=e.properties,a={a:{geom:s[0],index:r.a.index},b:{geom:s[1],index:r.b.index},c:{geom:s[2],index:r.c.index}};return tt([t],a)}function Et(e){const t=[0,1,2,0].map(r=>e[r][0][0]),s={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 tt([t],s)}function W(e,t,s,r,a,n=!1,c){const l=e.map(g=>{(!c||c<2.00703)&&(g=et(g));const d=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 s[o]}throw"Bad index value for indexesToTri"}();return n?[[d[1],d[0]],g]:[[d[0],d[1]],g]});return Et(l)}function et(e){return typeof e=="number"?e:e.replace(/^(c|e|b)(?:ent|dgeNode|box)(\d+)?$/,"$1$2")}function rt(e,t){return t&&t>=2.00703||Array.isArray(e[0])?e:e.map(s=>[s.illstNodes,s.mercNodes,s.startEnd])}function Q(e,t){for(let s=0;s<t.features.length;s++)if(D(e,t.features[s]))return t.features[s]}function st(e,t,s){const r=t.geometry.coordinates[0][0],a=t.geometry.coordinates[0][1],n=t.geometry.coordinates[0][2],c=e.geometry.coordinates,l=t.properties.a.geom,g=t.properties.b.geom,d=t.properties.c.geom,y=[a[0]-r[0],a[1]-r[1]],o=[n[0]-r[0],n[1]-r[1]],u=[c[0]-r[0],c[1]-r[1]],b=[g[0]-l[0],g[1]-l[1]],x=[d[0]-l[0],d[1]-l[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(s){const i=s[t.properties.a.index],w=s[t.properties.b.index],v=s[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]+l[0],h*b[1]+f*x[1]+l[1]]}function Tt(e,t,s,r){const a=e.geometry.coordinates,n=s.geometry.coordinates,c=Math.atan2(a[0]-n[0],a[1]-n[1]),l=Ot(c,t[0]);if(l===void 0)throw new Error("Unable to determine vertex index");const g=t[1][l];return st(e,g.features[0],r)}function nt(e,t,s,r,a,n,c,l){let g;if(c&&(g=Q(e,B([c]))),!g){if(s){const d=e.geometry.coordinates,y=s.gridNum,o=s.xOrigin,u=s.yOrigin,b=s.xUnit,x=s.yUnit,h=s.gridCache,f=C(d[0],o,b,y),i=C(d[1],u,x,y),w=h[f]?h[f][i]?h[f][i]:[]:[];t=B(w.map(v=>t.features[v]))}g=Q(e,t)}return l&&l(g),g?st(e,g,n):Tt(e,r,a,n)}function C(e,t,s,r){let a=Math.floor((e-t)/s);return a>=r&&(a=r-1),a}function Ot(e,t){let s=H(e-t[0]),r=Math.PI*2,a;for(let n=0;n<t.length;n++){const c=(n+1)%t.length,l=H(e-t[c]),g=Math.min(Math.abs(s),Math.abs(l));s*l<=0&&g<r&&(r=g,a=n),s=l}return a}function H(e,t=!1){const s=t?function(r){return!(r>=0&&r<Math.PI*2)}:function(r){return!(r>-1*Math.PI&&r<=Math.PI)};for(;s(e);)e=e+2*Math.PI*(e>0?-1:1);return e}const q=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 n=t.weight_buffer[a];return n&&(r[a]=Object.keys(n).reduce((c,l)=>{const g=et(l);return c[g]=n[l],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,n=W(["c",`b${r}`,`b${a}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,q);return B([n])}),this.vertices_params.bakw[1]=[0,1,2,3].map(r=>{const a=(r+1)%4,n=W(["c",`b${r}`,`b${a}`],t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,q);return B([n])}),this.centroid={forw:Y(t.centroid_point[0],{target:{geom:t.centroid_point[1],index:"c"}}),bakw:Y(t.centroid_point[1],{target:{geom:t.centroid_point[0],index:"c"}})},this.edges=rt(t.edges||[]),this.edgeNodes=t.edgeNodes||[];const s=t.tins_points.length==1?0:1;this.tins={forw:B(t.tins_points[0].map(r=>W(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!1,t.version))),bakw:B(t.tins_points[s].map(r=>W(r,t.points,t.edgeNodes||[],t.centroid_point,t.vertices_points,!0,t.version)))},this.addIndexedTin(),t.kinks_points&&(this.kinks={bakw:B(t.kinks_points.map(r=>Y(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 s=[];for(let r=0;r<this.tins.forw.features.length;r++){const a=this.tins.forw.features[r];["a","b","c"].map((n,c)=>{const l=a.geometry.coordinates[0][c],g=a.properties[n].geom,d=a.properties[n].index;typeof d=="number"&&(s[d]=[l,g])})}this.points=s}}addIndexedTin(){const t=this.tins,s=t.forw,r=t.bakw,a=Math.ceil(Math.sqrt(s.features.length));if(a<3){this.indexedTins=void 0;return}let n=[],c=[];const l=s.features.map(h=>{let f=[];return K(h)[0].map(i=>{n.length===0?n=[Array.from(i),Array.from(i)]:(i[0]<n[0][0]&&(n[0][0]=i[0]),i[0]>n[1][0]&&(n[1][0]=i[0]),i[1]<n[0][1]&&(n[0][1]=i[1]),i[1]>n[1][1]&&(n[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=(n[1][0]-n[0][0])/a,d=(n[1][1]-n[0][1])/a,y=l.reduce((h,f,i)=>{const w=C(f[0][0],n[0][0],g,a),v=C(f[1][0],n[0][0],g,a),A=C(f[0][1],n[0][1],d,a),E=C(f[1][1],n[0][1],d,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 K(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=C(f[0][0],c[0][0],u,a),v=C(f[1][0],c[0][0],u,a),A=C(f[0][1],c[0][1],b,a),E=C(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:n[0][0],yOrigin:n[0][1],xUnit:g,yUnit:d,gridCache:y},bakw:{gridNum:a,xOrigin:c[0][0],yOrigin:c[0][1],xUnit:u,yUnit:b,gridCache:x}}}transform(t,s,r){if(s&&this.strict_status==T.STATUS_ERROR)throw'Backward transform is not allowed if strict_status == "strict_error"';this.yaxisMode==T.YAXIS_FOLLOW&&s&&(t=[t[0],-1*t[1]]);const a=Y(t);if(this.bounds&&!s&&!r&&!D(a,this.boundsPolygon))return!1;const n=s?this.tins.bakw:this.tins.forw,c=s?this.indexedTins.bakw:this.indexedTins.forw,l=s?this.vertices_params.bakw:this.vertices_params.forw,g=s?this.centroid.bakw:this.centroid.forw,d=s?this.pointsWeightBuffer.bakw:this.pointsWeightBuffer.forw;let y,o;this.stateFull&&(this.stateBackward==s?y=this.stateTriangle:(this.stateBackward=s,this.stateTriangle=void 0),o=b=>{this.stateTriangle=b});let u=nt(a,n,c,l,g,d,y,o);if(this.bounds&&s&&!r){const b=Y(u);if(!D(b,this.boundsPolygon))return!1}else this.yaxisMode==T.YAXIS_FOLLOW&&!s&&(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 L=T;exports.Transform=L;exports.counterTri=Mt;exports.format_version=q;exports.normalizeEdges=rt;exports.rotateVerticesTriangle=At;exports.transformArr=nt;