isard 1.6.0 → 1.8.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.
- package/CHANGELOG.md +70 -0
- package/dist/basemap/furniture.d.ts +20 -2
- package/dist/basemap/furniture.js +72 -3
- package/dist/basemap/furniture.js.map +1 -1
- package/dist/basemap/meshes.d.ts +21 -0
- package/dist/basemap/meshes.js +159 -0
- package/dist/basemap/meshes.js.map +1 -0
- package/dist/basemap/placed.d.ts +13 -0
- package/dist/basemap/placed.js +14 -0
- package/dist/basemap/placed.js.map +1 -0
- package/dist/basemap/trees.d.ts +4 -14
- package/dist/basemap/trees.js +12 -93
- package/dist/basemap/trees.js.map +1 -1
- package/dist/basemap/vectortiles/context.d.ts +4 -2
- package/dist/basemap/vectortiles/context.js.map +1 -1
- package/dist/basemap/vectortiles/extrusions.d.ts +1 -1
- package/dist/basemap/vectortiles/extrusions.js +7 -16
- package/dist/basemap/vectortiles/extrusions.js.map +1 -1
- package/dist/basemap/vectortiles/furniture.d.ts +19 -0
- package/dist/basemap/vectortiles/furniture.js +29 -0
- package/dist/basemap/vectortiles/furniture.js.map +1 -0
- package/dist/basemap/vectortiles/labels.js +8 -1
- package/dist/basemap/vectortiles/labels.js.map +1 -1
- package/dist/basemap/vectortiles/lamps.js +11 -76
- package/dist/basemap/vectortiles/lamps.js.map +1 -1
- package/dist/basemap/vectortiles/placed.d.ts +38 -0
- package/dist/basemap/vectortiles/placed.js +143 -0
- package/dist/basemap/vectortiles/placed.js.map +1 -0
- package/dist/basemap/vectortiles/street-wind.js +4 -6
- package/dist/basemap/vectortiles/street-wind.js.map +1 -1
- package/dist/basemap/vectortiles/trees.d.ts +2 -9
- package/dist/basemap/vectortiles/trees.js +34 -165
- package/dist/basemap/vectortiles/trees.js.map +1 -1
- package/dist/basemap/vectortiles/vectors.d.ts +4 -5
- package/dist/basemap/vectortiles/vectors.js +17 -16
- package/dist/basemap/vectortiles/vectors.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +14 -4
- package/dist/basemap/vectortiles.js +40 -12
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/wmts.js +2 -2
- package/dist/basemap/wmts.js.map +1 -1
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +18 -14
- package/dist/bind/layers.d.ts +10 -3
- package/dist/bind/layers.js +11 -4
- package/dist/bind/layers.js.map +1 -1
- package/dist/data/collada.js +3 -17
- package/dist/data/collada.js.map +1 -1
- package/dist/data/crs.js +1 -1
- package/dist/data/crs.js.map +1 -1
- package/dist/data/ifc.js +21 -22
- package/dist/data/ifc.js.map +1 -1
- package/dist/geoplateforme.d.ts +16 -4
- package/dist/geoplateforme.js +26 -4
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_grid_bg.wasm +0 -0
- package/dist/isard_tess_bg.wasm +0 -0
- package/dist/layers/extrusions.js +5 -4
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.d.ts +0 -2
- package/dist/layers/features.js +5 -6
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/layers.d.ts +2 -0
- package/dist/layers/layers.js +11 -0
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/panoramas.d.ts +32 -10
- package/dist/layers/panoramas.js +55 -28
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/photos.js +5 -6
- package/dist/layers/photos.js.map +1 -1
- package/dist/layers/trees.js +7 -7
- package/dist/layers/trees.js.map +1 -1
- package/dist/layers/vectors.d.ts +1 -0
- package/dist/layers/vectors.js +23 -8
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/frame-loop.d.ts +2 -0
- package/dist/map/frame-loop.js +3 -3
- package/dist/map/frame-loop.js.map +1 -1
- package/dist/map.js +17 -0
- package/dist/map.js.map +1 -1
- package/dist/panoramax.d.ts +19 -0
- package/dist/panoramax.js +48 -3
- package/dist/panoramax.js.map +1 -1
- package/dist/react/CustomLayer.js +5 -4
- package/dist/react/CustomLayer.js.map +1 -1
- package/dist/react/Layer.d.ts +1 -1
- package/dist/react/Layer.js +6 -5
- package/dist/react/Layer.js.map +1 -1
- package/dist/react/VectorGeometry.d.ts +18 -9
- package/dist/react/VectorGeometry.js +30 -15
- package/dist/react/VectorGeometry.js.map +1 -1
- package/dist/react/VectorTiles.d.ts +65 -0
- package/dist/react/VectorTiles.js +112 -0
- package/dist/react/VectorTiles.js.map +1 -0
- package/dist/react/context.d.ts +12 -0
- package/dist/react/context.js +40 -1
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +7 -1
- package/dist/react/index.js +7 -1
- package/dist/react/index.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.js.map +1 -1
- package/dist/util/geo.d.ts +8 -0
- package/dist/util/geo.js +8 -0
- package/dist/util/geo.js.map +1 -1
- package/dist/util/gltf.d.ts +18 -1
- package/dist/util/gltf.js +26 -1
- package/dist/util/gltf.js.map +1 -1
- package/dist/util/roofs.d.ts +8 -0
- package/dist/util/roofs.js +16 -2
- package/dist/util/roofs.js.map +1 -1
- package/dist/util/style-floats.d.ts +33 -0
- package/dist/util/style-floats.js +34 -0
- package/dist/util/style-floats.js.map +1 -0
- package/dist/util/sun.js +1 -1
- package/dist/util/sun.js.map +1 -1
- package/dist/workers/basemap/furniture.d.ts +13 -0
- package/dist/workers/basemap/geometry.d.ts +2 -5
- package/dist/workers/basemap/labels.d.ts +5 -2
- package/dist/workers/basemap/lamps.d.ts +3 -3
- package/dist/workers/basemap/tiles.d.ts +2 -0
- package/dist/workers/basemap/trees.d.ts +3 -0
- package/dist/workers/basemap.worker.d.ts +17 -1
- package/dist/workers/basemap.worker.js +12 -1
- package/dist/workers/basemap.worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,178 +1,47 @@
|
|
|
1
1
|
/** The trees of a vector basemap (`VectorTiles.trees`): 3D models scattered by the workers over its woods and grass */
|
|
2
|
-
import { coniferModel, isWoodland,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { coniferModel, isWoodland, treeModel, treeSpacing } from "../trees.js";
|
|
3
|
+
import { placed } from "./placed.js";
|
|
4
|
+
import { STREET_ZOOM } from "./tiles.js";
|
|
5
5
|
/** Metres around the view's center where every tree is drawn in full at zoom 16 (twice as far a zoom level out);
|
|
6
6
|
* past them, simplified (`treeModel(…, true)`) */
|
|
7
7
|
const TREES_NEAR_METRES = 350;
|
|
8
|
-
/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */
|
|
9
|
-
const FOV = 0.6435011087932844;
|
|
10
8
|
/** How much denser the simplified trees far away stay than the full ones would (four times fewer triangles each): a
|
|
11
9
|
* tree twice as far kept as often */
|
|
12
10
|
const FAR_DENSITY = 4;
|
|
13
11
|
/** The simplified trees drawn at most, for so many full ones (`maxInstances`) */
|
|
14
12
|
const FAR_INSTANCES = 3;
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
const RESEND_SHARE = 0.05;
|
|
18
|
-
/** Metres in a degree of latitude (and of longitude at the equator), near enough for the trees' distances */
|
|
19
|
-
export const METRES_PER_DEGREE = 111320;
|
|
20
|
-
/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera
|
|
21
|
-
* stands behind the center of a tilted view, `FOV` its field of view) */
|
|
22
|
-
export const groundUnderCamera = (map) => {
|
|
23
|
-
const { pitch, bearing } = map.getCamera();
|
|
24
|
-
const back = ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *
|
|
25
|
-
Math.sin((pitch * Math.PI) / 180) *
|
|
26
|
-
(map.metersPerPixel() ?? 0);
|
|
27
|
-
return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];
|
|
28
|
-
};
|
|
29
|
-
/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or
|
|
30
|
-
* turned or zoomed as much), not at every frame of a drag */
|
|
31
|
-
export const followWhenMoved = (map, radius, send) => {
|
|
32
|
-
/** The view of the last call: center (metres), zoom, bearing, pitch */
|
|
33
|
-
let sent;
|
|
34
|
-
return () => {
|
|
35
|
-
const { center, zoom, bearing, pitch } = map.getCamera();
|
|
36
|
-
const [x, y] = [
|
|
37
|
-
center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),
|
|
38
|
-
center[1] * METRES_PER_DEGREE,
|
|
39
|
-
];
|
|
40
|
-
if (sent &&
|
|
41
|
-
Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&
|
|
42
|
-
Math.abs(zoom - sent[2]) < RESEND_SHARE &&
|
|
43
|
-
Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&
|
|
44
|
-
Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE)
|
|
45
|
-
return;
|
|
46
|
-
sent = [x, y, zoom, bearing, pitch];
|
|
47
|
-
send();
|
|
48
|
-
};
|
|
49
|
-
};
|
|
13
|
+
/** The trees' layers: broadleaved in full (the one returned, holding the others), conifers, then both simplified far
|
|
14
|
+
* away; with a model of the page's (`url`, `data`), that one alone, every tree in full */
|
|
50
15
|
export const trees = (context, options = {}) => {
|
|
51
|
-
const {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const send = () => {
|
|
81
|
-
const { center, zoom } = map.getCamera();
|
|
82
|
-
const cos = Math.cos((center[1] * Math.PI) / 180);
|
|
83
|
-
// The trees near the ground under the camera in full, as far as some way past the center
|
|
84
|
-
const [ex, ey, back] = groundUnderCamera(map);
|
|
85
|
-
const near = TREES_NEAR_METRES * 2 ** (16 - zoom) + back;
|
|
86
|
-
const density = others ? FAR_DENSITY : 1;
|
|
87
|
-
/** Each tree of the tiles that may be drawn: in full (near, or every one with a model of the page's) or
|
|
88
|
-
* simplified, with its score (the lowest kept first) */
|
|
89
|
-
const visit = (each) => {
|
|
90
|
-
found.forEach((t) => {
|
|
91
|
-
for (let i = 0; i < t.length / TREE_NUMBERS; i += 1) {
|
|
92
|
-
const dx = ((t[i * TREE_NUMBERS] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;
|
|
93
|
-
const dy = ((t[i * TREE_NUMBERS + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;
|
|
94
|
-
const distance = (dx * dx + dy * dy) / (near * near);
|
|
95
|
-
const rank = t[i * TREE_NUMBERS + 4] ?? 0;
|
|
96
|
-
if (distance <= 1)
|
|
97
|
-
each(t, i, true, rank);
|
|
98
|
-
else if (rank * (distance / density) < 1)
|
|
99
|
-
each(t, i, !others, rank * (distance / density));
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
};
|
|
103
|
-
// How many would be drawn: past a cap, the score kept lowered in proportion (the ranks are even, no sort needed)
|
|
104
|
-
let [fullCount, farCount] = [0, 0];
|
|
105
|
-
visit((_, __, full) => {
|
|
106
|
-
if (full)
|
|
107
|
-
fullCount += 1;
|
|
108
|
-
else
|
|
109
|
-
farCount += 1;
|
|
110
|
-
});
|
|
111
|
-
const limits = [
|
|
112
|
-
Math.min(1, maxInstances / Math.max(fullCount, 1)),
|
|
113
|
-
Math.min(1, (maxInstances * FAR_INSTANCES) / Math.max(farCount, 1)),
|
|
114
|
-
];
|
|
115
|
-
// The engine's numbers (longitude, latitude, altitude, heading, pitch, roll, scale): broadleaved and conifers in
|
|
116
|
-
// full, then simplified
|
|
117
|
-
const out = [[], [], [], []];
|
|
118
|
-
visit((t, i, full, score) => {
|
|
119
|
-
if (score >= (limits[full ? 0 : 1] ?? 1))
|
|
120
|
-
return;
|
|
121
|
-
const at = i * TREE_NUMBERS;
|
|
122
|
-
const conifer = others && t[at + 5] === 1 ? 1 : 0;
|
|
123
|
-
out[(full ? 0 : 2) + conifer]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);
|
|
124
|
-
});
|
|
125
|
-
const none = new Float64Array();
|
|
126
|
-
const [broadleaved = none, conifers = none, farBroadleaved = none, farConifers = none] = out.map((o) => Float64Array.from(o));
|
|
127
|
-
layer.setInstanceNumbers(broadleaved);
|
|
128
|
-
if (others) {
|
|
129
|
-
others.conifers.setInstanceNumbers(conifers);
|
|
130
|
-
others.farBroadleaved.setInstanceNumbers(farBroadleaved);
|
|
131
|
-
others.farConifers.setInstanceNumbers(farConifers);
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
const update = async () => {
|
|
135
|
-
if (context.destroyed())
|
|
136
|
-
return;
|
|
137
|
-
const { key, maxzoom, layers: list } = await renderer;
|
|
138
|
-
const camera = map.getCamera();
|
|
139
|
-
const z = maxzoom;
|
|
140
|
-
const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);
|
|
141
|
-
const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));
|
|
142
|
-
const metres = list.map((l) => (typeof spacing === 'number' ? spacing : spacing(l)));
|
|
143
|
-
const dropped = requests.keys().filter((k) => !keys.has(k));
|
|
144
|
-
// Out of view: dropped, or no longer asked for
|
|
145
|
-
dropped.forEach((k) => {
|
|
146
|
-
requests.drop(k);
|
|
147
|
-
found.delete(k);
|
|
148
|
-
});
|
|
149
|
-
// Dense around the new center
|
|
150
|
-
send();
|
|
151
|
-
wanted.forEach(([x, y], index) => {
|
|
152
|
-
const k = tileKey(z, x, y);
|
|
153
|
-
if (requests.has(k))
|
|
154
|
-
return;
|
|
155
|
-
const work = {
|
|
156
|
-
type: 'trees',
|
|
157
|
-
key,
|
|
158
|
-
z,
|
|
159
|
-
x,
|
|
160
|
-
y,
|
|
161
|
-
spacing: metres,
|
|
162
|
-
maxTrees,
|
|
163
|
-
priority: nearPriority(index),
|
|
164
|
-
};
|
|
165
|
-
requests.ask(k, (signal) => context.request(z, x, y, work, signal), (r) => {
|
|
166
|
-
if (!('trees' in r))
|
|
167
|
-
return;
|
|
168
|
-
found.set(k, r.trees);
|
|
169
|
-
send();
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
};
|
|
173
|
-
// While the camera moves, the trees drawn follow it (dense near it), chosen again once it has gone far enough
|
|
174
|
-
const follow = followWhenMoved(map, (zoom) => TREES_NEAR_METRES * 2 ** (16 - zoom), send);
|
|
175
|
-
context.followView(update, requests, follow);
|
|
16
|
+
const { layers = isWoodland, spacing = treeSpacing, minZoom = STREET_ZOOM, maxTiles = 9, maxTrees = 30000, maxInstances = 25000, colors, } = options;
|
|
17
|
+
const own = options.url !== undefined ? { url: options.url } : options.data && { data: options.data };
|
|
18
|
+
const [layer] = placed(context, {
|
|
19
|
+
models: own ? [own] : [{ data: treeModel(colors) }, { data: coniferModel(colors) }],
|
|
20
|
+
...(!own && {
|
|
21
|
+
far: {
|
|
22
|
+
models: [{ data: treeModel(colors, true) }, { data: coniferModel(colors, true) }],
|
|
23
|
+
density: FAR_DENSITY,
|
|
24
|
+
instances: FAR_INSTANCES,
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
layers: (l) => l.type === 'fill' && layers(l),
|
|
28
|
+
work: (key, z, x, y, priority, list) => ({
|
|
29
|
+
type: 'trees',
|
|
30
|
+
key,
|
|
31
|
+
z,
|
|
32
|
+
x,
|
|
33
|
+
y,
|
|
34
|
+
spacing: list.map((l) => (typeof spacing === 'number' ? spacing : spacing(l))),
|
|
35
|
+
maxTrees,
|
|
36
|
+
priority,
|
|
37
|
+
}),
|
|
38
|
+
read: (r) => ('trees' in r ? r.trees : undefined),
|
|
39
|
+
near: [TREES_NEAR_METRES, 16],
|
|
40
|
+
minZoom,
|
|
41
|
+
maxTiles,
|
|
42
|
+
maxInstances,
|
|
43
|
+
...(options.before && { before: options.before }),
|
|
44
|
+
});
|
|
176
45
|
return layer;
|
|
177
46
|
};
|
|
178
47
|
//# sourceMappingURL=trees.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trees.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/trees.ts"],"names":[],"mappings":"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","sourcesContent":["/** The trees of a vector basemap (`VectorTiles.trees`): 3D models scattered by the workers over its woods and grass */\n\nimport type { Layer, ModelLayer } from '../../layers/layers.ts';\nimport type { GeoMap } from '../../map.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport { coniferModel, isWoodland, TREE_NUMBERS, type TreeColors, treeModel, treeSpacing } from '../trees.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, STREET_ZOOM, tileKey, tilesAround } from './tiles.ts';\n\n/** Metres around the view's center where every tree is drawn in full at zoom 16 (twice as far a zoom level out);\n * past them, simplified (`treeModel(…, true)`) */\nconst TREES_NEAR_METRES = 350;\n\n/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */\nconst FOV = 0.6435011087932844;\n\n/** How much denser the simplified trees far away stay than the full ones would (four times fewer triangles each): a\n * tree twice as far kept as often */\nconst FAR_DENSITY = 4;\n\n/** The simplified trees drawn at most, for so many full ones (`maxInstances`) */\nconst FAR_INSTANCES = 3;\n\n/** While the camera moves, the trees chosen again once it has gone this share of the full trees' radius (or turned\n * or zoomed as much): going through the tiles' trees at every frame of a drag would hold the main thread */\nconst RESEND_SHARE = 0.05;\n\n/** Metres in a degree of latitude (and of longitude at the equator), near enough for the trees' distances */\nexport const METRES_PER_DEGREE = 111320;\n\n/** The options of `VectorTiles.trees` */\nexport interface TreesOptions {\n layers?: (layer: StyleLayer) => boolean;\n spacing?: number | ((layer: StyleLayer) => number);\n minZoom?: number;\n maxTiles?: number;\n maxTrees?: number;\n maxInstances?: number;\n colors?: Partial<TreeColors>;\n url?: string;\n data?: ArrayBuffer | ArrayBufferView<ArrayBuffer>;\n before?: Layer;\n}\n\n/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera\n * stands behind the center of a tilted view, `FOV` its field of view) */\nexport const groundUnderCamera = (map: GeoMap): [east: number, north: number, distance: number] => {\n const { pitch, bearing } = map.getCamera();\n const back =\n ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *\n Math.sin((pitch * Math.PI) / 180) *\n (map.metersPerPixel() ?? 0);\n\n return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];\n};\n\n/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or\n * turned or zoomed as much), not at every frame of a drag */\nexport const followWhenMoved = (map: GeoMap, radius: (zoom: number) => number, send: () => void): (() => void) => {\n /** The view of the last call: center (metres), zoom, bearing, pitch */\n let sent: [number, number, number, number, number] | undefined;\n\n return () => {\n const { center, zoom, bearing, pitch } = map.getCamera();\n const [x, y] = [\n center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),\n center[1] * METRES_PER_DEGREE,\n ];\n\n if (\n sent &&\n Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&\n Math.abs(zoom - sent[2]) < RESEND_SHARE &&\n Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&\n Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE\n )\n return;\n sent = [x, y, zoom, bearing, pitch];\n send();\n };\n};\n\nexport const trees = (context: VectorTilesContext, options: TreesOptions = {}): ModelLayer => {\n const { map } = context;\n const {\n layers = isWoodland,\n spacing = treeSpacing,\n minZoom = STREET_ZOOM,\n maxTiles = 9,\n maxTrees = 30000,\n maxInstances = 25000,\n } = options;\n const own = options.url !== undefined || options.data !== undefined;\n const model = options.url ? { url: options.url } : { data: options.data ?? treeModel(options.colors) };\n const before = options.before ? { before: options.before } : {};\n const layer = map.addModels({ ...model, instances: [], ...before });\n const add = (data: Uint8Array<ArrayBuffer>) => map.addModels({ data, instances: [], ...before });\n // The other kinds and the simplified trees far away on layers of their own, with it: conifers near, the broadleaved\n // and the conifers far away (a model of the page's: every tree, in full)\n const others = own\n ? undefined\n : {\n conifers: add(coniferModel(options.colors)),\n farBroadleaved: add(treeModel(options.colors, true)),\n farConifers: add(coniferModel(options.colors, true)),\n };\n\n if (others) layer.companions.push(others.conifers, others.farBroadleaved, others.farConifers);\n const renderer = context.renderer((l) => l.type === 'fill' && layers(l), []);\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n\n /** The tiles held or asked for, by key, and the trees of those that came */\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The trees drawn to the engine (longitude, latitude, altitude, heading, pitch, roll, scale each): all of them in\n * full near the camera (as far as `TREES_NEAR_METRES` past the view's center), at most `maxInstances`; past `near`\n * metres, simplified, those of a rank under\n * `FAR_DENSITY` (near / distance)², at most `FAR_INSTANCES` times as many (a model of the page's: thinned as the\n * full ones would be, none simplified) */\n const send = () => {\n const { center, zoom } = map.getCamera();\n const cos = Math.cos((center[1] * Math.PI) / 180);\n // The trees near the ground under the camera in full, as far as some way past the center\n const [ex, ey, back] = groundUnderCamera(map);\n const near = TREES_NEAR_METRES * 2 ** (16 - zoom) + back;\n const density = others ? FAR_DENSITY : 1;\n /** Each tree of the tiles that may be drawn: in full (near, or every one with a model of the page's) or\n * simplified, with its score (the lowest kept first) */\n const visit = (each: (t: Float64Array, i: number, full: boolean, score: number) => void) => {\n found.forEach((t) => {\n for (let i = 0; i < t.length / TREE_NUMBERS; i += 1) {\n const dx = ((t[i * TREE_NUMBERS] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[i * TREE_NUMBERS + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const distance = (dx * dx + dy * dy) / (near * near);\n const rank = t[i * TREE_NUMBERS + 4] ?? 0;\n\n if (distance <= 1) each(t, i, true, rank);\n else if (rank * (distance / density) < 1) each(t, i, !others, rank * (distance / density));\n }\n });\n };\n // How many would be drawn: past a cap, the score kept lowered in proportion (the ranks are even, no sort needed)\n let [fullCount, farCount] = [0, 0];\n\n visit((_, __, full) => {\n if (full) fullCount += 1;\n else farCount += 1;\n });\n\n const limits = [\n Math.min(1, maxInstances / Math.max(fullCount, 1)),\n Math.min(1, (maxInstances * FAR_INSTANCES) / Math.max(farCount, 1)),\n ];\n // The engine's numbers (longitude, latitude, altitude, heading, pitch, roll, scale): broadleaved and conifers in\n // full, then simplified\n const out: number[][] = [[], [], [], []];\n\n visit((t, i, full, score) => {\n if (score >= (limits[full ? 0 : 1] ?? 1)) return;\n\n const at = i * TREE_NUMBERS;\n const conifer = others && t[at + 5] === 1 ? 1 : 0;\n\n out[(full ? 0 : 2) + conifer]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n\n const none = new Float64Array();\n const [broadleaved = none, conifers = none, farBroadleaved = none, farConifers = none] = out.map((o) =>\n Float64Array.from(o),\n );\n\n layer.setInstanceNumbers(broadleaved);\n if (others) {\n others.conifers.setInstanceNumbers(conifers);\n others.farBroadleaved.setInstanceNumbers(farBroadleaved);\n others.farConifers.setInstanceNumbers(farConifers);\n }\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom, layers: list } = await renderer;\n const camera = map.getCamera();\n const z = maxzoom;\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n const metres = list.map((l) => (typeof spacing === 'number' ? spacing : spacing(l)));\n const dropped = requests.keys().filter((k) => !keys.has(k));\n\n // Out of view: dropped, or no longer asked for\n dropped.forEach((k) => {\n requests.drop(k);\n found.delete(k);\n });\n // Dense around the new center\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n\n const work: BasemapWork = {\n type: 'trees',\n key,\n z,\n x,\n y,\n spacing: metres,\n maxTrees,\n priority: nearPriority(index),\n };\n\n requests.ask(\n k,\n (signal) => context.request(z, x, y, work, signal),\n (r) => {\n if (!('trees' in r)) return;\n found.set(k, r.trees);\n send();\n },\n );\n });\n };\n // While the camera moves, the trees drawn follow it (dense near it), chosen again once it has gone far enough\n const follow = followWhenMoved(map, (zoom) => TREES_NEAR_METRES * 2 ** (16 - zoom), send);\n\n context.followView(update, requests, follow);\n\n return layer;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"trees.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/trees.ts"],"names":[],"mappings":"AAAA,uHAAuH;AAGvH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAmB,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGhG,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;kDACkD;AAClD,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B;qCACqC;AACrC,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,iFAAiF;AACjF,MAAM,aAAa,GAAG,CAAC,CAAC;AAgBxB;0FAC0F;AAC1F,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAA2B,EAAE,UAAwB,EAAE,EAAc,EAAE;IAC3F,MAAM,EACJ,MAAM,GAAG,UAAU,EACnB,OAAO,GAAG,WAAW,EACrB,OAAO,GAAG,WAAW,EACrB,QAAQ,GAAG,CAAC,EACZ,QAAQ,GAAG,KAAK,EAChB,YAAY,GAAG,KAAK,EACpB,MAAM,GACP,GAAG,OAAO,CAAC;IACZ,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;IACtG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;QAC9B,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACnF,GAAG,CAAC,CAAC,GAAG,IAAI;YACV,GAAG,EAAE;gBACH,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBACjF,OAAO,EAAE,WAAW;gBACpB,SAAS,EAAE,aAAa;aACzB;SACF,CAAC;QACF,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACvC,IAAI,EAAE,OAAO;YACb,GAAG;YACH,CAAC;YACD,CAAC;YACD,CAAC;YACD,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9E,QAAQ;YACR,QAAQ;SACT,CAAC;QACF,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7B,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["/** The trees of a vector basemap (`VectorTiles.trees`): 3D models scattered by the workers over its woods and grass */\n\nimport type { Layer, ModelLayer } from '../../layers/layers.ts';\nimport { coniferModel, isWoodland, type TreeColors, treeModel, treeSpacing } from '../trees.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { placed } from './placed.ts';\nimport { STREET_ZOOM } from './tiles.ts';\n\n/** Metres around the view's center where every tree is drawn in full at zoom 16 (twice as far a zoom level out);\n * past them, simplified (`treeModel(…, true)`) */\nconst TREES_NEAR_METRES = 350;\n\n/** How much denser the simplified trees far away stay than the full ones would (four times fewer triangles each): a\n * tree twice as far kept as often */\nconst FAR_DENSITY = 4;\n\n/** The simplified trees drawn at most, for so many full ones (`maxInstances`) */\nconst FAR_INSTANCES = 3;\n\n/** The options of `VectorTiles.trees` */\nexport interface TreesOptions {\n layers?: (layer: StyleLayer) => boolean;\n spacing?: number | ((layer: StyleLayer) => number);\n minZoom?: number;\n maxTiles?: number;\n maxTrees?: number;\n maxInstances?: number;\n colors?: Partial<TreeColors>;\n url?: string;\n data?: ArrayBuffer | ArrayBufferView<ArrayBuffer>;\n before?: Layer;\n}\n\n/** The trees' layers: broadleaved in full (the one returned, holding the others), conifers, then both simplified far\n * away; with a model of the page's (`url`, `data`), that one alone, every tree in full */\nexport const trees = (context: VectorTilesContext, options: TreesOptions = {}): ModelLayer => {\n const {\n layers = isWoodland,\n spacing = treeSpacing,\n minZoom = STREET_ZOOM,\n maxTiles = 9,\n maxTrees = 30000,\n maxInstances = 25000,\n colors,\n } = options;\n const own = options.url !== undefined ? { url: options.url } : options.data && { data: options.data };\n const [layer] = placed(context, {\n models: own ? [own] : [{ data: treeModel(colors) }, { data: coniferModel(colors) }],\n ...(!own && {\n far: {\n models: [{ data: treeModel(colors, true) }, { data: coniferModel(colors, true) }],\n density: FAR_DENSITY,\n instances: FAR_INSTANCES,\n },\n }),\n layers: (l) => l.type === 'fill' && layers(l),\n work: (key, z, x, y, priority, list) => ({\n type: 'trees',\n key,\n z,\n x,\n y,\n spacing: list.map((l) => (typeof spacing === 'number' ? spacing : spacing(l))),\n maxTrees,\n priority,\n }),\n read: (r) => ('trees' in r ? r.trees : undefined),\n near: [TREES_NEAR_METRES, 16],\n minZoom,\n maxTiles,\n maxInstances,\n ...(options.before && { before: options.before }),\n });\n\n return layer;\n};\n"]}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { Icons } from '../../layers/icons.ts';
|
|
6
6
|
import type { Layer } from '../../layers/layers.ts';
|
|
7
7
|
import type { VectorLayer } from '../../layers/vectors.ts';
|
|
8
|
-
import type { RoofMode } from '../../
|
|
8
|
+
import type { RoofMode } from '../../util/roofs.ts';
|
|
9
9
|
import { type Json, type StyleLayer } from '../vectorstyle.ts';
|
|
10
10
|
import type { VectorTilesContext } from './context.ts';
|
|
11
11
|
/**
|
|
@@ -16,10 +16,9 @@ export declare const dashes: (value: Json | undefined, zoom: number) => [number,
|
|
|
16
16
|
/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),
|
|
17
17
|
* not its casing, a railway, a path or a tunnel */
|
|
18
18
|
export declare const isStreet: (layer: StyleLayer) => boolean;
|
|
19
|
-
/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* such image; the atlas uploaded */
|
|
19
|
+
/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`
|
|
20
|
+
* (`STYLE.fillPattern`, `STYLE.linePattern`), replaced by its image's place in the icon atlas (texels) and pixel
|
|
21
|
+
* ratio; none if the atlas has no such image; the atlas uploaded */
|
|
23
22
|
export declare const placePatterns: (styles: Float32Array, names: readonly string[] | undefined, icons: Icons, prefix: string) => Float32Array;
|
|
24
23
|
/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */
|
|
25
24
|
export declare const translation: (value: Json | undefined, zoom: number) => [number, number];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers
|
|
3
3
|
* into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.
|
|
4
4
|
*/
|
|
5
|
-
import { FLOATS } from "../../
|
|
5
|
+
import { FLOATS, STYLE } from "../../util/style-floats.js";
|
|
6
6
|
import { evaluate, isExpression, vectorKind, zoomOnly } from "../vectorstyle.js";
|
|
7
7
|
import { TileRequests } from "./requests.js";
|
|
8
8
|
import { nearPriority, parseTileKey, tileKey, tileTriples } from "./tiles.js";
|
|
@@ -12,12 +12,14 @@ import { nearPriority, parseTileKey, tileKey, tileTriples } from "./tiles.js";
|
|
|
12
12
|
const OVERZOOM_LEVEL = 18;
|
|
13
13
|
/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */
|
|
14
14
|
const deepestLevel = (maxzoom) => Math.max(maxzoom, OVERZOOM_LEVEL);
|
|
15
|
+
/** A layout or paint value at a zoom, whatever the feature (an expression evaluated) */
|
|
16
|
+
const atZoom = (value, zoom) => isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
|
|
15
17
|
/**
|
|
16
18
|
* A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the
|
|
17
19
|
* canvas's `setLineDash`; past four, the first four), zeros for a solid line
|
|
18
20
|
*/
|
|
19
21
|
export const dashes = (value, zoom) => {
|
|
20
|
-
const v =
|
|
22
|
+
const v = atZoom(value, zoom);
|
|
21
23
|
const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];
|
|
22
24
|
const even = list.length % 2 === 1 ? [...list, ...list] : list;
|
|
23
25
|
const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];
|
|
@@ -29,30 +31,29 @@ export const isStreet = (layer) => /road|highway|street|motorway|trunk|primary|s
|
|
|
29
31
|
!/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);
|
|
30
32
|
/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */
|
|
31
33
|
const lineCap = (value, zoom) => {
|
|
32
|
-
const v =
|
|
34
|
+
const v = atZoom(value, zoom);
|
|
33
35
|
return v === 'round' || v === 'square' ? v : 'butt';
|
|
34
36
|
};
|
|
35
37
|
/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */
|
|
36
38
|
const lineJoin = (value, zoom) => {
|
|
37
|
-
const v =
|
|
39
|
+
const v = atZoom(value, zoom);
|
|
38
40
|
return v === 'round' || v === 'bevel' ? v : 'miter';
|
|
39
41
|
};
|
|
40
42
|
/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */
|
|
41
43
|
const miterLimit = (value, zoom) => {
|
|
42
|
-
const v = Number(
|
|
44
|
+
const v = Number(atZoom(value, zoom) ?? 2);
|
|
43
45
|
return Number.isFinite(v) ? v : 2;
|
|
44
46
|
};
|
|
45
|
-
/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* such image; the atlas uploaded */
|
|
47
|
+
/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`
|
|
48
|
+
* (`STYLE.fillPattern`, `STYLE.linePattern`), replaced by its image's place in the icon atlas (texels) and pixel
|
|
49
|
+
* ratio; none if the atlas has no such image; the atlas uploaded */
|
|
49
50
|
export const placePatterns = (styles, names, icons, prefix) => {
|
|
50
51
|
if (!names?.length)
|
|
51
52
|
return styles;
|
|
52
53
|
// Thousands of features a tile: a loop
|
|
53
54
|
for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {
|
|
54
|
-
const fill = styles[f +
|
|
55
|
-
const line = styles[f +
|
|
55
|
+
const fill = styles[f + STYLE.fillPattern] ?? 0;
|
|
56
|
+
const line = styles[f + STYLE.linePattern] ?? 0;
|
|
56
57
|
const index = fill > 0 ? fill : line;
|
|
57
58
|
if (index <= 0)
|
|
58
59
|
continue;
|
|
@@ -60,10 +61,10 @@ export const placePatterns = (styles, names, icons, prefix) => {
|
|
|
60
61
|
const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];
|
|
61
62
|
const ratio = icon?.pixelRatio ?? 0;
|
|
62
63
|
if (fill > 0)
|
|
63
|
-
styles.set([...place, ratio], f +
|
|
64
|
+
styles.set([...place, ratio], f + STYLE.size + 4);
|
|
64
65
|
else {
|
|
65
|
-
styles.set(place, f +
|
|
66
|
-
styles[f +
|
|
66
|
+
styles.set(place, f + STYLE.second);
|
|
67
|
+
styles[f + STYLE.patternRatio] = ratio;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
icons.flush();
|
|
@@ -73,7 +74,7 @@ export const placePatterns = (styles, names, icons, prefix) => {
|
|
|
73
74
|
const PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];
|
|
74
75
|
/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */
|
|
75
76
|
export const translation = (value, zoom) => {
|
|
76
|
-
const v =
|
|
77
|
+
const v = atZoom(value, zoom);
|
|
77
78
|
const [x, y] = Array.isArray(v) ? v.map(Number) : [];
|
|
78
79
|
return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];
|
|
79
80
|
};
|
|
@@ -225,7 +226,7 @@ export const vectors = (context, options = {}) => {
|
|
|
225
226
|
vector.styled.catch(() => undefined);
|
|
226
227
|
// While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of
|
|
227
228
|
// its start drawn)
|
|
228
|
-
context.followView(update, requests, update);
|
|
229
|
+
context.followView(vector, update, requests, update);
|
|
229
230
|
return vector;
|
|
230
231
|
};
|
|
231
232
|
//# sourceMappingURL=vectors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/vectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers\n * into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.\n */\n\nimport { FLOATS } from '../../layers/features.ts';\nimport type { Icons } from '../../layers/icons.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { VectorLayer, VectorSublayer } from '../../layers/vectors.ts';\nimport type { RoofMode } from '../../workers/basemap/geometry.ts';\nimport type { BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { evaluate, isExpression, type Json, type StyleLayer, vectorKind, zoomOnly } from '../vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, parseTileKey, type TileTriple, tileKey, tileTriples } from './tiles.ts';\n\n/** The deepest level `vectors()` cuts its tiles at: past the source's deepest level, its tiles cut again into deeper\n * ones (overzoom, as MapLibre does) down to level 18, their styles those of their level, smaller tiles\n * drawn in a closer view; past it, the tiles of that level stretched */\nconst OVERZOOM_LEVEL = 18;\n\n/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */\nconst deepestLevel = (maxzoom: number): number => Math.max(maxzoom, OVERZOOM_LEVEL);\n\n/**\n * A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the\n * canvas's `setLineDash`; past four, the first four), zeros for a solid line\n */\nexport const dashes = (value: Json | undefined, zoom: number): [number, number, number, number] => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];\n const even = list.length % 2 === 1 ? [...list, ...list] : list;\n const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];\n\n return [a, b, c, d];\n};\n\n/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),\n * not its casing, a railway, a path or a tunnel */\nexport const isStreet = (layer: StyleLayer): boolean =>\n /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&\n !/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);\n\n/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */\nconst lineCap = (value: Json | undefined, zoom: number): 'butt' | 'round' | 'square' => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n return v === 'round' || v === 'square' ? v : 'butt';\n};\n\n/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */\nconst lineJoin = (value: Json | undefined, zoom: number): 'miter' | 'bevel' | 'round' => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n return v === 'round' || v === 'bevel' ? v : 'miter';\n};\n\n/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */\nconst miterLimit = (value: Json | undefined, zoom: number): number => {\n const v = Number(isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : (value ?? 2));\n\n return Number.isFinite(v) ? v : 2;\n};\n\n/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names` (float 28\n * for a fill, 29 for a line or a building: floats the engine does not keep), replaced by its image's place in the icon\n * atlas (texels) and pixel ratio, at 12 and 16 for a fill, 4 and 27 for a line or a building; none if the atlas has no\n * such image; the atlas uploaded */\nexport const placePatterns = (\n styles: Float32Array,\n names: readonly string[] | undefined,\n icons: Icons,\n prefix: string,\n): Float32Array => {\n if (!names?.length) return styles;\n // Thousands of features a tile: a loop\n for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {\n const fill = styles[f + 28] ?? 0;\n const line = styles[f + 29] ?? 0;\n const index = fill > 0 ? fill : line;\n\n if (index <= 0) continue;\n\n const icon = icons.get(prefix + (names[index - 1] ?? ''));\n const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];\n const ratio = icon?.pixelRatio ?? 0;\n\n if (fill > 0) styles.set([...place, ratio], f + 12);\n else {\n styles.set(place, f + 4);\n styles[f + 27] = ratio;\n }\n }\n icons.flush();\n\n return styles;\n};\n\n/** The paint properties of the patterns `vectors()` draws, whose images come from the style's sprite */\nconst PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];\n\n/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */\nexport const translation = (value: Json | undefined, zoom: number): [number, number] => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n const [x, y] = Array.isArray(v) ? v.map(Number) : [];\n\n return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];\n};\n\n/** The options of `VectorTiles.vectors` */\nexport interface VectorsOptions {\n layers?: (layer: StyleLayer) => boolean;\n streets?: (layer: StyleLayer) => boolean;\n before?: Layer;\n /** The buildings' roofs: from their data (`roof:shape`, `roof:height`; flat without, the default), generated from\n * their outline where they have none (hipped, gabled or mansard by size and shape), or all flat */\n roofs?: RoofMode;\n /** The buildings' walls show their windows: glass by day, some lit at night (default false: only the lit ones) */\n facades?: boolean;\n}\n\nexport const vectors = (context: VectorTilesContext, options: VectorsOptions = {}): VectorLayer => {\n const { map } = context;\n const { layers = () => true, streets = isStreet, before, roofs = 'data', facades = false } = options;\n const vector = map.addVectorLayer(before);\n\n vector.setFacades(facades);\n const state: {\n renderer: Promise<Renderer>;\n /** The style layers as the application changed them (`setPaintProperty`…): a copy, its style left as it is */\n own?: StyleLayer[];\n /** Bumped by each update: only the last one drops the tiles out of its view */\n update: number;\n /** Bumped by each restyle: a tile cut under an older style is restyled once it is there */\n style: number;\n } = { renderer: context.renderer((l) => vectorKind(l) !== undefined && layers(l), []), update: 0, style: 0 };\n\n state.renderer.catch(() => undefined);\n\n /** The style's sprites among the map's icons, if a layer drawn has a pattern: waited for before the first tiles */\n const sprites = context.ready\n .then(({ style }) =>\n style.layers.some((l) => layers(l) && PATTERNS.some((k) => l.paint?.[k] !== undefined))\n ? context.addSprites()\n : undefined,\n )\n .catch(() => undefined);\n const placed = (styles: Float32Array, names: readonly string[] | undefined) =>\n placePatterns(styles, names, map.icons, context.iconPrefix);\n context.layers.push(vector);\n\n const sublayers = (list: StyleLayer[]): VectorSublayer[] => {\n const zoom = map.getCamera().zoom;\n\n return list.map((l) => ({\n id: l.id,\n sourceLayer: l['source-layer'],\n kind: vectorKind(l) ?? 'fill',\n minZoom: l.minzoom ?? 0,\n maxZoom: l.maxzoom ?? 24,\n visible: l.layout?.visibility !== 'none',\n opacity: zoomOnly(l.paint?.[`${l.type}-opacity`], 1) ?? 1,\n cap: lineCap(l.layout?.['line-cap'], zoom),\n join: lineJoin(l.layout?.['line-join'], zoom),\n miterLimit: miterLimit(l.layout?.['line-miter-limit'], zoom),\n translate: translation(l.paint?.[`${l.type}-translate`], zoom),\n translateAnchor: l.paint?.[`${l.type}-translate-anchor`] === 'viewport' ? 'viewport' : 'map',\n patterned: l.paint?.['fill-pattern'] !== undefined || l.paint?.['background-pattern'] !== undefined,\n lit: l.type === 'line' && streets(l),\n dash: l.type === 'line' ? dashes(l.paint?.['line-dasharray'], zoom) : [0, 0, 0, 0],\n }));\n };\n\n /** The tiles held or asked for, by `z/x/y` */\n const requests = new TileRequests();\n /** A tile's geometry, or its styles alone, asked of the worker of its tile of the source's level (which keeps the\n * decoded tile its deeper tiles are cut from) */\n const ask = (\n { key, maxzoom }: { key: string; maxzoom: number },\n [z, x, y]: TileTriple,\n styles: boolean,\n priority: Priority,\n signal?: AbortSignal,\n ) => {\n const d = Math.max(0, z - maxzoom);\n const work: BasemapWork = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), roofs, priority };\n\n // The geometry made ready for the GPU in the workers, with the prisms the relief needs\n return context.request(\n z - d,\n Math.floor(x / 2 ** d),\n Math.floor(y / 2 ** d),\n styles ? { ...work, styles } : { ...work, prism: map.hasRelief },\n signal,\n );\n };\n\n // The workers tessellate the tiles (the main thread only uploads them), once they know the module\n context.broadcast({ type: 'tess', url: map.tessUrl });\n /** Asks the workers again for the styles of a tile held, under the current style; the tile's geometry stays as it\n * is */\n const restyleTile = async (renderer: { key: string; maxzoom: number }, k: string) => {\n const r = await ask(renderer, parseTileKey(k), true, 'auto').catch(() => undefined);\n\n if (r && 'styles' in r) vector.setTileStyles(k, placed(r.styles, r.patterns));\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const generation = ++state.update;\n // The style the tiles are cut under: that of the renderer awaited, a restyle meanwhile (a paint property set as the\n // style loads) asking their styles again once they are there\n const style = state.style;\n const { key, maxzoom, layers: list } = await state.renderer;\n\n await sprites;\n\n vector.setSublayers(sublayers(state.own ?? list));\n\n const wanted = tileTriples(map.engine.vectorTilesInView(0, deepestLevel(maxzoom)));\n const keys = new Set(wanted.map((t) => tileKey(...t)));\n const loads = wanted.flatMap((t, index) => {\n const k = tileKey(...t);\n\n if (requests.has(k)) return [];\n\n return [\n requests.ask(\n k,\n (signal) => ask({ key, maxzoom }, t, false, nearPriority(index, 'high', 'auto'), signal),\n async (r) => {\n if (!('vectors' in r)) return;\n await vector.setTile(k, { ...r.vectors, styles: placed(r.vectors.styles, r.vectors.patterns) });\n // Cut under a style changed since: its styles asked for again\n if (style !== state.style) await restyleTile(await state.renderer, k);\n },\n ),\n ];\n });\n // Out of view: those still asked for go at once, those drawn once their replacements are there (no hole). The\n // drawn ones are those the engine shows, held or not (a recut forgets what it held, not what is drawn)\n const drop = (drawn: boolean) => {\n const shown = new Set(vector.tileKeys);\n const known = new Set([...requests.keys(), ...(drawn ? shown : [])]);\n\n known.forEach((k) => {\n if (keys.has(k) || shown.has(k) !== drawn) return;\n requests.drop(k);\n vector.removeTile(k);\n });\n };\n\n drop(false);\n // Every tile of the view, those an earlier update asked for too: a tile out of view stays drawn until all of them\n // are there\n await Promise.all([...loads, requests.answered(keys)]);\n // A later update (the view moved again meanwhile) drops for its own view: these keys are no longer the view\n if (!context.destroyed() && generation === state.update) drop(true);\n };\n const refresh = () => {\n update().catch(() => undefined);\n };\n /** The style layers changed: the workers' copy, then the styles of the tiles held */\n const restyle = async (list: StyleLayer[]) => {\n state.own = list;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, list, key));\n\n const renderer = await state.renderer;\n\n vector.setSublayers(sublayers(list));\n await Promise.all(vector.tileKeys.map((k) => restyleTile(renderer, k)));\n };\n\n vector.restyle = (id, group, name, value) => {\n state.renderer\n .then(({ layers: list }) => {\n const next = (state.own ?? list).map((l) =>\n l.id === id ? { ...l, [group]: { ...l[group], [name]: value } } : l,\n );\n\n // Visibility and dashes are the engine's: the tiles stay as they are\n if ((group === 'layout' && name === 'visibility') || name === 'line-dasharray') {\n state.own = next;\n vector.setSublayers(sublayers(next));\n\n return undefined;\n }\n // An outline added or taken away: a feature more or less in each tile, cut again\n if (name === 'fill-outline-color' || name === 'fill-antialias') {\n state.own = next;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, next, key));\n vector.setSublayers(sublayers(next));\n vector.recut?.();\n\n return undefined;\n }\n\n return restyle(next);\n })\n .catch(() => undefined);\n };\n vector.recut = () => {\n requests.abortAll();\n refresh();\n };\n vector.styled = state.renderer.then(({ layers: list }) => {\n if (!context.destroyed()) vector.setSublayers(sublayers(state.own ?? list));\n });\n // Reported by the style's `ready`\n vector.styled.catch(() => undefined);\n\n // While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of\n // its start drawn)\n context.followView(update, requests, update);\n\n return vector;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/vectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers\n * into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.\n */\n\nimport type { Icons } from '../../layers/icons.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { VectorLayer, VectorSublayer } from '../../layers/vectors.ts';\nimport type { RoofMode } from '../../util/roofs.ts';\nimport { FLOATS, STYLE } from '../../util/style-floats.ts';\nimport type { BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { evaluate, isExpression, type Json, type StyleLayer, vectorKind, zoomOnly } from '../vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, parseTileKey, type TileTriple, tileKey, tileTriples } from './tiles.ts';\n\n/** The deepest level `vectors()` cuts its tiles at: past the source's deepest level, its tiles cut again into deeper\n * ones (overzoom, as MapLibre does) down to level 18, their styles those of their level, smaller tiles\n * drawn in a closer view; past it, the tiles of that level stretched */\nconst OVERZOOM_LEVEL = 18;\n\n/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */\nconst deepestLevel = (maxzoom: number): number => Math.max(maxzoom, OVERZOOM_LEVEL);\n\n/** A layout or paint value at a zoom, whatever the feature (an expression evaluated) */\nconst atZoom = (value: Json | undefined, zoom: number): unknown =>\n isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n/**\n * A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the\n * canvas's `setLineDash`; past four, the first four), zeros for a solid line\n */\nexport const dashes = (value: Json | undefined, zoom: number): [number, number, number, number] => {\n const v = atZoom(value, zoom);\n const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];\n const even = list.length % 2 === 1 ? [...list, ...list] : list;\n const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];\n\n return [a, b, c, d];\n};\n\n/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),\n * not its casing, a railway, a path or a tunnel */\nexport const isStreet = (layer: StyleLayer): boolean =>\n /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&\n !/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);\n\n/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */\nconst lineCap = (value: Json | undefined, zoom: number): 'butt' | 'round' | 'square' => {\n const v = atZoom(value, zoom);\n\n return v === 'round' || v === 'square' ? v : 'butt';\n};\n\n/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */\nconst lineJoin = (value: Json | undefined, zoom: number): 'miter' | 'bevel' | 'round' => {\n const v = atZoom(value, zoom);\n\n return v === 'round' || v === 'bevel' ? v : 'miter';\n};\n\n/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */\nconst miterLimit = (value: Json | undefined, zoom: number): number => {\n const v = Number(atZoom(value, zoom) ?? 2);\n\n return Number.isFinite(v) ? v : 2;\n};\n\n/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`\n * (`STYLE.fillPattern`, `STYLE.linePattern`), replaced by its image's place in the icon atlas (texels) and pixel\n * ratio; none if the atlas has no such image; the atlas uploaded */\nexport const placePatterns = (\n styles: Float32Array,\n names: readonly string[] | undefined,\n icons: Icons,\n prefix: string,\n): Float32Array => {\n if (!names?.length) return styles;\n // Thousands of features a tile: a loop\n for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {\n const fill = styles[f + STYLE.fillPattern] ?? 0;\n const line = styles[f + STYLE.linePattern] ?? 0;\n const index = fill > 0 ? fill : line;\n\n if (index <= 0) continue;\n\n const icon = icons.get(prefix + (names[index - 1] ?? ''));\n const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];\n const ratio = icon?.pixelRatio ?? 0;\n\n if (fill > 0) styles.set([...place, ratio], f + STYLE.size + 4);\n else {\n styles.set(place, f + STYLE.second);\n styles[f + STYLE.patternRatio] = ratio;\n }\n }\n icons.flush();\n\n return styles;\n};\n\n/** The paint properties of the patterns `vectors()` draws, whose images come from the style's sprite */\nconst PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];\n\n/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */\nexport const translation = (value: Json | undefined, zoom: number): [number, number] => {\n const v = atZoom(value, zoom);\n const [x, y] = Array.isArray(v) ? v.map(Number) : [];\n\n return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];\n};\n\n/** The options of `VectorTiles.vectors` */\nexport interface VectorsOptions {\n layers?: (layer: StyleLayer) => boolean;\n streets?: (layer: StyleLayer) => boolean;\n before?: Layer;\n /** The buildings' roofs: from their data (`roof:shape`, `roof:height`; flat without, the default), generated from\n * their outline where they have none (hipped, gabled or mansard by size and shape), or all flat */\n roofs?: RoofMode;\n /** The buildings' walls show their windows: glass by day, some lit at night (default false: only the lit ones) */\n facades?: boolean;\n}\n\nexport const vectors = (context: VectorTilesContext, options: VectorsOptions = {}): VectorLayer => {\n const { map } = context;\n const { layers = () => true, streets = isStreet, before, roofs = 'data', facades = false } = options;\n const vector = map.addVectorLayer(before);\n\n vector.setFacades(facades);\n const state: {\n renderer: Promise<Renderer>;\n /** The style layers as the application changed them (`setPaintProperty`…): a copy, its style left as it is */\n own?: StyleLayer[];\n /** Bumped by each update: only the last one drops the tiles out of its view */\n update: number;\n /** Bumped by each restyle: a tile cut under an older style is restyled once it is there */\n style: number;\n } = { renderer: context.renderer((l) => vectorKind(l) !== undefined && layers(l), []), update: 0, style: 0 };\n\n state.renderer.catch(() => undefined);\n\n /** The style's sprites among the map's icons, if a layer drawn has a pattern: waited for before the first tiles */\n const sprites = context.ready\n .then(({ style }) =>\n style.layers.some((l) => layers(l) && PATTERNS.some((k) => l.paint?.[k] !== undefined))\n ? context.addSprites()\n : undefined,\n )\n .catch(() => undefined);\n const placed = (styles: Float32Array, names: readonly string[] | undefined) =>\n placePatterns(styles, names, map.icons, context.iconPrefix);\n context.layers.push(vector);\n\n const sublayers = (list: StyleLayer[]): VectorSublayer[] => {\n const zoom = map.getCamera().zoom;\n\n return list.map((l) => ({\n id: l.id,\n sourceLayer: l['source-layer'],\n kind: vectorKind(l) ?? 'fill',\n minZoom: l.minzoom ?? 0,\n maxZoom: l.maxzoom ?? 24,\n visible: l.layout?.visibility !== 'none',\n opacity: zoomOnly(l.paint?.[`${l.type}-opacity`], 1) ?? 1,\n cap: lineCap(l.layout?.['line-cap'], zoom),\n join: lineJoin(l.layout?.['line-join'], zoom),\n miterLimit: miterLimit(l.layout?.['line-miter-limit'], zoom),\n translate: translation(l.paint?.[`${l.type}-translate`], zoom),\n translateAnchor: l.paint?.[`${l.type}-translate-anchor`] === 'viewport' ? 'viewport' : 'map',\n patterned: l.paint?.['fill-pattern'] !== undefined || l.paint?.['background-pattern'] !== undefined,\n lit: l.type === 'line' && streets(l),\n dash: l.type === 'line' ? dashes(l.paint?.['line-dasharray'], zoom) : [0, 0, 0, 0],\n }));\n };\n\n /** The tiles held or asked for, by `z/x/y` */\n const requests = new TileRequests();\n /** A tile's geometry, or its styles alone, asked of the worker of its tile of the source's level (which keeps the\n * decoded tile its deeper tiles are cut from) */\n const ask = (\n { key, maxzoom }: { key: string; maxzoom: number },\n [z, x, y]: TileTriple,\n styles: boolean,\n priority: Priority,\n signal?: AbortSignal,\n ) => {\n const d = Math.max(0, z - maxzoom);\n const work: BasemapWork = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), roofs, priority };\n\n // The geometry made ready for the GPU in the workers, with the prisms the relief needs\n return context.request(\n z - d,\n Math.floor(x / 2 ** d),\n Math.floor(y / 2 ** d),\n styles ? { ...work, styles } : { ...work, prism: map.hasRelief },\n signal,\n );\n };\n\n // The workers tessellate the tiles (the main thread only uploads them), once they know the module\n context.broadcast({ type: 'tess', url: map.tessUrl });\n /** Asks the workers again for the styles of a tile held, under the current style; the tile's geometry stays as it\n * is */\n const restyleTile = async (renderer: { key: string; maxzoom: number }, k: string) => {\n const r = await ask(renderer, parseTileKey(k), true, 'auto').catch(() => undefined);\n\n if (r && 'styles' in r) vector.setTileStyles(k, placed(r.styles, r.patterns));\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const generation = ++state.update;\n // The style the tiles are cut under: that of the renderer awaited, a restyle meanwhile (a paint property set as the\n // style loads) asking their styles again once they are there\n const style = state.style;\n const { key, maxzoom, layers: list } = await state.renderer;\n\n await sprites;\n\n vector.setSublayers(sublayers(state.own ?? list));\n\n const wanted = tileTriples(map.engine.vectorTilesInView(0, deepestLevel(maxzoom)));\n const keys = new Set(wanted.map((t) => tileKey(...t)));\n const loads = wanted.flatMap((t, index) => {\n const k = tileKey(...t);\n\n if (requests.has(k)) return [];\n\n return [\n requests.ask(\n k,\n (signal) => ask({ key, maxzoom }, t, false, nearPriority(index, 'high', 'auto'), signal),\n async (r) => {\n if (!('vectors' in r)) return;\n await vector.setTile(k, { ...r.vectors, styles: placed(r.vectors.styles, r.vectors.patterns) });\n // Cut under a style changed since: its styles asked for again\n if (style !== state.style) await restyleTile(await state.renderer, k);\n },\n ),\n ];\n });\n // Out of view: those still asked for go at once, those drawn once their replacements are there (no hole). The\n // drawn ones are those the engine shows, held or not (a recut forgets what it held, not what is drawn)\n const drop = (drawn: boolean) => {\n const shown = new Set(vector.tileKeys);\n const known = new Set([...requests.keys(), ...(drawn ? shown : [])]);\n\n known.forEach((k) => {\n if (keys.has(k) || shown.has(k) !== drawn) return;\n requests.drop(k);\n vector.removeTile(k);\n });\n };\n\n drop(false);\n // Every tile of the view, those an earlier update asked for too: a tile out of view stays drawn until all of them\n // are there\n await Promise.all([...loads, requests.answered(keys)]);\n // A later update (the view moved again meanwhile) drops for its own view: these keys are no longer the view\n if (!context.destroyed() && generation === state.update) drop(true);\n };\n const refresh = () => {\n update().catch(() => undefined);\n };\n /** The style layers changed: the workers' copy, then the styles of the tiles held */\n const restyle = async (list: StyleLayer[]) => {\n state.own = list;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, list, key));\n\n const renderer = await state.renderer;\n\n vector.setSublayers(sublayers(list));\n await Promise.all(vector.tileKeys.map((k) => restyleTile(renderer, k)));\n };\n\n vector.restyle = (id, group, name, value) => {\n state.renderer\n .then(({ layers: list }) => {\n const next = (state.own ?? list).map((l) =>\n l.id === id ? { ...l, [group]: { ...l[group], [name]: value } } : l,\n );\n\n // Visibility and dashes are the engine's: the tiles stay as they are\n if ((group === 'layout' && name === 'visibility') || name === 'line-dasharray') {\n state.own = next;\n vector.setSublayers(sublayers(next));\n\n return undefined;\n }\n // An outline added or taken away: a feature more or less in each tile, cut again\n if (name === 'fill-outline-color' || name === 'fill-antialias') {\n state.own = next;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, next, key));\n vector.setSublayers(sublayers(next));\n vector.recut?.();\n\n return undefined;\n }\n\n return restyle(next);\n })\n .catch(() => undefined);\n };\n vector.recut = () => {\n requests.abortAll();\n refresh();\n };\n vector.styled = state.renderer.then(({ layers: list }) => {\n if (!context.destroyed()) vector.setSublayers(sublayers(state.own ?? list));\n });\n // Reported by the style's `ready`\n vector.styled.catch(() => undefined);\n\n // While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of\n // its start drawn)\n context.followView(vector, update, requests, update);\n\n return vector;\n};\n"]}
|
|
@@ -18,6 +18,7 @@ import type { VectorLayer } from '../layers/vectors.ts';
|
|
|
18
18
|
import type { GeoMap } from '../map.ts';
|
|
19
19
|
import type { LabelCandidate, Style, StyleLayer } from './vectorstyle.ts';
|
|
20
20
|
import { type VectorExtrusionOptions } from './vectortiles/extrusions.ts';
|
|
21
|
+
import { type FurnitureOptions } from './vectortiles/furniture.ts';
|
|
21
22
|
import { type LabelsOptions, size, tileLabels } from './vectortiles/labels.ts';
|
|
22
23
|
import { type LampsOptions } from './vectortiles/lamps.ts';
|
|
23
24
|
import { type StreetWindLayer, type StreetWindOptions } from './vectortiles/street-wind.ts';
|
|
@@ -77,9 +78,8 @@ export declare class VectorTiles {
|
|
|
77
78
|
/** Prefix of the names of its sprites' images among the map's icons */
|
|
78
79
|
private get iconPrefix();
|
|
79
80
|
private request;
|
|
80
|
-
/** Sends a renderer of these layers to every worker (again under
|
|
81
|
-
* `draws` the tiles into images with patterns (the raster path: the others take their images in the page)
|
|
82
|
-
* its key */
|
|
81
|
+
/** Sends a renderer of these layers to every worker (`again`: under that key, restyled), with the style's sprites if
|
|
82
|
+
* it `draws` the tiles into images with patterns (the raster path: the others take their images in the page) */
|
|
83
83
|
private renderer;
|
|
84
84
|
/**
|
|
85
85
|
* A raster layer drawing the style's fills, lines and circles (or those `layers` keeps, then `extraLayers`, of the
|
|
@@ -133,6 +133,14 @@ export declare class VectorTiles {
|
|
|
133
133
|
* The models load the engine with 3D Tiles.
|
|
134
134
|
*/
|
|
135
135
|
lamps(options?: LampsOptions): ModelLayer;
|
|
136
|
+
/**
|
|
137
|
+
* The street furniture as 3D models, from OpenMapTiles' points of interest of the street: bus shelters at the bus
|
|
138
|
+
* stops, waste baskets, post boxes, drinking fountains (Wallace's in Paris), bicycle racks, each facing its street;
|
|
139
|
+
* benches along the pedestrian streets and the paths of the parks and gardens. Placed by the workers, one instanced
|
|
140
|
+
* draw a kind, all of them near the camera and fewer away from it. The layer returned holds the other kinds' (its
|
|
141
|
+
* `companions`); removed with it
|
|
142
|
+
*/
|
|
143
|
+
furniture(options?: FurnitureOptions): ModelLayer;
|
|
136
144
|
/**
|
|
137
145
|
* A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the
|
|
138
146
|
* `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the
|
|
@@ -163,9 +171,11 @@ export declare class VectorTiles {
|
|
|
163
171
|
labels(options?: LabelsOptions): SymbolLayer<LabelCandidate>;
|
|
164
172
|
/**
|
|
165
173
|
* Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every
|
|
166
|
-
* `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed
|
|
174
|
+
* `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed or the layer removed
|
|
167
175
|
*/
|
|
168
176
|
private followView;
|
|
177
|
+
/** Calls `stop` when destroyed or once `layer` is removed, whichever comes first */
|
|
178
|
+
private stopWith;
|
|
169
179
|
/** Stops its workers' work and removes its raster and label layers from the map (those still there) */
|
|
170
180
|
destroy(): void;
|
|
171
181
|
}
|