@maplat/transform 0.4.1 → 0.5.1

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.
package/src/types.ts CHANGED
@@ -1,122 +1,162 @@
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
- }
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
+ }
123
+
124
+ // ─── MapTransform types ───────────────────────────────────────────────────────
125
+
126
+ /**
127
+ * Viewport representation: center in mercator, zoom level, rotation in radians.
128
+ */
129
+ export interface Viewpoint {
130
+ /** Mercator coordinate [x, y] */
131
+ center: number[];
132
+ /** Mercator zoom level */
133
+ zoom: number;
134
+ /** Rotation angle in radians */
135
+ rotation: number;
136
+ }
137
+
138
+ /**
139
+ * Sub-map TIN data for MapTransform.setMapData().
140
+ */
141
+ export interface SubMapData {
142
+ /** Compiled TIN data */
143
+ compiled: Compiled;
144
+ /** Layer priority (higher = checked first) */
145
+ priority: number;
146
+ /** Layer importance (used when multiple layers overlap) */
147
+ importance: number;
148
+ /** Bounds vertices in pixel (XY) space. Falls back to compiled.bounds if omitted. */
149
+ bounds?: number[][];
150
+ }
151
+
152
+ /**
153
+ * Input data for MapTransform.setMapData().
154
+ */
155
+ export interface MapData {
156
+ /** Compiled TIN data for the main layer */
157
+ compiled: Compiled;
158
+ /** maxZoom value used to compute _maxxy = 2^maxZoom * 256 */
159
+ maxZoom?: number;
160
+ /** Sub-map layers */
161
+ sub_maps?: SubMapData[];
162
+ }
@@ -0,0 +1,104 @@
1
+ import { MERC_MAX, MERC_CROSSMATRIX } from "./constants.ts";
2
+ import type { Viewpoint } from "./types.ts";
3
+
4
+ /**
5
+ * size(画面サイズ)とズームから、地図面座標上での半径を得る
6
+ *
7
+ * @param size - 画面サイズ [width, height]
8
+ * @param zoom - メルカトルズームレベル
9
+ * @returns メルカトル座標上での半径
10
+ */
11
+ export function zoom2Radius(size: [number, number], zoom: number): number {
12
+ const radius = Math.floor(Math.min(size[0], size[1]) / 4);
13
+ return (radius * MERC_MAX) / 128 / Math.pow(2, zoom);
14
+ }
15
+
16
+ /**
17
+ * 与えられた差分行列を回転する
18
+ *
19
+ * @param xys - 回転する座標の配列
20
+ * @param theta - 回転角(ラジアン)
21
+ * @returns 回転後の座標の配列
22
+ */
23
+ export function rotateMatrix(xys: number[][], theta: number): number[][] {
24
+ const result: number[][] = [];
25
+ for (let i = 0; i < xys.length; i++) {
26
+ const xy = xys[i];
27
+ const x = xy[0] * Math.cos(theta) - xy[1] * Math.sin(theta);
28
+ const y = xy[0] * Math.sin(theta) + xy[1] * Math.cos(theta);
29
+ result.push([x, y]);
30
+ }
31
+ return result;
32
+ }
33
+
34
+ /**
35
+ * 画面サイズと地図ズームから、メルカトル座標上での5座標を取得する
36
+ *
37
+ * @param center - 中心のメルカトル座標 [x, y]
38
+ * @param zoom - メルカトルズームレベル
39
+ * @param rotation - 回転角(ラジアン)
40
+ * @param size - 画面サイズ [width, height]
41
+ * @returns 中心+上下左右の5点のメルカトル座標配列
42
+ */
43
+ export function mercViewpoint2Mercs(
44
+ center: number[],
45
+ zoom: number,
46
+ rotation: number,
47
+ size: [number, number]
48
+ ): number[][] {
49
+ const radius = zoom2Radius(size, zoom);
50
+ const crossDelta = rotateMatrix(MERC_CROSSMATRIX, rotation);
51
+ const cross = crossDelta.map(xy => [
52
+ xy[0] * radius + center[0],
53
+ xy[1] * radius + center[1]
54
+ ]);
55
+ return cross;
56
+ }
57
+
58
+ /**
59
+ * メルカトル5地点情報からメルカトル地図でのサイズ情報(中心座標、ズーム、回転)を得る
60
+ *
61
+ * @param mercs - 中心+上下左右の5点のメルカトル座標配列
62
+ * @param size - 画面サイズ [width, height]
63
+ * @returns Viewpoint オブジェクト(center, zoom, rotation)
64
+ */
65
+ export function mercs2MercViewpoint(
66
+ mercs: number[][],
67
+ size: [number, number]
68
+ ): Viewpoint {
69
+ const center = mercs[0];
70
+ const nesw = mercs.slice(1, 5);
71
+ const neswDelta = nesw.map(val => [
72
+ val[0] - center[0],
73
+ val[1] - center[1]
74
+ ]);
75
+ const normal = [
76
+ [0.0, 1.0],
77
+ [1.0, 0.0],
78
+ [0.0, -1.0],
79
+ [-1.0, 0.0]
80
+ ];
81
+ let abss = 0;
82
+ let cosx = 0;
83
+ let sinx = 0;
84
+ for (let i = 0; i < 4; i++) {
85
+ const delta = neswDelta[i];
86
+ const norm = normal[i];
87
+ const abs = Math.sqrt(Math.pow(delta[0], 2) + Math.pow(delta[1], 2));
88
+ abss += abs;
89
+ const outer = delta[0] * norm[1] - delta[1] * norm[0];
90
+ const inner = Math.acos(
91
+ (delta[0] * norm[0] + delta[1] * norm[1]) / abs
92
+ );
93
+ const theta = outer > 0.0 ? -1.0 * inner : inner;
94
+ cosx += Math.cos(theta);
95
+ sinx += Math.sin(theta);
96
+ }
97
+ const scale = abss / 4.0;
98
+ const omega = Math.atan2(sinx, cosx);
99
+
100
+ const radius = Math.floor(Math.min(size[0], size[1]) / 4);
101
+ const zoom = Math.log((radius * MERC_MAX) / 128 / scale) / Math.log(2);
102
+
103
+ return { center, zoom, rotation: omega };
104
+ }