isard 1.5.0 → 1.7.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 +213 -1
- package/README.md +3 -2
- package/dist/basemap/furniture.d.ts +26 -0
- package/dist/basemap/furniture.js +95 -0
- package/dist/basemap/furniture.js.map +1 -0
- 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 +25 -8
- package/dist/basemap/trees.js +77 -105
- package/dist/basemap/trees.js.map +1 -1
- package/dist/basemap/vectorstyle.d.ts +9 -3
- package/dist/basemap/vectorstyle.js +5 -6
- package/dist/basemap/vectorstyle.js.map +1 -1
- package/dist/basemap/vectortiles/context.d.ts +7 -2
- package/dist/basemap/vectortiles/context.js.map +1 -1
- package/dist/basemap/vectortiles/extrusions.d.ts +4 -0
- package/dist/basemap/vectortiles/extrusions.js +9 -3
- 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.d.ts +3 -0
- package/dist/basemap/vectortiles/labels.js +50 -18
- package/dist/basemap/vectortiles/labels.js.map +1 -1
- package/dist/basemap/vectortiles/lamps.d.ts +23 -0
- package/dist/basemap/vectortiles/lamps.js +25 -0
- package/dist/basemap/vectortiles/lamps.js.map +1 -0
- 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/requests.d.ts +4 -0
- package/dist/basemap/vectortiles/requests.js +15 -2
- package/dist/basemap/vectortiles/requests.js.map +1 -1
- 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 -0
- package/dist/basemap/vectortiles/trees.js +40 -86
- package/dist/basemap/vectortiles/trees.js.map +1 -1
- package/dist/basemap/vectortiles/vectors.d.ts +16 -0
- package/dist/basemap/vectortiles/vectors.js +76 -11
- package/dist/basemap/vectortiles/vectors.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +37 -7
- package/dist/basemap/vectortiles.js +78 -17
- 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 +19 -13
- package/dist/bind/layers.js +1 -0
- package/dist/bind/layers.js.map +1 -1
- package/dist/data/collada.d.ts +19 -0
- package/dist/data/collada.js +305 -0
- package/dist/data/collada.js.map +1 -0
- package/dist/data/crs.js +1 -1
- package/dist/data/crs.js.map +1 -1
- package/dist/data/ifc.d.ts +100 -0
- package/dist/data/ifc.js +371 -0
- package/dist/data/ifc.js.map +1 -0
- package/dist/decoder.worker.js +5 -5
- package/dist/decoder.worker.js.map +3 -3
- package/dist/formats.d.ts +7 -2
- package/dist/formats.js +7 -2
- package/dist/formats.js.map +1 -1
- package/dist/geoplateforme.d.ts +14 -2
- package/dist/geoplateforme.js +24 -2
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.js +8 -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.d.ts +10 -0
- package/dist/layers/extrusions.js +33 -6
- 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 +14 -0
- package/dist/layers/layers.js +55 -1
- 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.d.ts +48 -0
- package/dist/layers/photos.js +139 -0
- package/dist/layers/photos.js.map +1 -0
- package/dist/layers/symbols.d.ts +5 -1
- package/dist/layers/symbols.js +111 -32
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/trees.d.ts +28 -0
- package/dist/layers/trees.js +51 -0
- package/dist/layers/trees.js.map +1 -0
- package/dist/layers/vectors.d.ts +29 -2
- package/dist/layers/vectors.js +98 -9
- 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/layer-spec.d.ts +3 -0
- package/dist/map/layer-spec.js +2 -0
- package/dist/map/layer-spec.js.map +1 -1
- package/dist/map.d.ts +8 -0
- package/dist/map.js +32 -2
- package/dist/map.js.map +1 -1
- package/dist/panoramax.d.ts +55 -0
- package/dist/panoramax.js +97 -0
- package/dist/panoramax.js.map +1 -0
- package/dist/react/Layer.d.ts +1 -0
- package/dist/react/Layer.js.map +1 -1
- package/dist/react/VectorGeometry.d.ts +22 -8
- package/dist/react/VectorGeometry.js +36 -14
- 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 +9 -0
- package/dist/react/context.js +32 -0
- 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 +26 -0
- package/dist/util/gltf.js +52 -0
- package/dist/util/gltf.js.map +1 -0
- package/dist/util/roofs.d.ts +18 -0
- package/dist/util/roofs.js +44 -0
- package/dist/util/roofs.js.map +1 -0
- 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/wasm/isard.d.ts +56 -17
- package/dist/wasm/isard.js +128 -18
- package/dist/wasm/isard_core.d.ts +44 -17
- package/dist/wasm/isard_core.js +104 -18
- package/dist/wasm/isard_tess.d.ts +6 -3
- package/dist/wasm/isard_tess.js +27 -4
- package/dist/workers/basemap/furniture.d.ts +13 -0
- package/dist/workers/basemap/geometry.d.ts +35 -22
- package/dist/workers/basemap/labels.d.ts +18 -2
- package/dist/workers/basemap/lamps.d.ts +10 -0
- package/dist/workers/basemap/tiles.d.ts +2 -0
- package/dist/workers/basemap/trees.d.ts +6 -1
- package/dist/workers/basemap.worker.d.ts +58 -2
- package/dist/workers/basemap.worker.js +26 -3
- package/dist/workers/basemap.worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,93 +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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
/** Metres around the view's center where every tree is drawn at zoom 16 (twice as far a zoom level out)
|
|
2
|
+
import { coniferModel, isWoodland, treeModel, treeSpacing } from "../trees.js";
|
|
3
|
+
import { placed } from "./placed.js";
|
|
4
|
+
import { STREET_ZOOM } from "./tiles.js";
|
|
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
|
+
* past them, simplified (`treeModel(…, true)`) */
|
|
6
7
|
const TREES_NEAR_METRES = 350;
|
|
7
|
-
/**
|
|
8
|
-
|
|
8
|
+
/** How much denser the simplified trees far away stay than the full ones would (four times fewer triangles each): a
|
|
9
|
+
* tree twice as far kept as often */
|
|
10
|
+
const FAR_DENSITY = 4;
|
|
11
|
+
/** The simplified trees drawn at most, for so many full ones (`maxInstances`) */
|
|
12
|
+
const FAR_INSTANCES = 3;
|
|
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 */
|
|
9
15
|
export const trees = (context, options = {}) => {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
...
|
|
15
|
-
|
|
16
|
-
|
|
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 }),
|
|
17
44
|
});
|
|
18
|
-
const renderer = context.renderer((l) => l.type === 'fill' && layers(l), []);
|
|
19
|
-
renderer.catch(() => undefined);
|
|
20
|
-
context.layers.push(layer);
|
|
21
|
-
/** The tiles held or asked for, by key, and the trees of those that came */
|
|
22
|
-
const requests = new TileRequests();
|
|
23
|
-
const found = new Map();
|
|
24
|
-
/** The trees drawn to the engine (longitude, latitude, altitude, heading, pitch, roll, scale each): all of them
|
|
25
|
-
* near the view's center, past `near` metres those of a rank under (near / distance)², at most `maxInstances` */
|
|
26
|
-
const send = () => {
|
|
27
|
-
const { center, zoom } = map.getCamera();
|
|
28
|
-
const near = TREES_NEAR_METRES * 2 ** (16 - zoom);
|
|
29
|
-
const cos = Math.cos((center[1] * Math.PI) / 180);
|
|
30
|
-
const chosen = [];
|
|
31
|
-
found.forEach((t) => {
|
|
32
|
-
for (let i = 0; i < t.length / TREE_NUMBERS; i += 1) {
|
|
33
|
-
const dx = ((t[i * TREE_NUMBERS] ?? 0) - center[0]) * METRES_PER_DEGREE * cos;
|
|
34
|
-
const dy = ((t[i * TREE_NUMBERS + 1] ?? 0) - center[1]) * METRES_PER_DEGREE;
|
|
35
|
-
const far = (dx * dx + dy * dy) / (near * near);
|
|
36
|
-
const score = (t[i * TREE_NUMBERS + 4] ?? 0) * Math.max(1, far);
|
|
37
|
-
if (score < 1)
|
|
38
|
-
chosen.push([score, t, i]);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
if (chosen.length > maxInstances)
|
|
42
|
-
chosen.sort((a, b) => a[0] - b[0]).splice(maxInstances);
|
|
43
|
-
const out = new Float64Array(chosen.length * 7);
|
|
44
|
-
chosen.forEach(([, t, i], k) => {
|
|
45
|
-
const at = i * TREE_NUMBERS;
|
|
46
|
-
out.set([t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1], k * 7);
|
|
47
|
-
});
|
|
48
|
-
layer.setInstanceNumbers(out);
|
|
49
|
-
};
|
|
50
|
-
const update = async () => {
|
|
51
|
-
if (context.destroyed())
|
|
52
|
-
return;
|
|
53
|
-
const { key, maxzoom, layers: list } = await renderer;
|
|
54
|
-
const camera = map.getCamera();
|
|
55
|
-
const z = maxzoom;
|
|
56
|
-
const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);
|
|
57
|
-
const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));
|
|
58
|
-
const metres = list.map((l) => (typeof spacing === 'number' ? spacing : spacing(l)));
|
|
59
|
-
const dropped = requests.keys().filter((k) => !keys.has(k));
|
|
60
|
-
// Out of view: dropped, or no longer asked for
|
|
61
|
-
dropped.forEach((k) => {
|
|
62
|
-
requests.drop(k);
|
|
63
|
-
found.delete(k);
|
|
64
|
-
});
|
|
65
|
-
// Dense around the new center
|
|
66
|
-
send();
|
|
67
|
-
wanted.forEach(([x, y], index) => {
|
|
68
|
-
const k = tileKey(z, x, y);
|
|
69
|
-
if (requests.has(k))
|
|
70
|
-
return;
|
|
71
|
-
const work = {
|
|
72
|
-
type: 'trees',
|
|
73
|
-
key,
|
|
74
|
-
z,
|
|
75
|
-
x,
|
|
76
|
-
y,
|
|
77
|
-
spacing: metres,
|
|
78
|
-
maxTrees,
|
|
79
|
-
priority: nearPriority(index),
|
|
80
|
-
};
|
|
81
|
-
requests.ask(k, (signal) => context.request(z, x, y, work, signal), (r) => {
|
|
82
|
-
if (!('trees' in r))
|
|
83
|
-
return;
|
|
84
|
-
found.set(k, r.trees);
|
|
85
|
-
send();
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
};
|
|
89
|
-
// While the camera moves, the trees drawn follow its center (dense near it)
|
|
90
|
-
context.followView(update, requests, send);
|
|
91
45
|
return layer;
|
|
92
46
|
};
|
|
93
47
|
//# sourceMappingURL=trees.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trees.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/trees.ts"],"names":[],"mappings":"AAAA,uHAAuH;
|
|
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"]}
|
|
@@ -2,8 +2,10 @@
|
|
|
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 type { Icons } from '../../layers/icons.ts';
|
|
5
6
|
import type { Layer } from '../../layers/layers.ts';
|
|
6
7
|
import type { VectorLayer } from '../../layers/vectors.ts';
|
|
8
|
+
import type { RoofMode } from '../../util/roofs.ts';
|
|
7
9
|
import { type Json, type StyleLayer } from '../vectorstyle.ts';
|
|
8
10
|
import type { VectorTilesContext } from './context.ts';
|
|
9
11
|
/**
|
|
@@ -11,10 +13,24 @@ import type { VectorTilesContext } from './context.ts';
|
|
|
11
13
|
* canvas's `setLineDash`; past four, the first four), zeros for a solid line
|
|
12
14
|
*/
|
|
13
15
|
export declare const dashes: (value: Json | undefined, zoom: number) => [number, number, number, number];
|
|
16
|
+
/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),
|
|
17
|
+
* not its casing, a railway, a path or a tunnel */
|
|
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
|
+
* (`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 */
|
|
22
|
+
export declare const placePatterns: (styles: Float32Array, names: readonly string[] | undefined, icons: Icons, prefix: string) => Float32Array;
|
|
23
|
+
/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */
|
|
24
|
+
export declare const translation: (value: Json | undefined, zoom: number) => [number, number];
|
|
14
25
|
/** The options of `VectorTiles.vectors` */
|
|
15
26
|
export interface VectorsOptions {
|
|
16
27
|
layers?: (layer: StyleLayer) => boolean;
|
|
17
28
|
streets?: (layer: StyleLayer) => boolean;
|
|
18
29
|
before?: Layer;
|
|
30
|
+
/** The buildings' roofs: from their data (`roof:shape`, `roof:height`; flat without, the default), generated from
|
|
31
|
+
* their outline where they have none (hipped, gabled or mansard by size and shape), or all flat */
|
|
32
|
+
roofs?: RoofMode;
|
|
33
|
+
/** The buildings' walls show their windows: glass by day, some lit at night (default false: only the lit ones) */
|
|
34
|
+
facades?: boolean;
|
|
19
35
|
}
|
|
20
36
|
export declare const vectors: (context: VectorTilesContext, options?: VectorsOptions) => VectorLayer;
|
|
@@ -2,21 +2,24 @@
|
|
|
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, STYLE } from "../../util/style-floats.js";
|
|
5
6
|
import { evaluate, isExpression, vectorKind, zoomOnly } from "../vectorstyle.js";
|
|
6
7
|
import { TileRequests } from "./requests.js";
|
|
7
8
|
import { nearPriority, parseTileKey, tileKey, tileTriples } from "./tiles.js";
|
|
8
9
|
/** The deepest level `vectors()` cuts its tiles at: past the source's deepest level, its tiles cut again into deeper
|
|
9
|
-
* ones (overzoom, as MapLibre does) down to level 18, their
|
|
10
|
+
* ones (overzoom, as MapLibre does) down to level 18, their styles those of their level, smaller tiles
|
|
10
11
|
* drawn in a closer view; past it, the tiles of that level stretched */
|
|
11
12
|
const OVERZOOM_LEVEL = 18;
|
|
12
13
|
/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */
|
|
13
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;
|
|
14
17
|
/**
|
|
15
18
|
* A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the
|
|
16
19
|
* canvas's `setLineDash`; past four, the first four), zeros for a solid line
|
|
17
20
|
*/
|
|
18
21
|
export const dashes = (value, zoom) => {
|
|
19
|
-
const v =
|
|
22
|
+
const v = atZoom(value, zoom);
|
|
20
23
|
const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];
|
|
21
24
|
const even = list.length % 2 === 1 ? [...list, ...list] : list;
|
|
22
25
|
const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];
|
|
@@ -24,19 +27,71 @@ export const dashes = (value, zoom) => {
|
|
|
24
27
|
};
|
|
25
28
|
/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),
|
|
26
29
|
* not its casing, a railway, a path or a tunnel */
|
|
27
|
-
const isStreet = (layer) => /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&
|
|
30
|
+
export const isStreet = (layer) => /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&
|
|
28
31
|
!/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);
|
|
29
32
|
/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */
|
|
30
33
|
const lineCap = (value, zoom) => {
|
|
31
|
-
const v =
|
|
34
|
+
const v = atZoom(value, zoom);
|
|
32
35
|
return v === 'round' || v === 'square' ? v : 'butt';
|
|
33
36
|
};
|
|
37
|
+
/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */
|
|
38
|
+
const lineJoin = (value, zoom) => {
|
|
39
|
+
const v = atZoom(value, zoom);
|
|
40
|
+
return v === 'round' || v === 'bevel' ? v : 'miter';
|
|
41
|
+
};
|
|
42
|
+
/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */
|
|
43
|
+
const miterLimit = (value, zoom) => {
|
|
44
|
+
const v = Number(atZoom(value, zoom) ?? 2);
|
|
45
|
+
return Number.isFinite(v) ? v : 2;
|
|
46
|
+
};
|
|
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 */
|
|
50
|
+
export const placePatterns = (styles, names, icons, prefix) => {
|
|
51
|
+
if (!names?.length)
|
|
52
|
+
return styles;
|
|
53
|
+
// Thousands of features a tile: a loop
|
|
54
|
+
for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {
|
|
55
|
+
const fill = styles[f + STYLE.fillPattern] ?? 0;
|
|
56
|
+
const line = styles[f + STYLE.linePattern] ?? 0;
|
|
57
|
+
const index = fill > 0 ? fill : line;
|
|
58
|
+
if (index <= 0)
|
|
59
|
+
continue;
|
|
60
|
+
const icon = icons.get(prefix + (names[index - 1] ?? ''));
|
|
61
|
+
const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];
|
|
62
|
+
const ratio = icon?.pixelRatio ?? 0;
|
|
63
|
+
if (fill > 0)
|
|
64
|
+
styles.set([...place, ratio], f + STYLE.size + 4);
|
|
65
|
+
else {
|
|
66
|
+
styles.set(place, f + STYLE.second);
|
|
67
|
+
styles[f + STYLE.patternRatio] = ratio;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
icons.flush();
|
|
71
|
+
return styles;
|
|
72
|
+
};
|
|
73
|
+
/** The paint properties of the patterns `vectors()` draws, whose images come from the style's sprite */
|
|
74
|
+
const PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];
|
|
75
|
+
/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */
|
|
76
|
+
export const translation = (value, zoom) => {
|
|
77
|
+
const v = atZoom(value, zoom);
|
|
78
|
+
const [x, y] = Array.isArray(v) ? v.map(Number) : [];
|
|
79
|
+
return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];
|
|
80
|
+
};
|
|
34
81
|
export const vectors = (context, options = {}) => {
|
|
35
82
|
const { map } = context;
|
|
36
|
-
const { layers = () => true, streets = isStreet, before } = options;
|
|
83
|
+
const { layers = () => true, streets = isStreet, before, roofs = 'data', facades = false } = options;
|
|
37
84
|
const vector = map.addVectorLayer(before);
|
|
85
|
+
vector.setFacades(facades);
|
|
38
86
|
const state = { renderer: context.renderer((l) => vectorKind(l) !== undefined && layers(l), []), update: 0, style: 0 };
|
|
39
87
|
state.renderer.catch(() => undefined);
|
|
88
|
+
/** The style's sprites among the map's icons, if a layer drawn has a pattern: waited for before the first tiles */
|
|
89
|
+
const sprites = context.ready
|
|
90
|
+
.then(({ style }) => style.layers.some((l) => layers(l) && PATTERNS.some((k) => l.paint?.[k] !== undefined))
|
|
91
|
+
? context.addSprites()
|
|
92
|
+
: undefined)
|
|
93
|
+
.catch(() => undefined);
|
|
94
|
+
const placed = (styles, names) => placePatterns(styles, names, map.icons, context.iconPrefix);
|
|
40
95
|
context.layers.push(vector);
|
|
41
96
|
const sublayers = (list) => {
|
|
42
97
|
const zoom = map.getCamera().zoom;
|
|
@@ -49,6 +104,11 @@ export const vectors = (context, options = {}) => {
|
|
|
49
104
|
visible: l.layout?.visibility !== 'none',
|
|
50
105
|
opacity: zoomOnly(l.paint?.[`${l.type}-opacity`], 1) ?? 1,
|
|
51
106
|
cap: lineCap(l.layout?.['line-cap'], zoom),
|
|
107
|
+
join: lineJoin(l.layout?.['line-join'], zoom),
|
|
108
|
+
miterLimit: miterLimit(l.layout?.['line-miter-limit'], zoom),
|
|
109
|
+
translate: translation(l.paint?.[`${l.type}-translate`], zoom),
|
|
110
|
+
translateAnchor: l.paint?.[`${l.type}-translate-anchor`] === 'viewport' ? 'viewport' : 'map',
|
|
111
|
+
patterned: l.paint?.['fill-pattern'] !== undefined || l.paint?.['background-pattern'] !== undefined,
|
|
52
112
|
lit: l.type === 'line' && streets(l),
|
|
53
113
|
dash: l.type === 'line' ? dashes(l.paint?.['line-dasharray'], zoom) : [0, 0, 0, 0],
|
|
54
114
|
}));
|
|
@@ -59,7 +119,7 @@ export const vectors = (context, options = {}) => {
|
|
|
59
119
|
* decoded tile its deeper tiles are cut from) */
|
|
60
120
|
const ask = ({ key, maxzoom }, [z, x, y], styles, priority, signal) => {
|
|
61
121
|
const d = Math.max(0, z - maxzoom);
|
|
62
|
-
const work = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), priority };
|
|
122
|
+
const work = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), roofs, priority };
|
|
63
123
|
// The geometry made ready for the GPU in the workers, with the prisms the relief needs
|
|
64
124
|
return context.request(z - d, Math.floor(x / 2 ** d), Math.floor(y / 2 ** d), styles ? { ...work, styles } : { ...work, prism: map.hasRelief }, signal);
|
|
65
125
|
};
|
|
@@ -70,13 +130,17 @@ export const vectors = (context, options = {}) => {
|
|
|
70
130
|
const restyleTile = async (renderer, k) => {
|
|
71
131
|
const r = await ask(renderer, parseTileKey(k), true, 'auto').catch(() => undefined);
|
|
72
132
|
if (r && 'styles' in r)
|
|
73
|
-
vector.setTileStyles(k, r.styles);
|
|
133
|
+
vector.setTileStyles(k, placed(r.styles, r.patterns));
|
|
74
134
|
};
|
|
75
135
|
const update = async () => {
|
|
76
136
|
if (context.destroyed())
|
|
77
137
|
return;
|
|
78
138
|
const generation = ++state.update;
|
|
139
|
+
// The style the tiles are cut under: that of the renderer awaited, a restyle meanwhile (a paint property set as the
|
|
140
|
+
// style loads) asking their styles again once they are there
|
|
141
|
+
const style = state.style;
|
|
79
142
|
const { key, maxzoom, layers: list } = await state.renderer;
|
|
143
|
+
await sprites;
|
|
80
144
|
vector.setSublayers(sublayers(state.own ?? list));
|
|
81
145
|
const wanted = tileTriples(map.engine.vectorTilesInView(0, deepestLevel(maxzoom)));
|
|
82
146
|
const keys = new Set(wanted.map((t) => tileKey(...t)));
|
|
@@ -84,12 +148,11 @@ export const vectors = (context, options = {}) => {
|
|
|
84
148
|
const k = tileKey(...t);
|
|
85
149
|
if (requests.has(k))
|
|
86
150
|
return [];
|
|
87
|
-
const style = state.style;
|
|
88
151
|
return [
|
|
89
152
|
requests.ask(k, (signal) => ask({ key, maxzoom }, t, false, nearPriority(index, 'high', 'auto'), signal), async (r) => {
|
|
90
153
|
if (!('vectors' in r))
|
|
91
154
|
return;
|
|
92
|
-
vector.setTile(k, r.vectors);
|
|
155
|
+
await vector.setTile(k, { ...r.vectors, styles: placed(r.vectors.styles, r.vectors.patterns) });
|
|
93
156
|
// Cut under a style changed since: its styles asked for again
|
|
94
157
|
if (style !== state.style)
|
|
95
158
|
await restyleTile(await state.renderer, k);
|
|
@@ -109,7 +172,9 @@ export const vectors = (context, options = {}) => {
|
|
|
109
172
|
});
|
|
110
173
|
};
|
|
111
174
|
drop(false);
|
|
112
|
-
|
|
175
|
+
// Every tile of the view, those an earlier update asked for too: a tile out of view stays drawn until all of them
|
|
176
|
+
// are there
|
|
177
|
+
await Promise.all([...loads, requests.answered(keys)]);
|
|
113
178
|
// A later update (the view moved again meanwhile) drops for its own view: these keys are no longer the view
|
|
114
179
|
if (!context.destroyed() && generation === state.update)
|
|
115
180
|
drop(true);
|
|
@@ -161,7 +226,7 @@ export const vectors = (context, options = {}) => {
|
|
|
161
226
|
vector.styled.catch(() => undefined);
|
|
162
227
|
// While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of
|
|
163
228
|
// its start drawn)
|
|
164
|
-
context.followView(update, requests, update);
|
|
229
|
+
context.followView(vector, update, requests, update);
|
|
165
230
|
return vector;
|
|
166
231
|
};
|
|
167
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 type { Layer } from '../../layers/layers.ts';\nimport type { VectorLayer, VectorSublayer } from '../../layers/vectors.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 filters and 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 */\nconst 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/** The options of `VectorTiles.vectors` */\nexport interface VectorsOptions {\n layers?: (layer: StyleLayer) => boolean;\n streets?: (layer: StyleLayer) => boolean;\n before?: Layer;\n}\n\nexport const vectors = (context: VectorTilesContext, options: VectorsOptions = {}): VectorLayer => {\n const { map } = context;\n const { layers = () => true, streets = isStreet, before } = options;\n const vector = map.addVectorLayer(before);\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 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 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), 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, r.styles);\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const generation = ++state.update;\n const { key, maxzoom, layers: list } = await state.renderer;\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 const style = state.style;\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 vector.setTile(k, r.vectors);\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 await Promise.all(loads);\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,7 +18,9 @@ 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';
|
|
23
|
+
import { type LampsOptions } from './vectortiles/lamps.ts';
|
|
22
24
|
import { type StreetWindLayer, type StreetWindOptions } from './vectortiles/street-wind.ts';
|
|
23
25
|
import { type LoadedStyle, OPENFREEMAP_STYLES, PLAN_STYLES, styleAttribution, VECTOR_BASEMAPS } from './vectortiles/style.ts';
|
|
24
26
|
import { type TreesOptions } from './vectortiles/trees.ts';
|
|
@@ -68,10 +70,16 @@ export declare class VectorTiles {
|
|
|
68
70
|
private sprites;
|
|
69
71
|
/** The style's sprites, kept once all of them came: one that failed is asked for again by the next layer */
|
|
70
72
|
private loadSprites;
|
|
73
|
+
/** The style's sprites added to the map's icons, once */
|
|
74
|
+
private spritesAdded;
|
|
75
|
+
/** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'
|
|
76
|
+
* patterns */
|
|
77
|
+
private addSprites;
|
|
71
78
|
/** Prefix of the names of its sprites' images among the map's icons */
|
|
72
79
|
private get iconPrefix();
|
|
73
80
|
private request;
|
|
74
|
-
/** Sends a renderer of these layers to every worker (again under
|
|
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) */
|
|
75
83
|
private renderer;
|
|
76
84
|
/**
|
|
77
85
|
* A raster layer drawing the style's fills, lines and circles (or those `layers` keeps, then `extraLayers`, of the
|
|
@@ -117,6 +125,22 @@ export declare class VectorTiles {
|
|
|
117
125
|
* engine with 3D Tiles.
|
|
118
126
|
*/
|
|
119
127
|
trees(options?: TreesOptions): ModelLayer;
|
|
128
|
+
/**
|
|
129
|
+
* Street lamps along the style's streets (the road line layers, or those `layers` keeps) as 3D models, from street
|
|
130
|
+
* level (`minZoom`, default 16): the workers place them `spacing` metres apart (default 30) along each street, every
|
|
131
|
+
* other one on its other side, as far from its middle as its class says; their heads lit at night (`light`). All of
|
|
132
|
+
* them near the ground under the camera, fewer and fewer away from it, at most `maxInstances` drawn (default 15000).
|
|
133
|
+
* The models load the engine with 3D Tiles.
|
|
134
|
+
*/
|
|
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;
|
|
120
144
|
/**
|
|
121
145
|
* A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the
|
|
122
146
|
* `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the
|
|
@@ -125,11 +149,15 @@ export declare class VectorTiles {
|
|
|
125
149
|
* and pitch, picked by feature (`pick` gives its properties and style layer), restyled without cutting the tiles
|
|
126
150
|
* again (`setPaintProperty`, `setLayoutProperty`). Its tiles follow the view, while it moves too, coarser far away in a
|
|
127
151
|
* tilted view, and those leaving it stay until the ones replacing them are there; past the source's deepest level,
|
|
128
|
-
* cut again from its tiles down to level 18 (overzoom: their
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* `line-
|
|
132
|
-
*
|
|
152
|
+
* cut again from its tiles down to level 18 (overzoom: their styles those of their level; a filter reading the zoom
|
|
153
|
+
* holds at the whole zoom under the camera's, as MapLibre evaluates it). The fills' outlines are drawn one
|
|
154
|
+
* pixel wide, the lines' ends as their `line-cap` says, their joins as their `line-join` says (and `line-miter-limit`),
|
|
155
|
+
* offset by `line-offset`; the colors follow the camera's zoom; the fills', lines' and buildings' patterns from the
|
|
156
|
+
* style's sprite (the fills' over the relief too; on the globe, their average color there), the circle layers' points
|
|
157
|
+
* as circles facing the screen, the lines' blur, the fills' and lines' translations. The buildings' roofs (`roofs`)
|
|
158
|
+
* as their data says (`roof:shape`, `roof:height`; flat without, the default), generated from their outline where
|
|
159
|
+
* they have none (`'generated'`), or all flat. `raster` stays the lighter path for heavy styles and small devices.
|
|
160
|
+
* At night (`setSun`) the line layers `streets` keeps glow (by default those whose id names
|
|
133
161
|
* a road, not its casing, a railway, a path or a tunnel).
|
|
134
162
|
*/
|
|
135
163
|
vectors(options?: VectorsOptions): VectorLayer;
|
|
@@ -143,9 +171,11 @@ export declare class VectorTiles {
|
|
|
143
171
|
labels(options?: LabelsOptions): SymbolLayer<LabelCandidate>;
|
|
144
172
|
/**
|
|
145
173
|
* Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every
|
|
146
|
-
* `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
|
|
147
175
|
*/
|
|
148
176
|
private followView;
|
|
177
|
+
/** Calls `stop` when destroyed or once `layer` is removed, whichever comes first */
|
|
178
|
+
private stopWith;
|
|
149
179
|
/** Stops its workers' work and removes its raster and label layers from the map (those still there) */
|
|
150
180
|
destroy(): void;
|
|
151
181
|
}
|