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
package/dist/basemap/trees.d.ts
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The trees of a vector map (`VectorTiles.trees`):
|
|
3
|
-
*
|
|
2
|
+
* The trees of a vector map (`VectorTiles.trees`): low-poly trees made here as glTF binaries (no file to download), a
|
|
3
|
+
* broadleaved one and a conifer, their trunk and crown flat-shaded in their colors; the style layers they grow on by
|
|
4
|
+
* default, and the share of conifers in a wood from its data.
|
|
4
5
|
*/
|
|
6
|
+
import type { Value } from './mvt.ts';
|
|
5
7
|
import type { StyleLayer } from './vectorstyle.ts';
|
|
6
|
-
/**
|
|
7
|
-
export declare const TREE_NUMBERS = 5;
|
|
8
|
-
/** Colors of the trunk and of the crown (linear RGBA, as glTF's `baseColorFactor`) */
|
|
8
|
+
/** Colors of the trunk, of the broadleaved crown and of the conifers' (linear RGBA, as glTF's `baseColorFactor`) */
|
|
9
9
|
export interface TreeColors {
|
|
10
10
|
trunk: [number, number, number, number];
|
|
11
11
|
crown: [number, number, number, number];
|
|
12
|
+
conifer: [number, number, number, number];
|
|
12
13
|
}
|
|
14
|
+
/** The models' heights (metres): a tree's height from its data scales them by it */
|
|
15
|
+
export declare const TREE_METRES: {
|
|
16
|
+
readonly broadleaved: 10.2;
|
|
17
|
+
readonly conifer: 11;
|
|
18
|
+
};
|
|
13
19
|
/**
|
|
14
|
-
* A tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors
|
|
15
|
-
*
|
|
20
|
+
* A broadleaved tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`; `far`: the
|
|
21
|
+
* same simplified for far away, a few faces (some 30 triangles instead of 100)
|
|
16
22
|
*/
|
|
17
|
-
export declare const treeModel: (colors?: Partial<TreeColors
|
|
23
|
+
export declare const treeModel: (colors?: Partial<TreeColors>, far?: boolean) => Uint8Array<ArrayBuffer>;
|
|
24
|
+
/**
|
|
25
|
+
* A conifer as a glTF binary, about 11 metres high: a trunk and three cones one over the other in `colors`; `far`: one
|
|
26
|
+
* pyramid on a trunk of three faces for far away (some 17 triangles instead of 63)
|
|
27
|
+
*/
|
|
28
|
+
export declare const coniferModel: (colors?: Partial<TreeColors>, far?: boolean) => Uint8Array<ArrayBuffer>;
|
|
18
29
|
/**
|
|
19
30
|
* Whether trees grow on a style layer by default: the woods and forests of the style's fills (OpenMapTiles'
|
|
20
31
|
* `landcover` wood, PLAN IGN's forests) and the grass of its parks and gardens; not the wooded relief of PLAN IGN,
|
|
@@ -24,3 +35,9 @@ export declare const treeModel: (colors?: Partial<TreeColors>) => Uint8Array<Arr
|
|
|
24
35
|
export declare const isWoodland: (layer: StyleLayer) => boolean;
|
|
25
36
|
/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */
|
|
26
37
|
export declare const treeSpacing: (layer: StyleLayer) => number;
|
|
38
|
+
/**
|
|
39
|
+
* The share of conifers in a wood from its properties: OpenStreetMap's `leaf_type` (needleleaved, broadleaved,
|
|
40
|
+
* mixed), PLAN IGN's `nature` (« conifères », « feuillus », « mixte »); without them, OpenMapTiles' forests a third
|
|
41
|
+
* conifers and its other woods some, the grass of parks none
|
|
42
|
+
*/
|
|
43
|
+
export declare const coniferShare: (properties: Record<string, Value>) => number;
|
package/dist/basemap/trees.js
CHANGED
|
@@ -1,129 +1,83 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The trees of a vector map (`VectorTiles.trees`):
|
|
3
|
-
*
|
|
2
|
+
* The trees of a vector map (`VectorTiles.trees`): low-poly trees made here as glTF binaries (no file to download), a
|
|
3
|
+
* broadleaved one and a conifer, their trunk and crown flat-shaded in their colors; the style layers they grow on by
|
|
4
|
+
* default, and the share of conifers in a wood from its data.
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/** Sides of the trunk and of the crown */
|
|
6
|
+
import { glb, join, revolve } from "./meshes.js";
|
|
7
|
+
/** Sides of the trunk and of the crown near the view; of the crown far away (a pyramid), of the trunk there */
|
|
8
8
|
const SIDES = 7;
|
|
9
|
+
const FAR_SIDES = 4;
|
|
10
|
+
const FAR_TRUNK_SIDES = 3;
|
|
11
|
+
/** The models' heights (metres): a tree's height from its data scales them by it */
|
|
12
|
+
export const TREE_METRES = { broadleaved: 10.2, conifer: 11 };
|
|
9
13
|
const DEFAULT_COLORS = {
|
|
10
14
|
trunk: [0.2, 0.12, 0.07, 1],
|
|
11
15
|
crown: [0.12, 0.27, 0.08, 1],
|
|
12
|
-
|
|
13
|
-
/** A solid of revolution around the vertical (glTF +Y up), flat-shaded: rings of (height, radius), a point at the
|
|
14
|
-
* top when its radius is 0; the triangles' positions and normals, one normal per face */
|
|
15
|
-
const revolve = (rings) => {
|
|
16
|
-
const at = (k, [h, r]) => {
|
|
17
|
-
const a = (k / SIDES) * Math.PI * 2;
|
|
18
|
-
return [Math.cos(a) * r, h, Math.sin(a) * r];
|
|
19
|
-
};
|
|
20
|
-
const positions = [];
|
|
21
|
-
const normals = [];
|
|
22
|
-
const face = (a, b, c) => {
|
|
23
|
-
const u = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
|
|
24
|
-
const v = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
|
|
25
|
-
const n = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];
|
|
26
|
-
const length = Math.hypot(...n);
|
|
27
|
-
// A degenerate face (two points at the apex) is left out
|
|
28
|
-
if (length === 0)
|
|
29
|
-
return;
|
|
30
|
-
positions.push(...a, ...b, ...c);
|
|
31
|
-
[0, 1, 2].forEach(() => {
|
|
32
|
-
normals.push(n[0] / length, n[1] / length, n[2] / length);
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
rings.slice(1).forEach((ring, i) => {
|
|
36
|
-
const below = rings[i] ?? ring;
|
|
37
|
-
Array.from({ length: SIDES }, (_, k) => k).forEach((k) => {
|
|
38
|
-
const [a, b] = [at(k, below), at(k + 1, below)];
|
|
39
|
-
const [c, d] = [at(k, ring), at(k + 1, ring)];
|
|
40
|
-
// Counter-clockwise seen from outside
|
|
41
|
-
face(a, c, b);
|
|
42
|
-
face(b, c, d);
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
// The bottom closed: seen from below
|
|
46
|
-
const base = rings[0];
|
|
47
|
-
if (base && base[1] > 0) {
|
|
48
|
-
Array.from({ length: SIDES }, (_, k) => k).forEach((k) => {
|
|
49
|
-
face([0, base[0], 0], at(k, base), at(k + 1, base));
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
return { positions, normals };
|
|
53
|
-
};
|
|
54
|
-
/** Lowest and highest of interleaved x, y, z (glTF needs them on positions) */
|
|
55
|
-
const bounds = (xyz) => {
|
|
56
|
-
const axes = [0, 1, 2].map((a) => xyz.filter((_, i) => i % 3 === a));
|
|
57
|
-
return { min: axes.map((v) => Math.min(...v)), max: axes.map((v) => Math.max(...v)) };
|
|
16
|
+
conifer: [0.05, 0.16, 0.08, 1],
|
|
58
17
|
};
|
|
59
18
|
/**
|
|
60
|
-
* A tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors
|
|
61
|
-
*
|
|
19
|
+
* A broadleaved tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`; `far`: the
|
|
20
|
+
* same simplified for far away, a few faces (some 30 triangles instead of 100)
|
|
62
21
|
*/
|
|
63
|
-
export const treeModel = (colors = {}) => {
|
|
22
|
+
export const treeModel = (colors = {}, far = false) => {
|
|
64
23
|
const { trunk, crown } = { ...DEFAULT_COLORS, ...colors };
|
|
24
|
+
if (far) {
|
|
25
|
+
const stem = revolve([
|
|
26
|
+
[0, 0.3],
|
|
27
|
+
[3, 0.22],
|
|
28
|
+
], FAR_TRUNK_SIDES);
|
|
29
|
+
const top = revolve([
|
|
30
|
+
[2.4, 0.8],
|
|
31
|
+
[5.6, 2.9],
|
|
32
|
+
[TREE_METRES.broadleaved, 0],
|
|
33
|
+
], FAR_SIDES);
|
|
34
|
+
return glb([stem, top], [trunk, crown]);
|
|
35
|
+
}
|
|
65
36
|
const parts = [
|
|
66
37
|
revolve([
|
|
67
38
|
[0, 0.28],
|
|
68
39
|
[3.2, 0.2],
|
|
69
|
-
]),
|
|
40
|
+
], SIDES),
|
|
70
41
|
revolve([
|
|
71
42
|
[2.4, 0.6],
|
|
72
43
|
[3.6, 2.4],
|
|
73
44
|
[5.6, 2.9],
|
|
74
45
|
[7.8, 2.3],
|
|
75
46
|
[9.4, 1.1],
|
|
76
|
-
[
|
|
77
|
-
]),
|
|
47
|
+
[TREE_METRES.broadleaved, 0],
|
|
48
|
+
], SIDES),
|
|
78
49
|
];
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// The chunks padded to 4 bytes: the JSON with spaces, the binary with zeros
|
|
111
|
-
const json = new TextEncoder().encode(JSON.stringify(gltf));
|
|
112
|
-
const jsonLength = Math.ceil(json.length / 4) * 4;
|
|
113
|
-
const binLength = Math.ceil(bin.byteLength / 4) * 4;
|
|
114
|
-
const out = new Uint8Array(12 + 8 + jsonLength + 8 + binLength);
|
|
115
|
-
const view = new DataView(out.buffer);
|
|
116
|
-
view.setUint32(0, 0x46546c67, true);
|
|
117
|
-
view.setUint32(4, 2, true);
|
|
118
|
-
view.setUint32(8, out.length, true);
|
|
119
|
-
view.setUint32(12, jsonLength, true);
|
|
120
|
-
view.setUint32(16, 0x4e4f534a, true);
|
|
121
|
-
out.fill(0x20, 20, 20 + jsonLength);
|
|
122
|
-
out.set(json, 20);
|
|
123
|
-
view.setUint32(20 + jsonLength, binLength, true);
|
|
124
|
-
view.setUint32(24 + jsonLength, 0x004e4942, true);
|
|
125
|
-
out.set(new Uint8Array(bin.buffer), 28 + jsonLength);
|
|
126
|
-
return out;
|
|
50
|
+
return glb(parts, [trunk, crown]);
|
|
51
|
+
};
|
|
52
|
+
/** A cone of the conifers' crown: from `base` metres up, `radius` wide, to its point at `top` */
|
|
53
|
+
const cone = (base, radius, top) => revolve([
|
|
54
|
+
[base, radius],
|
|
55
|
+
[top, 0],
|
|
56
|
+
], SIDES);
|
|
57
|
+
/**
|
|
58
|
+
* A conifer as a glTF binary, about 11 metres high: a trunk and three cones one over the other in `colors`; `far`: one
|
|
59
|
+
* pyramid on a trunk of three faces for far away (some 17 triangles instead of 63)
|
|
60
|
+
*/
|
|
61
|
+
export const coniferModel = (colors = {}, far = false) => {
|
|
62
|
+
const { trunk, conifer } = { ...DEFAULT_COLORS, ...colors };
|
|
63
|
+
if (far) {
|
|
64
|
+
const stem = revolve([
|
|
65
|
+
[0, 0.24],
|
|
66
|
+
[2, 0.18],
|
|
67
|
+
], FAR_TRUNK_SIDES);
|
|
68
|
+
const top = revolve([
|
|
69
|
+
[1.4, 2.3],
|
|
70
|
+
[TREE_METRES.conifer, 0],
|
|
71
|
+
], FAR_SIDES);
|
|
72
|
+
return glb([stem, top], [trunk, conifer]);
|
|
73
|
+
}
|
|
74
|
+
const tiers = [cone(1.4, 2.4, 5.4), cone(3.6, 1.9, 8), cone(6, 1.3, TREE_METRES.conifer)];
|
|
75
|
+
const crown = join(...tiers);
|
|
76
|
+
const stem = revolve([
|
|
77
|
+
[0, 0.24],
|
|
78
|
+
[2, 0.18],
|
|
79
|
+
], SIDES);
|
|
80
|
+
return glb([stem, crown], [trunk, conifer]);
|
|
127
81
|
};
|
|
128
82
|
/** Whether a style layer is OpenMapTiles' grass (the lawns of parks and gardens among it) */
|
|
129
83
|
const isGrass = (layer) => layer['source-layer'] === 'landcover' && /grass/i.test(layer.id);
|
|
@@ -138,4 +92,22 @@ export const isWoodland = (layer) => layer.type === 'fill' &&
|
|
|
138
92
|
(/wood|forest|for[eê]t/i.test(layer.id) || isGrass(layer));
|
|
139
93
|
/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */
|
|
140
94
|
export const treeSpacing = (layer) => (isGrass(layer) ? 25 : 9);
|
|
95
|
+
/**
|
|
96
|
+
* The share of conifers in a wood from its properties: OpenStreetMap's `leaf_type` (needleleaved, broadleaved,
|
|
97
|
+
* mixed), PLAN IGN's `nature` (« conifères », « feuillus », « mixte »); without them, OpenMapTiles' forests a third
|
|
98
|
+
* conifers and its other woods some, the grass of parks none
|
|
99
|
+
*/
|
|
100
|
+
export const coniferShare = (properties) => {
|
|
101
|
+
const leaf = properties.leaf_type;
|
|
102
|
+
const nature = typeof properties.nature === 'string' ? properties.nature : '';
|
|
103
|
+
if (leaf === 'needleleaved' || /conif/i.test(nature))
|
|
104
|
+
return 1;
|
|
105
|
+
if (leaf === 'broadleaved' || /feuillu/i.test(nature))
|
|
106
|
+
return 0;
|
|
107
|
+
if (leaf === 'mixed' || /mixte/i.test(nature))
|
|
108
|
+
return 0.5;
|
|
109
|
+
if (properties.class === 'wood')
|
|
110
|
+
return properties.subclass === 'forest' ? 0.35 : 0.15;
|
|
111
|
+
return 0;
|
|
112
|
+
};
|
|
141
113
|
//# sourceMappingURL=trees.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trees.js","sourceRoot":"","sources":["../../src/basemap/trees.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The trees of a vector map (`VectorTiles.trees`): a low-poly tree made here as a glTF binary (no file to download),\n * its trunk and its crown flat-shaded in their colors, and the style layers they grow on by default.\n */\n\nimport type { StyleLayer } from './vectorstyle.ts';\n\n/** Numbers of a tree in the workers' answer: longitude, latitude, scale, heading, rank */\nexport const TREE_NUMBERS = 5;\n\n/** A point or a vector: x, y, z */\ntype Vec3 = [number, number, number];\n\n/** Sides of the trunk and of the crown */\nconst SIDES = 7;\n\n/** Colors of the trunk and of the crown (linear RGBA, as glTF's `baseColorFactor`) */\nexport interface TreeColors {\n trunk: [number, number, number, number];\n crown: [number, number, number, number];\n}\n\nconst DEFAULT_COLORS: TreeColors = {\n trunk: [0.2, 0.12, 0.07, 1],\n crown: [0.12, 0.27, 0.08, 1],\n};\n\n/** A solid of revolution around the vertical (glTF +Y up), flat-shaded: rings of (height, radius), a point at the\n * top when its radius is 0; the triangles' positions and normals, one normal per face */\nconst revolve = (rings: [height: number, radius: number][]): { positions: number[]; normals: number[] } => {\n const at = (k: number, [h, r]: [number, number]): Vec3 => {\n const a = (k / SIDES) * Math.PI * 2;\n\n return [Math.cos(a) * r, h, Math.sin(a) * r];\n };\n const positions: number[] = [];\n const normals: number[] = [];\n const face = (a: Vec3, b: Vec3, c: Vec3) => {\n const u: Vec3 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];\n const v: Vec3 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];\n const n: Vec3 = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];\n const length = Math.hypot(...n);\n\n // A degenerate face (two points at the apex) is left out\n if (length === 0) return;\n positions.push(...a, ...b, ...c);\n [0, 1, 2].forEach(() => {\n normals.push(n[0] / length, n[1] / length, n[2] / length);\n });\n };\n\n rings.slice(1).forEach((ring, i) => {\n const below = rings[i] ?? ring;\n\n Array.from({ length: SIDES }, (_, k) => k).forEach((k) => {\n const [a, b] = [at(k, below), at(k + 1, below)];\n const [c, d] = [at(k, ring), at(k + 1, ring)];\n\n // Counter-clockwise seen from outside\n face(a, c, b);\n face(b, c, d);\n });\n });\n // The bottom closed: seen from below\n const base = rings[0];\n\n if (base && base[1] > 0) {\n Array.from({ length: SIDES }, (_, k) => k).forEach((k) => {\n face([0, base[0], 0], at(k, base), at(k + 1, base));\n });\n }\n\n return { positions, normals };\n};\n\n/** Lowest and highest of interleaved x, y, z (glTF needs them on positions) */\nconst bounds = (xyz: number[]): { min: number[]; max: number[] } => {\n const axes = [0, 1, 2].map((a) => xyz.filter((_, i) => i % 3 === a));\n\n return { min: axes.map((v) => Math.min(...v)), max: axes.map((v) => Math.max(...v)) };\n};\n\n/**\n * A tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`, one mesh of two primitives,\n * its front +Z (`ModelInstance.heading` turns it), standing on its origin\n */\nexport const treeModel = (colors: Partial<TreeColors> = {}): Uint8Array<ArrayBuffer> => {\n const { trunk, crown } = { ...DEFAULT_COLORS, ...colors };\n const parts = [\n revolve([\n [0, 0.28],\n [3.2, 0.2],\n ]),\n revolve([\n [2.4, 0.6],\n [3.6, 2.4],\n [5.6, 2.9],\n [7.8, 2.3],\n [9.4, 1.1],\n [10.2, 0],\n ]),\n ];\n // The buffer: each part's positions then normals, 4-byte floats\n const floats = parts.flatMap((p) => [...p.positions, ...p.normals]);\n const bin = new Float32Array(floats);\n const views = parts.flatMap((p, i) => {\n const before = parts.slice(0, i).reduce((n, q) => n + (q.positions.length + q.normals.length) * 4, 0);\n\n return [\n { buffer: 0, byteOffset: before, byteLength: p.positions.length * 4, target: 34962 },\n { buffer: 0, byteOffset: before + p.positions.length * 4, byteLength: p.normals.length * 4, target: 34962 },\n ];\n });\n const accessors = parts.flatMap((p, i) => [\n { bufferView: i * 2, componentType: 5126, count: p.positions.length / 3, type: 'VEC3', ...bounds(p.positions) },\n { bufferView: i * 2 + 1, componentType: 5126, count: p.normals.length / 3, type: 'VEC3' },\n ]);\n const gltf = {\n asset: { version: '2.0', generator: 'isard' },\n scene: 0,\n scenes: [{ nodes: [0] }],\n nodes: [{ mesh: 0 }],\n meshes: [\n {\n primitives: parts.map((_, i) => ({ attributes: { POSITION: i * 2, NORMAL: i * 2 + 1 }, material: i })),\n },\n ],\n materials: [trunk, crown].map((color) => ({\n pbrMetallicRoughness: { baseColorFactor: color, metallicFactor: 0, roughnessFactor: 1 },\n })),\n accessors,\n bufferViews: views,\n buffers: [{ byteLength: bin.byteLength }],\n };\n // The chunks padded to 4 bytes: the JSON with spaces, the binary with zeros\n const json = new TextEncoder().encode(JSON.stringify(gltf));\n const jsonLength = Math.ceil(json.length / 4) * 4;\n const binLength = Math.ceil(bin.byteLength / 4) * 4;\n const out = new Uint8Array(12 + 8 + jsonLength + 8 + binLength);\n const view = new DataView(out.buffer);\n\n view.setUint32(0, 0x46546c67, true);\n view.setUint32(4, 2, true);\n view.setUint32(8, out.length, true);\n view.setUint32(12, jsonLength, true);\n view.setUint32(16, 0x4e4f534a, true);\n out.fill(0x20, 20, 20 + jsonLength);\n out.set(json, 20);\n view.setUint32(20 + jsonLength, binLength, true);\n view.setUint32(24 + jsonLength, 0x004e4942, true);\n out.set(new Uint8Array(bin.buffer), 28 + jsonLength);\n\n return out;\n};\n\n/** Whether a style layer is OpenMapTiles' grass (the lawns of parks and gardens among it) */\nconst isGrass = (layer: StyleLayer): boolean => layer['source-layer'] === 'landcover' && /grass/i.test(layer.id);\n\n/**\n * Whether trees grow on a style layer by default: the woods and forests of the style's fills (OpenMapTiles'\n * `landcover` wood, PLAN IGN's forests) and the grass of its parks and gardens; not the wooded relief of PLAN IGN,\n * which repeats its forests, nor OpenMapTiles' `park` layer (protected areas and historic sites: a river's banks\n * among them)\n */\nexport const isWoodland = (layer: StyleLayer): boolean =>\n layer.type === 'fill' &&\n layer['source-layer'] !== 'oro_relief' &&\n (/wood|forest|for[eê]t/i.test(layer.id) || isGrass(layer));\n\n/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */\nexport const treeSpacing = (layer: StyleLayer): number => (isGrass(layer) ? 25 : 9);\n"]}
|
|
1
|
+
{"version":3,"file":"trees.js","sourceRoot":"","sources":["../../src/basemap/trees.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The trees of a vector map (`VectorTiles.trees`): low-poly trees made here as glTF binaries (no file to download), a\n * broadleaved one and a conifer, their trunk and crown flat-shaded in their colors; the style layers they grow on by\n * default, and the share of conifers in a wood from its data.\n */\n\nimport { glb, join, revolve } from './meshes.ts';\nimport type { Value } from './mvt.ts';\nimport type { StyleLayer } from './vectorstyle.ts';\n\n/** Sides of the trunk and of the crown near the view; of the crown far away (a pyramid), of the trunk there */\nconst SIDES = 7;\nconst FAR_SIDES = 4;\nconst FAR_TRUNK_SIDES = 3;\n\n/** Colors of the trunk, of the broadleaved crown and of the conifers' (linear RGBA, as glTF's `baseColorFactor`) */\nexport interface TreeColors {\n trunk: [number, number, number, number];\n crown: [number, number, number, number];\n conifer: [number, number, number, number];\n}\n\n/** The models' heights (metres): a tree's height from its data scales them by it */\nexport const TREE_METRES = { broadleaved: 10.2, conifer: 11 } as const;\n\nconst DEFAULT_COLORS: TreeColors = {\n trunk: [0.2, 0.12, 0.07, 1],\n crown: [0.12, 0.27, 0.08, 1],\n conifer: [0.05, 0.16, 0.08, 1],\n};\n\n/**\n * A broadleaved tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`; `far`: the\n * same simplified for far away, a few faces (some 30 triangles instead of 100)\n */\nexport const treeModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, crown } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.3],\n [3, 0.22],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [2.4, 0.8],\n [5.6, 2.9],\n [TREE_METRES.broadleaved, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, crown]);\n }\n\n const parts = [\n revolve(\n [\n [0, 0.28],\n [3.2, 0.2],\n ],\n SIDES,\n ),\n revolve(\n [\n [2.4, 0.6],\n [3.6, 2.4],\n [5.6, 2.9],\n [7.8, 2.3],\n [9.4, 1.1],\n [TREE_METRES.broadleaved, 0],\n ],\n SIDES,\n ),\n ];\n\n return glb(parts, [trunk, crown]);\n};\n\n/** A cone of the conifers' crown: from `base` metres up, `radius` wide, to its point at `top` */\nconst cone = (base: number, radius: number, top: number) =>\n revolve(\n [\n [base, radius],\n [top, 0],\n ],\n SIDES,\n );\n\n/**\n * A conifer as a glTF binary, about 11 metres high: a trunk and three cones one over the other in `colors`; `far`: one\n * pyramid on a trunk of three faces for far away (some 17 triangles instead of 63)\n */\nexport const coniferModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, conifer } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.24],\n [2, 0.18],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [1.4, 2.3],\n [TREE_METRES.conifer, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, conifer]);\n }\n const tiers = [cone(1.4, 2.4, 5.4), cone(3.6, 1.9, 8), cone(6, 1.3, TREE_METRES.conifer)];\n const crown = join(...tiers);\n const stem = revolve(\n [\n [0, 0.24],\n [2, 0.18],\n ],\n SIDES,\n );\n\n return glb([stem, crown], [trunk, conifer]);\n};\n\n/** Whether a style layer is OpenMapTiles' grass (the lawns of parks and gardens among it) */\nconst isGrass = (layer: StyleLayer): boolean => layer['source-layer'] === 'landcover' && /grass/i.test(layer.id);\n\n/**\n * Whether trees grow on a style layer by default: the woods and forests of the style's fills (OpenMapTiles'\n * `landcover` wood, PLAN IGN's forests) and the grass of its parks and gardens; not the wooded relief of PLAN IGN,\n * which repeats its forests, nor OpenMapTiles' `park` layer (protected areas and historic sites: a river's banks\n * among them)\n */\nexport const isWoodland = (layer: StyleLayer): boolean =>\n layer.type === 'fill' &&\n layer['source-layer'] !== 'oro_relief' &&\n (/wood|forest|for[eê]t/i.test(layer.id) || isGrass(layer));\n\n/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */\nexport const treeSpacing = (layer: StyleLayer): number => (isGrass(layer) ? 25 : 9);\n\n/**\n * The share of conifers in a wood from its properties: OpenStreetMap's `leaf_type` (needleleaved, broadleaved,\n * mixed), PLAN IGN's `nature` (« conifères », « feuillus », « mixte »); without them, OpenMapTiles' forests a third\n * conifers and its other woods some, the grass of parks none\n */\nexport const coniferShare = (properties: Record<string, Value>): number => {\n const leaf = properties.leaf_type;\n const nature = typeof properties.nature === 'string' ? properties.nature : '';\n\n if (leaf === 'needleleaved' || /conif/i.test(nature)) return 1;\n if (leaf === 'broadleaved' || /feuillu/i.test(nature)) return 0;\n if (leaf === 'mixed' || /mixte/i.test(nature)) return 0.5;\n if (properties.class === 'wood') return properties.subclass === 'forest' ? 0.35 : 0.15;\n\n return 0;\n};\n"]}
|
|
@@ -70,10 +70,15 @@ export interface LabelCandidate {
|
|
|
70
70
|
lat: number;
|
|
71
71
|
/** On a line: the direction there (degrees of longitude and latitude) */
|
|
72
72
|
along?: [number, number];
|
|
73
|
+
/** A text along a line: the line around it (longitudes and latitudes interleaved), as long before it as after it,
|
|
74
|
+
* for the text to follow its bends */
|
|
75
|
+
path?: number[];
|
|
73
76
|
/** Its text runs along the line (`symbol-placement: line`, `text-rotation-alignment` not `viewport`) */
|
|
74
77
|
textAlong?: boolean;
|
|
75
78
|
textOptional?: boolean;
|
|
76
79
|
icon?: CandidateIcon;
|
|
80
|
+
/** Metres over the ground: a point in a building of the style's, on its roof */
|
|
81
|
+
height?: number;
|
|
77
82
|
font: string;
|
|
78
83
|
size: Json;
|
|
79
84
|
color: string;
|
|
@@ -100,10 +105,11 @@ export declare const css: ([r, g, b, a]: [number, number, number, number]) => st
|
|
|
100
105
|
export declare const isExpression: (e: unknown) => e is Json[];
|
|
101
106
|
export declare const evaluate: (e: Json, ctx: Context) => unknown;
|
|
102
107
|
/** The kind of geometry a style layer is drawn with as vectors (`vectors()`: backgrounds as fills, extrusions raised
|
|
103
|
-
* into blocks); undefined for the others (symbols,
|
|
104
|
-
|
|
105
|
-
export declare const vectorKind: (layer: StyleLayer) => "fill" | "line" | "extrusion" | undefined;
|
|
108
|
+
* into blocks, circles); undefined for the others (symbols, rasters) */
|
|
109
|
+
export declare const vectorKind: (layer: StyleLayer) => "fill" | "line" | "extrusion" | "circle" | undefined;
|
|
106
110
|
export declare const filter: (f: Json | undefined, ctx: Context) => boolean;
|
|
111
|
+
/** Whether an expression reads the zoom (a filter that does holds at some zooms only) */
|
|
112
|
+
export declare const usesZoom: (e: Json | undefined) => boolean;
|
|
107
113
|
/** Whether a value depends on the feature (else only on the zoom, evaluated once per tile) */
|
|
108
114
|
export declare const isFeatureDependent: (e: Json | undefined) => boolean;
|
|
109
115
|
/** A `{token}` text field (or an expression) to the text of a feature */
|
|
@@ -396,17 +396,14 @@ export const evaluate = (e, ctx) => {
|
|
|
396
396
|
// ── Filters ──
|
|
397
397
|
const LEGACY_COMPARISONS = new Set(['==', '!=', '<', '<=', '>', '>=']);
|
|
398
398
|
/** The kind of geometry a style layer is drawn with as vectors (`vectors()`: backgrounds as fills, extrusions raised
|
|
399
|
-
* into blocks); undefined for the others (symbols,
|
|
400
|
-
* images are the raster path's) */
|
|
399
|
+
* into blocks, circles); undefined for the others (symbols, rasters) */
|
|
401
400
|
export const vectorKind = (layer) => {
|
|
402
|
-
const paint = layer.paint ?? {};
|
|
403
|
-
if (['fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'background-pattern'].some((k) => k in paint)) {
|
|
404
|
-
return undefined;
|
|
405
|
-
}
|
|
406
401
|
if (layer.type === 'line')
|
|
407
402
|
return 'line';
|
|
408
403
|
if (layer.type === 'fill-extrusion')
|
|
409
404
|
return 'extrusion';
|
|
405
|
+
if (layer.type === 'circle')
|
|
406
|
+
return 'circle';
|
|
410
407
|
return layer.type === 'fill' || layer.type === 'background' ? 'fill' : undefined;
|
|
411
408
|
};
|
|
412
409
|
/** Whether a filter (not `all`, `any`, `none`) is in the legacy form: `["==", "key", value]`, `["in", "key", a, b]`,
|
|
@@ -478,6 +475,8 @@ export const filter = (f, ctx) => {
|
|
|
478
475
|
return true;
|
|
479
476
|
return compile(f)(ctx);
|
|
480
477
|
};
|
|
478
|
+
/** Whether an expression reads the zoom (a filter that does holds at some zooms only) */
|
|
479
|
+
export const usesZoom = (e) => Array.isArray(e) && (e[0] === 'zoom' || e.some(usesZoom));
|
|
481
480
|
/** The operators that read the feature */
|
|
482
481
|
const FEATURE_OPERATORS = new Set(['get', 'has', '!has', 'geometry-type', 'properties', 'id']);
|
|
483
482
|
/** Whether a value depends on the feature (else only on the zoom, evaluated once per tile) */
|