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/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,220 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
Every notable change of `isard
|
|
3
|
+
Every notable change of `isard`. The format follows [Keep a Changelog](https://keepachangelog.com), the
|
|
4
4
|
versions [Semantic Versioning](https://semver.org) (before 1.0.0, a minor version may change an API).
|
|
5
5
|
|
|
6
|
+
## [1.7.0] - 2026-10-26
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- 360° photos at street level: `addPanoramas({ photos })` takes equirectangular images (where each was taken, the way
|
|
11
|
+
its middle faces), projected onto the scene around and walked along as a vehicle's panoramas are (the engine's
|
|
12
|
+
panorama pass: a camera without focal read as equirectangular). `panoramaxSequence` reads a Panoramax sequence's
|
|
13
|
+
photos in their order, `panoramaxPanoramas` gives its 360° ones; in the Panoramax example, From there on a 360° photo
|
|
14
|
+
walks in its sequence (the wheel, Z and S).
|
|
15
|
+
- The BD TOPO's roofs at their height: `bdtopoRoofs()` raises a building to its ridge under a roof from its eaves to
|
|
16
|
+
its ridge (`altitude_minimale_toit`, `altitude_maximale_toit`; flat under half a metre) where the BD TOPO gives them
|
|
17
|
+
(most of the towns, not Paris yet), else to its `hauteur` (its eaves) under a roof generated within;
|
|
18
|
+
`bdtopoBuildings` uses it, as the Buildings examples do (the React one now with roofs too).
|
|
19
|
+
- Street furniture: `tiles.furniture()` places, from OpenMapTiles' points of interest of the street, a bus shelter at
|
|
20
|
+
each bus stop, waste baskets, post boxes, drinking fountains (Wallace's) and bicycle racks, each facing the nearest
|
|
21
|
+
street, and benches along the pedestrian streets and the paths of the parks and gardens; made here as glTF models
|
|
22
|
+
(no file to download), one instanced draw a kind, all of them near the camera and fewer away from it. The street lamps and the furniture share their placing
|
|
23
|
+
(`placed`: the workers' things around the view); a model's translucent color is blended. The 3D vector examples show
|
|
24
|
+
them. About 0.7 KB gzipped more for the basemap worker.
|
|
25
|
+
|
|
26
|
+
- React: `<VectorTiles>` holds the vector tiles of a style, its children drawing from them with one set of tiles and
|
|
27
|
+
workers: `<Geometry>`, `<Trees>`, `<Lamps>`, `<Furniture>`, `<Extrusions>`, `<Labels>`, their options as props
|
|
28
|
+
(compared by value: an object written inline keeps the layer); `useVectorTiles()` for a part of your own. The React
|
|
29
|
+
examples drop their components of an effect and a second `vectorTiles()` of the same style (its tiles fetched and
|
|
30
|
+
cut twice); `<VectorGeometry>` stays, a `<Geometry>` with tiles of its own.
|
|
31
|
+
- `Layer.removed`; a layer of a `VectorTiles` removed stops following the view (its tiles no longer asked for), the
|
|
32
|
+
others going on.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- A map could be idle before its vector tiles were there: the engine knows only the tiles it holds, so once the
|
|
37
|
+
engine with 3D Tiles came (a model, trees, street lamps added) and the tiles were cut again from the workers' cache
|
|
38
|
+
(nothing on the network meanwhile), 'idle' came with no city drawn (`whenIdle`, the visual tests: Paris by night
|
|
39
|
+
blank now and then on the CI). The map now waits on the work of its vector tiles (the workers' cuts, the uploads
|
|
40
|
+
over frames).
|
|
41
|
+
- An IFC model's worker failing once the model is open rejects the answers awaited (a storey's meshes, an element's
|
|
42
|
+
properties), which hung.
|
|
43
|
+
- A vector layer removed no longer uploads the tiles still waiting (it reached a freed engine after `map.destroy()`).
|
|
44
|
+
- The labels' workers read the buildings' heights only when the labels hide behind them (`occluded`).
|
|
45
|
+
- A `roof:shape` the engine does not know is generated with `roofs: 'generated'` on `extrusions()` too, as on
|
|
46
|
+
`vectors()`; an explicitly flat roof no longer sends its building's whole outline.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- The trees run on the street lamps' and furniture's placing (`placed`, the simplified trees far away an option of
|
|
51
|
+
it); the code of the vector tiles' workers and of the engine tidied (helpers shared, the style's floats and the
|
|
52
|
+
engine's texture units named). The engine and the basemap worker 0.1 KB gzipped more each.
|
|
53
|
+
|
|
54
|
+
## [1.6.0] - 2026-10-26
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- IFC models, further: each storey meshed when asked (`storey.load()`, `storey.elements`): a large model's storeys
|
|
59
|
+
one at a time, those in view only; `model.place`, where the model stands, from its `IfcMapConversion` in a projected
|
|
60
|
+
CRS isard knows (the conversion's rotation and scale, the project's unit, the grid's convergence) or else its site's
|
|
61
|
+
latitude and longitude turned by its true north; `ModelLayer.setHighlight(feature, color)` tints a feature (an IFC
|
|
62
|
+
element picked). The IFC models example meshes its storeys one after the other, places FZK-Haus by its true north and
|
|
63
|
+
highlights the element clicked; the georeferenced BIM scene example (TypeScript and React): buildingSMART's scene, one
|
|
64
|
+
IFC file per discipline, each placed by its own map conversion, fitting together.
|
|
65
|
+
- IFC models (BIM): `loadIfc(url | bytes)` of `isard/formats` reads an IFC file with web-ifc (ThatOpen, MPL-2.0;
|
|
66
|
+
fetched on first use from jsDelivr, or `webIfc`: a folder of yours) in a worker of its own: each storey a glTF binary
|
|
67
|
+
for `addModels`, each element a feature of it (its IFC class, name, storey), its properties on demand
|
|
68
|
+
(`model.properties(element)`: attributes, property and quantity sets), its site (`IfcSite`'s latitude and
|
|
69
|
+
longitude). A model with features (`_BATCHID`, `EXT_mesh_features`) is picked by feature: the hit's `index` is the
|
|
70
|
+
element under the point. The IFC models example (TypeScript and React): the KIT's FZK-Haus at its site in Karlsruhe
|
|
71
|
+
and buildingSMART's Duplex, storey by storey, an element's properties on a click.
|
|
72
|
+
- COLLADA models (BIM and CAD exports): `loadCollada(url)` and `parseCollada(text, images)` of `isard/formats` read a
|
|
73
|
+
`.dae` into a glTF binary for `addModels({ data })`: its meshes where its scene's nodes put them, in metres and turned
|
|
74
|
+
from its up axis to glTF's, its materials' colors, transparencies and textures. The examples' new BIM section: A
|
|
75
|
+
BIM building (iTowns' sample building on the IGN's orthophotos and relief, in TypeScript and React), and Inside a
|
|
76
|
+
shopping mall moved there.
|
|
77
|
+
- Panoramax, the open street-level photos of the IGN and OpenStreetMap France: `panoramaxStyle()` gives its MapLibre
|
|
78
|
+
style (its sequences and a dot at each photo, drawn as any style by `vectorTiles().vectors()`), `panoramaxPicture(id)`
|
|
79
|
+
a photo's data from its STAC API (where and when, its heading, its field of view, its images, its producer and
|
|
80
|
+
licence, the photos before and after it), `panoramaxPhoto` the photo for `addPhoto`. `map.addPhoto` stands any photo
|
|
81
|
+
where it was taken, facing its way (a glTF of the photo made by the page: flat on a frame across its field of view, a
|
|
82
|
+
360° one on a band round its camera, each pixel where the camera saw it); from its place (`setFirstPerson`) it lies
|
|
83
|
+
over the buildings it shows. The Panoramax example (TypeScript and React): a dot clicked, its photo in 3D, the photos
|
|
84
|
+
before and after it, the eye in its place with the photo left of a line dragged and the 3D map right of it.
|
|
85
|
+
- `labels({ occluded: true })`: the labels hidden by buildings another `vectorTiles()` raises (a `<VectorGeometry>` of
|
|
86
|
+
the same style, as in the React examples).
|
|
87
|
+
- Street lamps: `tiles.lamps()` places them along the style's streets (30 m apart, every other one on the other side,
|
|
88
|
+
as far from the middle as the street's class says), their heads lit at night; `ModelLayer.setGlow(from, color)`
|
|
89
|
+
lights any model from a height up at night (an additive pass of the model layer). The 3D vector examples show them.
|
|
90
|
+
About 0.3 KB gzipped more for the basemap worker.
|
|
91
|
+
- `<VectorGeometry roofs facades>` in React (the roofs make the layer anew, the facades do not); `{ type: 'trees' }`
|
|
92
|
+
for `map.add` and `<Layer>` (`map.addTrees`, its handle a `ModelLayer`).
|
|
93
|
+
- Landmarks: in `vectors()`, a building holding a theatre, a museum, a place of worship, a castle, a monument, an
|
|
94
|
+
attraction or a town hall (OpenMapTiles' points of interest in its tile) has no office windows, and is floodlit at
|
|
95
|
+
night (a warm light from the foot of its walls fading up them, each face as lit as it faces the lights): the Opéra
|
|
96
|
+
Garnier no longer reads as offices in Paris by night. About 0.1 KB gzipped more for the basemap worker.
|
|
97
|
+
- The trees simplified far away instead of thinned: `trees()` draws every tree in full near the camera and, farther,
|
|
98
|
+
a simplified model (a few faces: some 30 triangles instead of 100), thinned four times more gently, up to three times
|
|
99
|
+
as many as the full ones (`treeModel` and `coniferModel` take `far`); the forest stays dense to the horizon.
|
|
100
|
+
- The models' instances placed by the GPU: uploaded once (until they or the relief under them change), each put in its
|
|
101
|
+
east-north-up frame by the vertex shader, instead of each one's matrix made on the main thread at every frame the
|
|
102
|
+
view moved. The trees example: four times as many trees for 3.6 ms a frame (2.7 for a quarter of them before).
|
|
103
|
+
- Trees of two kinds: `trees()` grows conifers among the broadleaved trees by their wood's data (OpenStreetMap's
|
|
104
|
+
`leaf_type`, PLAN IGN's `nature`; OpenMapTiles' forests a third conifers), drawn on a layer that goes with the one
|
|
105
|
+
returned (`coniferModel`, `TreeColors.conifer`); `map.addTrees({ data })` stands trees at the points of a source that
|
|
106
|
+
has them (a city's street trees), conifers by their leaf type or genus, scaled to their height.
|
|
107
|
+
- The buildings' facades: `vectors({ facades: true })`, `addExtrusions({ facades: true })` (`VectorLayer.setFacades`)
|
|
108
|
+
draw the windows on the walls, a grid of bays and floors along each wall and up from its foot, glass by day (some
|
|
109
|
+
panes lighter, some darker), the same windows lit at night; far away, the walls' even tone. The 3D vector examples
|
|
110
|
+
show them. About 0.7 KB gzipped more for the engines, no frame cost measured.
|
|
111
|
+
- The labels hidden by the buildings, as Mapbox GL's Standard style hides them: `labels()` of a `vectorTiles()` that
|
|
112
|
+
raises its buildings (`vectors()` with a `fill-extrusion` layer, or `extrusions()`) hides a label whole when a
|
|
113
|
+
building, a tree or a model stands before its anchor, and lifts a label in a building onto its roof (its style's
|
|
114
|
+
`fill-extrusion-height`). `addSymbols({ occluded: true })` for any symbol layer. The solid scene's depth is read at
|
|
115
|
+
five pixels around each label's anchor (taken from the sun's shadows when they drew it, no cost, else drawn once a
|
|
116
|
+
frame), the label hidden where three stand nearer than it by more than some metres: no wavering on a roof or
|
|
117
|
+
between close walls. About 1.1 KB gzipped more for the engines, 0.5 KB for the basemap worker.
|
|
118
|
+
- `addExtrusions({ roof, roofHeight })`: the extrusion layers' roofs, as `vectors()` builds them: flat by default, one
|
|
119
|
+
of OpenStreetMap's `roof:shape` per building (hipped, gabled, pyramidal, mansard; the others as the nearest of them),
|
|
120
|
+
or `generated` from its outline; their height as their slopes make it unless given. Changing them with `setStyle`
|
|
121
|
+
builds the blocks again. `VectorTiles.extrusions({ roofs })` makes them as `vectors()` does (`'data'`,
|
|
122
|
+
`'generated'`, `'flat'` by default). The buildings example generates the BD TOPO's roofs.
|
|
123
|
+
- `vectors({ roofs })`: the buildings' roofs, flat by default; as their data says when the tiles have it (`roof:shape`:
|
|
124
|
+
hipped, gabled, pyramidal, mansard; `roof:height`), or generated from their outline (`'generated'`: hipped or gabled
|
|
125
|
+
under 450 m², a mansard under 3000 m², flat past that and for courtyards). A roof is the lower envelope of planes
|
|
126
|
+
rising from its outline's edges, built over the whole building and cut to each tile (its ridges go on across the
|
|
127
|
+
tiles), fitted into the building's height. A concave outline (an L, a T, an H) is cut into wings where a wall carried
|
|
128
|
+
on from an inward corner meets it, each wing roofed and closed by a gable against the next, their eaves level (a
|
|
129
|
+
narrower wing's ridge lower); past six wings, flat. The 3D vector examples use the generated roofs. About 8 KB gzipped more
|
|
130
|
+
for the engines and the tessellation module.
|
|
131
|
+
- `vectors()`: the lines' and buildings' patterns (`line-pattern` as tall as the line, repeated along it;
|
|
132
|
+
`fill-extrusion-pattern` on the roofs as the fills' and along the walls), and the fills' patterns over the relief
|
|
133
|
+
(the ground under each pixel from its depth, drawn once a frame when a patterned layer needs it; on the globe, their
|
|
134
|
+
average color still).
|
|
135
|
+
- `vectors()`: the lines' `line-blur` (each feature's, their edges fading over it) and the fills' and lines'
|
|
136
|
+
translations (`fill-translate`, `line-translate`, turning with the map unless `*-translate-anchor` is `viewport`;
|
|
137
|
+
the fills picked where they are drawn).
|
|
138
|
+
- `vectors()`: the style's circle layers, their points drawn as circles facing the screen (`circle-color`,
|
|
139
|
+
`circle-radius`, `circle-stroke-width` and `circle-stroke-color` with their opacities; picked by feature), and the
|
|
140
|
+
fills' patterns (`fill-pattern`, `background-pattern`) from the style's sprite, anchored to the world and fading from
|
|
141
|
+
one zoom's to the next's as MapLibre's (over the relief, a pattern's average color). The sprite's images go to the
|
|
142
|
+
workers only for the raster path.
|
|
143
|
+
- `vectors()`: the lines joined as their `line-join` says (`miter`, MapLibre's default, bevelled past
|
|
144
|
+
`line-miter-limit`; `bevel`; `round`, the only join before) and offset by `line-offset` (each feature's own,
|
|
145
|
+
following the zoom; the ends of the pieces moved along their miters, so that offset lines still meet). Each line
|
|
146
|
+
piece carries the directions of the line around it, 8 bytes more; about 2 KB gzipped more for the engines, 0.6 KB
|
|
147
|
+
for the tessellation module.
|
|
148
|
+
|
|
149
|
+
- Texts along lines follow their bends (`placement: 'line'`, a vector style's `symbol-placement: line`): each glyph
|
|
150
|
+
placed along the line from the anchor and turned with it, read left to right, its own box in the collision grid; not
|
|
151
|
+
shown round a bend sharper than 45° between two glyphs or off the line's ends; on one line of text. A vector
|
|
152
|
+
basemap's texts along lines repeat every `symbol-spacing`. Labels fade in and out (300 ms), keeping their opacity
|
|
153
|
+
as their tiles come again. About 4 KB gzipped more for the engines.
|
|
154
|
+
- The labels' collisions worked out again every 300 ms while the map moves (and at once when it stops), as MapLibre's:
|
|
155
|
+
in between the labels shown follow the map, their boxes as they were. The collision grid in cells of 16 pixels,
|
|
156
|
+
reaching past the screen. A vector basemap's main thread as before its texts along lines (1.7 ms a frame over the
|
|
157
|
+
3D vector example's drag).
|
|
158
|
+
- GRIB2 packed with CCSDS (data template 5.42), as Météo-France's AROME and ECMWF's open data come: `map.readGrids`
|
|
159
|
+
decodes it in the grid module (CCSDS 121.0-B, as libaec codes it; tested against ecCodes, fuzzed). About 2.4 KB
|
|
160
|
+
gzipped more for the grid module. The example Wind over France (AROME every 2.5 km through the hours of a run), in
|
|
161
|
+
TypeScript and React.
|
|
162
|
+
|
|
163
|
+
### Changed
|
|
164
|
+
|
|
165
|
+
- The examples regrouped by what they show: Getting started, Data layers, Basemaps and terrain, 3D city (the vector
|
|
166
|
+
maps), 3D data (3D Tiles, point clouds, models, panels, three.js), Street level (panoramas, Panoramax), BIM and
|
|
167
|
+
indoor (IFC, COLLADA, a shopping mall), Flows, Analysis and comparison.
|
|
168
|
+
- Zooming a pitched 3D city with Panoramax over it jerked: a far tile's buildings (10 MB and more) went to the GPU in
|
|
169
|
+
one upload, tens of milliseconds, and Panoramax's sequences (a point every few metres, most segments under a pixel,
|
|
170
|
+
each drawn as wide as the line) loaded the GPU until it stalled the page. A large tile's blocks now go a part at a
|
|
171
|
+
time over several frames (2 MB a part, the tile drawn once they all are there, the one it replaces until then), and
|
|
172
|
+
the lines are simplified in the workers to a quarter of a pixel at the tile's zoom (no change on screen). Zooming
|
|
173
|
+
the Panoramax example: 4 frames over 25 ms a zoom instead of 12, the long tasks' time divided by 2.5; the other 3D
|
|
174
|
+
vector maps as before (vector-3d: no frame over 25 ms). The Panoramax example's line between the photo and the 3D
|
|
175
|
+
map is dragged (it followed the cursor).
|
|
176
|
+
- Lines and circles (of `vectors()`, `addLines`, `addCircles`) drawn after buildings, trees or models are hidden
|
|
177
|
+
behind them on a flat map too, as Mapbox GL's buildings hide its lines and circles (in relief they already were by
|
|
178
|
+
the hills); a second style over a 3D city (Panoramax's) no longer shows through its buildings.
|
|
179
|
+
- The sun's light takes the color of its altitude (nearly white high up, golden under 15°, orange at the horizon) and
|
|
180
|
+
the shadows the sky's bluer light, as dark as their opacity; the shadows soften far from the camera (their samples
|
|
181
|
+
spreading up to three times as wide).
|
|
182
|
+
- `vectors()`: a filter reading the zoom holds as MapLibre evaluates it, at the whole zoom under the camera's, not at
|
|
183
|
+
the level of the tile drawn (drawn from half a level under it, a tile of level 15 showed `['>=', ['zoom'], 15]`
|
|
184
|
+
from 14.5): each feature styled with the zooms its filter holds over, which the engine checks at the camera's zoom.
|
|
185
|
+
- At night, the ground is darker where the buildings around hide the sky: the streets and courtyards read under the
|
|
186
|
+
roofs, which kept the same blue (the sun's map drawn from straight above, its heights giving each pixel's share of
|
|
187
|
+
the sky within 25 metres). Two depth passes more a frame at night, as by day with shadows.
|
|
188
|
+
|
|
189
|
+
### Fixed
|
|
190
|
+
|
|
191
|
+
- The floodlit landmarks flickered at night as the view moved: the lights were drawn a hair nearer than the walls
|
|
192
|
+
they light, so a wall just behind another (the parts of a monument inside one another) caught light in streaks that
|
|
193
|
+
came and went. The blocks' lights are now drawn only on the surfaces drawn (`invariant gl_Position`, depth `EQUAL`):
|
|
194
|
+
at the Opéra Garnier, a third of the pixels changing as the view moves by a quarter pixel.
|
|
195
|
+
- A paint property set as a `vectors()` style loads (`setPaintProperty` right after `vectors()`, or `paint` of a
|
|
196
|
+
`<VectorGeometry>`) was lost: the tiles cut under the former style before it came were never restyled.
|
|
197
|
+
- Paris by night flickered as the view moved: the parts of a landmark's building (the Opéra Garnier's stage tower,
|
|
198
|
+
the Louvre's wings) were not landmarks unless they held its point of interest, and their dark walls with lit windows
|
|
199
|
+
fought the floodlit walls along them; a building inside a landmark's, or holding its middle, is now one too (a
|
|
200
|
+
neighbour against its wall is not). The lit windows, bright points on dark walls, sparkled far away where they shrank
|
|
201
|
+
to a pixel: they now fade from bays of 6 pixels to 2 (the glass by day as before), a faint even glow in their place.
|
|
202
|
+
- `map.rebuildLayer` (a `<Layer>` or a bound layer made anew) moves the new layer's companions with it (the
|
|
203
|
+
conifers of `addTrees`), and no longer places it under the old one's companions, removed with it.
|
|
204
|
+
- Zooming in a 3D vector map jerked as tiles came in: their meshes were all uploaded as they arrived, several in one
|
|
205
|
+
frame (copying their buffers to the GPU, tens of milliseconds each), and the frames after waited on the GPU.
|
|
206
|
+
`vectors()` now uploads them over several frames, 4 ms a frame (a tile out of view still drawn until its
|
|
207
|
+
replacements are uploaded): zooming in and out of the 3D vector examples, 0 to 3 frames over 25 ms instead of 5 to 27.
|
|
208
|
+
- `vectors()` over the relief with no raster layer under it (`basemap: 'none'`): its fills showed nowhere, the shadow
|
|
209
|
+
volumes they are drawn with finding no ground in the depth buffer. The relief's ground is now drawn (its depth
|
|
210
|
+
alone) when no raster layer draws it first, over the tiles a raster layer would draw (#42).
|
|
211
|
+
- Zooming jerked and tiles blinked out: `vectors()` dropped a tile out of view once the tiles its own update asked for
|
|
212
|
+
were there, not those an earlier update was still waiting for, leaving a hole for a frame or more; the labels of new
|
|
213
|
+
tiles (thousands of features past the source's deepest level, shaped again at each whole zoom) held the main thread
|
|
214
|
+
up to 200 ms. A tile out of view now stays drawn until every tile of the view is there, and the labels are shaped a
|
|
215
|
+
slice at a time, a frame let through every 6 ms: zooming in and out of the 3D vector example, no frame over 50 ms
|
|
216
|
+
(217 before), two long tasks instead of thirteen.
|
|
217
|
+
|
|
6
218
|
## [1.5.0] - 2026-10-24
|
|
7
219
|
|
|
8
220
|
### Added
|
package/README.md
CHANGED
|
@@ -179,8 +179,9 @@ More in [Develop and release](https://ideal-adventure-zqn6y6p.pages.github.io/gu
|
|
|
179
179
|
|
|
180
180
|
## Roadmap
|
|
181
181
|
|
|
182
|
-
The whole MapLibre style drawn as vectors, a 3D vector map to walk through,
|
|
183
|
-
buildings, more of the models' files), several projections
|
|
182
|
+
The whole MapLibre style drawn as vectors, a 3D vector map to walk through, Panoramax's street-level photos on the map
|
|
183
|
+
and at street level, fluids on the globe (wakes behind the buildings, more of the models' files), several projections
|
|
184
|
+
on the globe, and smaller items: see
|
|
184
185
|
[Roadmap](https://ideal-adventure-zqn6y6p.pages.github.io/guide/roadmap).
|
|
185
186
|
|
|
186
187
|
## Licence
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The street furniture of a vector map (`VectorTiles.lamps`, `VectorTiles.furniture`), each made here as a glTF binary
|
|
3
|
+
* (no file to download), flat-shaded: a street lamp (its head lit at night: `ModelLayer.setGlow` from `LAMP_HEAD` up),
|
|
4
|
+
* a bus shelter, a waste basket, a post box, a Wallace fountain, bicycle racks, a bench.
|
|
5
|
+
*/
|
|
6
|
+
/** Metres from a lamp's foot to its head: the part lit at night */
|
|
7
|
+
export declare const LAMP_HEAD = 4.6;
|
|
8
|
+
/** A street lamp as a glTF binary, some 5 metres high: a thin pole, a lantern on top */
|
|
9
|
+
export declare const lampModel: () => Uint8Array<ArrayBuffer>;
|
|
10
|
+
/** A bus shelter, 3.6 metres wide, 2.5 high: a back and two sides of glass in a steel frame, a roof, an advert at one
|
|
11
|
+
* end; open toward the street (its front) */
|
|
12
|
+
export declare const shelterModel: () => Uint8Array<ArrayBuffer>;
|
|
13
|
+
/** A waste basket of Paris, about a metre high: a green hoop on a post */
|
|
14
|
+
export declare const binModel: () => Uint8Array<ArrayBuffer>;
|
|
15
|
+
/** A post box of La Poste, 1.3 metres high: a yellow box on a foot */
|
|
16
|
+
export declare const postboxModel: () => Uint8Array<ArrayBuffer>;
|
|
17
|
+
/** A Wallace fountain, 2.7 metres high: a base, a column (its four caryatids), a dome, all dark green cast iron */
|
|
18
|
+
export declare const fountainModel: () => Uint8Array<ArrayBuffer>;
|
|
19
|
+
/** Bicycle racks: three steel hoops a metre apart, 0.8 metres high, across the front */
|
|
20
|
+
export declare const rackModel: () => Uint8Array<ArrayBuffer>;
|
|
21
|
+
/** A bench, 1.8 metres wide: a wooden seat and back on dark green feet, facing its front */
|
|
22
|
+
export declare const benchModel: () => Uint8Array<ArrayBuffer>;
|
|
23
|
+
/** The kinds of furniture placed by the workers, in the order of their numbers (`PLACED_KIND`) */
|
|
24
|
+
export declare const FURNITURE: readonly ["shelter", "bin", "postbox", "fountain", "rack", "bench"];
|
|
25
|
+
/** The model of each kind of furniture */
|
|
26
|
+
export declare const FURNITURE_MODELS: Readonly<Record<(typeof FURNITURE)[number], () => Uint8Array<ArrayBuffer>>>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The street furniture of a vector map (`VectorTiles.lamps`, `VectorTiles.furniture`), each made here as a glTF binary
|
|
3
|
+
* (no file to download), flat-shaded: a street lamp (its head lit at night: `ModelLayer.setGlow` from `LAMP_HEAD` up),
|
|
4
|
+
* a bus shelter, a waste basket, a post box, a Wallace fountain, bicycle racks, a bench.
|
|
5
|
+
*/
|
|
6
|
+
import { box, glb, join, revolve } from "./meshes.js";
|
|
7
|
+
/** Colors of a street lamp (linear RGBA, as glTF's `baseColorFactor`): Paris's dark green cast iron */
|
|
8
|
+
const POLE = [0.04, 0.07, 0.05, 1];
|
|
9
|
+
const HEAD = [0.55, 0.52, 0.42, 1];
|
|
10
|
+
/** Metres from a lamp's foot to its head: the part lit at night */
|
|
11
|
+
export const LAMP_HEAD = 4.6;
|
|
12
|
+
/** A street lamp as a glTF binary, some 5 metres high: a thin pole, a lantern on top */
|
|
13
|
+
export const lampModel = () => {
|
|
14
|
+
const pole = revolve([
|
|
15
|
+
[0, 0.14],
|
|
16
|
+
[0.6, 0.1],
|
|
17
|
+
[LAMP_HEAD, 0.06],
|
|
18
|
+
], 5);
|
|
19
|
+
const head = revolve([
|
|
20
|
+
[LAMP_HEAD, 0.12],
|
|
21
|
+
[4.95, 0.32],
|
|
22
|
+
[5.25, 0.26],
|
|
23
|
+
[5.45, 0],
|
|
24
|
+
], 6);
|
|
25
|
+
return glb([pole, head], [POLE, HEAD]);
|
|
26
|
+
};
|
|
27
|
+
/** Colors of the street furniture (linear RGBA): Paris's dark green cast iron, steel, wood, glass, La Poste's yellow */
|
|
28
|
+
const GREEN = [0.03, 0.08, 0.05, 1];
|
|
29
|
+
const STEEL = [0.32, 0.33, 0.34, 1];
|
|
30
|
+
const WOOD = [0.36, 0.2, 0.09, 1];
|
|
31
|
+
const GLASS = [0.55, 0.7, 0.75, 0.35];
|
|
32
|
+
const POSTER = [0.85, 0.82, 0.72, 1];
|
|
33
|
+
const YELLOW = [0.95, 0.7, 0.02, 1];
|
|
34
|
+
/** A bus shelter, 3.6 metres wide, 2.5 high: a back and two sides of glass in a steel frame, a roof, an advert at one
|
|
35
|
+
* end; open toward the street (its front) */
|
|
36
|
+
export const shelterModel = () => {
|
|
37
|
+
const [w, d, h] = [1.8, 0.7, 2.5];
|
|
38
|
+
const frame = join(box(-w, 0, -d, -w + 0.08, h, -d + 0.08), box(w - 0.08, 0, -d, w, h, -d + 0.08), box(-w, 0, d - 0.08, -w + 0.08, h, d), box(w - 0.08, 0, d - 0.08, w, h, d), box(-w - 0.1, h, -d - 0.1, w + 0.1, h + 0.12, d + 0.25));
|
|
39
|
+
const glass = join(box(-w, 0.15, -d, w, h - 0.1, -d + 0.03), box(-w, 0.15, -d, -w + 0.03, h - 0.1, d - 0.1));
|
|
40
|
+
const advert = box(w - 0.12, 0.3, -d + 0.1, w - 0.04, 2.1, d - 0.1);
|
|
41
|
+
const seat = box(-0.9, 0.42, -d + 0.05, 0.9, 0.48, -d + 0.4);
|
|
42
|
+
return glb([frame, glass, advert, seat], [STEEL, GLASS, POSTER, STEEL]);
|
|
43
|
+
};
|
|
44
|
+
/** A waste basket of Paris, about a metre high: a green hoop on a post */
|
|
45
|
+
export const binModel = () => {
|
|
46
|
+
const post = box(-0.04, 0, -0.32, 0.04, 1.05, -0.24);
|
|
47
|
+
const hoop = revolve([
|
|
48
|
+
[0.35, 0],
|
|
49
|
+
[0.38, 0.2],
|
|
50
|
+
[0.95, 0.24],
|
|
51
|
+
[0.98, 0.25],
|
|
52
|
+
], 8);
|
|
53
|
+
return glb([post, hoop], [GREEN, GREEN]);
|
|
54
|
+
};
|
|
55
|
+
/** A post box of La Poste, 1.3 metres high: a yellow box on a foot */
|
|
56
|
+
export const postboxModel = () => glb([box(-0.08, 0, -0.08, 0.08, 0.6, 0.08), box(-0.25, 0.6, -0.18, 0.25, 1.3, 0.18)], [STEEL, YELLOW]);
|
|
57
|
+
/** A Wallace fountain, 2.7 metres high: a base, a column (its four caryatids), a dome, all dark green cast iron */
|
|
58
|
+
export const fountainModel = () => glb([
|
|
59
|
+
revolve([
|
|
60
|
+
[0, 0.42],
|
|
61
|
+
[0.35, 0.36],
|
|
62
|
+
[0.5, 0.22],
|
|
63
|
+
[1.9, 0.22],
|
|
64
|
+
[2.05, 0.38],
|
|
65
|
+
[2.3, 0.34],
|
|
66
|
+
[2.55, 0.18],
|
|
67
|
+
[2.75, 0],
|
|
68
|
+
], 8),
|
|
69
|
+
], [GREEN]);
|
|
70
|
+
/** Bicycle racks: three steel hoops a metre apart, 0.8 metres high, across the front */
|
|
71
|
+
export const rackModel = () => glb([
|
|
72
|
+
join(...[-1, 0, 1].flatMap((k) => [
|
|
73
|
+
box(k - 0.03, 0, -0.38, k + 0.03, 0.8, -0.32),
|
|
74
|
+
box(k - 0.03, 0, 0.32, k + 0.03, 0.8, 0.38),
|
|
75
|
+
box(k - 0.03, 0.74, -0.38, k + 0.03, 0.8, 0.38),
|
|
76
|
+
])),
|
|
77
|
+
], [STEEL]);
|
|
78
|
+
/** A bench, 1.8 metres wide: a wooden seat and back on dark green feet, facing its front */
|
|
79
|
+
export const benchModel = () => {
|
|
80
|
+
const feet = join(box(-0.85, 0, -0.25, -0.75, 0.45, 0.2), box(0.75, 0, -0.25, 0.85, 0.45, 0.2));
|
|
81
|
+
const wood = join(box(-0.9, 0.42, -0.25, 0.9, 0.48, 0.22), box(-0.9, 0.5, -0.3, 0.9, 0.85, -0.25));
|
|
82
|
+
return glb([feet, wood], [GREEN, WOOD]);
|
|
83
|
+
};
|
|
84
|
+
/** The kinds of furniture placed by the workers, in the order of their numbers (`PLACED_KIND`) */
|
|
85
|
+
export const FURNITURE = ['shelter', 'bin', 'postbox', 'fountain', 'rack', 'bench'];
|
|
86
|
+
/** The model of each kind of furniture */
|
|
87
|
+
export const FURNITURE_MODELS = {
|
|
88
|
+
shelter: shelterModel,
|
|
89
|
+
bin: binModel,
|
|
90
|
+
postbox: postboxModel,
|
|
91
|
+
fountain: fountainModel,
|
|
92
|
+
rack: rackModel,
|
|
93
|
+
bench: benchModel,
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=furniture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"furniture.js","sourceRoot":"","sources":["../../src/basemap/furniture.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The street furniture of a vector map (`VectorTiles.lamps`, `VectorTiles.furniture`), each made here as a glTF binary\n * (no file to download), flat-shaded: a street lamp (its head lit at night: `ModelLayer.setGlow` from `LAMP_HEAD` up),\n * a bus shelter, a waste basket, a post box, a Wallace fountain, bicycle racks, a bench.\n */\n\nimport { box, type Color, glb, join, revolve } from './meshes.ts';\n\n/** Colors of a street lamp (linear RGBA, as glTF's `baseColorFactor`): Paris's dark green cast iron */\nconst POLE: Color = [0.04, 0.07, 0.05, 1];\nconst HEAD: Color = [0.55, 0.52, 0.42, 1];\n\n/** Metres from a lamp's foot to its head: the part lit at night */\nexport const LAMP_HEAD = 4.6;\n\n/** A street lamp as a glTF binary, some 5 metres high: a thin pole, a lantern on top */\nexport const lampModel = (): Uint8Array<ArrayBuffer> => {\n const pole = revolve(\n [\n [0, 0.14],\n [0.6, 0.1],\n [LAMP_HEAD, 0.06],\n ],\n 5,\n );\n const head = revolve(\n [\n [LAMP_HEAD, 0.12],\n [4.95, 0.32],\n [5.25, 0.26],\n [5.45, 0],\n ],\n 6,\n );\n\n return glb([pole, head], [POLE, HEAD]);\n};\n\n/** Colors of the street furniture (linear RGBA): Paris's dark green cast iron, steel, wood, glass, La Poste's yellow */\nconst GREEN: Color = [0.03, 0.08, 0.05, 1];\nconst STEEL: Color = [0.32, 0.33, 0.34, 1];\nconst WOOD: Color = [0.36, 0.2, 0.09, 1];\nconst GLASS: Color = [0.55, 0.7, 0.75, 0.35];\nconst POSTER: Color = [0.85, 0.82, 0.72, 1];\nconst YELLOW: Color = [0.95, 0.7, 0.02, 1];\n\n/** A bus shelter, 3.6 metres wide, 2.5 high: a back and two sides of glass in a steel frame, a roof, an advert at one\n * end; open toward the street (its front) */\nexport const shelterModel = (): Uint8Array<ArrayBuffer> => {\n const [w, d, h] = [1.8, 0.7, 2.5];\n const frame = join(\n box(-w, 0, -d, -w + 0.08, h, -d + 0.08),\n box(w - 0.08, 0, -d, w, h, -d + 0.08),\n box(-w, 0, d - 0.08, -w + 0.08, h, d),\n box(w - 0.08, 0, d - 0.08, w, h, d),\n box(-w - 0.1, h, -d - 0.1, w + 0.1, h + 0.12, d + 0.25),\n );\n const glass = join(box(-w, 0.15, -d, w, h - 0.1, -d + 0.03), box(-w, 0.15, -d, -w + 0.03, h - 0.1, d - 0.1));\n const advert = box(w - 0.12, 0.3, -d + 0.1, w - 0.04, 2.1, d - 0.1);\n const seat = box(-0.9, 0.42, -d + 0.05, 0.9, 0.48, -d + 0.4);\n\n return glb([frame, glass, advert, seat], [STEEL, GLASS, POSTER, STEEL]);\n};\n\n/** A waste basket of Paris, about a metre high: a green hoop on a post */\nexport const binModel = (): Uint8Array<ArrayBuffer> => {\n const post = box(-0.04, 0, -0.32, 0.04, 1.05, -0.24);\n const hoop = revolve(\n [\n [0.35, 0],\n [0.38, 0.2],\n [0.95, 0.24],\n [0.98, 0.25],\n ],\n 8,\n );\n\n return glb([post, hoop], [GREEN, GREEN]);\n};\n\n/** A post box of La Poste, 1.3 metres high: a yellow box on a foot */\nexport const postboxModel = (): Uint8Array<ArrayBuffer> =>\n glb([box(-0.08, 0, -0.08, 0.08, 0.6, 0.08), box(-0.25, 0.6, -0.18, 0.25, 1.3, 0.18)], [STEEL, YELLOW]);\n\n/** A Wallace fountain, 2.7 metres high: a base, a column (its four caryatids), a dome, all dark green cast iron */\nexport const fountainModel = (): Uint8Array<ArrayBuffer> =>\n glb(\n [\n revolve(\n [\n [0, 0.42],\n [0.35, 0.36],\n [0.5, 0.22],\n [1.9, 0.22],\n [2.05, 0.38],\n [2.3, 0.34],\n [2.55, 0.18],\n [2.75, 0],\n ],\n 8,\n ),\n ],\n [GREEN],\n );\n\n/** Bicycle racks: three steel hoops a metre apart, 0.8 metres high, across the front */\nexport const rackModel = (): Uint8Array<ArrayBuffer> =>\n glb(\n [\n join(\n ...[-1, 0, 1].flatMap((k) => [\n box(k - 0.03, 0, -0.38, k + 0.03, 0.8, -0.32),\n box(k - 0.03, 0, 0.32, k + 0.03, 0.8, 0.38),\n box(k - 0.03, 0.74, -0.38, k + 0.03, 0.8, 0.38),\n ]),\n ),\n ],\n [STEEL],\n );\n\n/** A bench, 1.8 metres wide: a wooden seat and back on dark green feet, facing its front */\nexport const benchModel = (): Uint8Array<ArrayBuffer> => {\n const feet = join(box(-0.85, 0, -0.25, -0.75, 0.45, 0.2), box(0.75, 0, -0.25, 0.85, 0.45, 0.2));\n const wood = join(box(-0.9, 0.42, -0.25, 0.9, 0.48, 0.22), box(-0.9, 0.5, -0.3, 0.9, 0.85, -0.25));\n\n return glb([feet, wood], [GREEN, WOOD]);\n};\n\n/** The kinds of furniture placed by the workers, in the order of their numbers (`PLACED_KIND`) */\nexport const FURNITURE = ['shelter', 'bin', 'postbox', 'fountain', 'rack', 'bench'] as const;\n\n/** The model of each kind of furniture */\nexport const FURNITURE_MODELS: Readonly<Record<(typeof FURNITURE)[number], () => Uint8Array<ArrayBuffer>>> = {\n shelter: shelterModel,\n bin: binModel,\n postbox: postboxModel,\n fountain: fountainModel,\n rack: rackModel,\n bench: benchModel,\n};\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small flat-shaded meshes made in the page (the trees, the street furniture) and their glTF binaries: solids of
|
|
3
|
+
* revolution, boxes, parts joined.
|
|
4
|
+
*/
|
|
5
|
+
/** A color: linear RGBA, as glTF's `baseColorFactor` */
|
|
6
|
+
export type Color = [number, number, number, number];
|
|
7
|
+
/** A mesh's triangles: their positions and normals (x, y, z each; one normal per face) */
|
|
8
|
+
export interface Mesh {
|
|
9
|
+
positions: number[];
|
|
10
|
+
normals: number[];
|
|
11
|
+
}
|
|
12
|
+
/** A solid of revolution around the vertical (glTF +Y up), flat-shaded: rings of (height, radius), a point at the
|
|
13
|
+
* top when its radius is 0; the triangles' positions and normals, one normal per face */
|
|
14
|
+
export declare const revolve: (rings: [height: number, radius: number][], sides: number) => Mesh;
|
|
15
|
+
/** A box from (x0, y0, z0) to (x1, y1, z1) (glTF axes: y up, z the model's front, x its left), its faces outward */
|
|
16
|
+
export declare const box: (x0: number, y0: number, z0: number, x1: number, y1: number, z1: number) => Mesh;
|
|
17
|
+
/** Parts of one color joined into one */
|
|
18
|
+
export declare const join: (...parts: Mesh[]) => Mesh;
|
|
19
|
+
/** Parts flat-shaded in their colors as a glTF binary: one mesh of a primitive each, its front +Z
|
|
20
|
+
* (`ModelInstance.heading` turns it), standing on its origin */
|
|
21
|
+
export declare const glb: (parts: Mesh[], colors: Color[]) => Uint8Array<ArrayBuffer>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small flat-shaded meshes made in the page (the trees, the street furniture) and their glTF binaries: solids of
|
|
3
|
+
* revolution, boxes, parts joined.
|
|
4
|
+
*/
|
|
5
|
+
import { bounds, glbOf } from "../util/gltf.js";
|
|
6
|
+
/** A solid of revolution around the vertical (glTF +Y up), flat-shaded: rings of (height, radius), a point at the
|
|
7
|
+
* top when its radius is 0; the triangles' positions and normals, one normal per face */
|
|
8
|
+
export const revolve = (rings, sides) => {
|
|
9
|
+
const at = (k, [h, r]) => {
|
|
10
|
+
const a = (k / sides) * Math.PI * 2;
|
|
11
|
+
return [Math.cos(a) * r, h, Math.sin(a) * r];
|
|
12
|
+
};
|
|
13
|
+
const positions = [];
|
|
14
|
+
const normals = [];
|
|
15
|
+
const face = (a, b, c) => {
|
|
16
|
+
const u = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
|
|
17
|
+
const v = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
|
|
18
|
+
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]];
|
|
19
|
+
const length = Math.hypot(...n);
|
|
20
|
+
// A degenerate face (two points at the apex) is left out
|
|
21
|
+
if (length === 0)
|
|
22
|
+
return;
|
|
23
|
+
positions.push(...a, ...b, ...c);
|
|
24
|
+
[0, 1, 2].forEach(() => {
|
|
25
|
+
normals.push(n[0] / length, n[1] / length, n[2] / length);
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
rings.slice(1).forEach((ring, i) => {
|
|
29
|
+
const below = rings[i] ?? ring;
|
|
30
|
+
Array.from({ length: sides }, (_, k) => k).forEach((k) => {
|
|
31
|
+
const [a, b] = [at(k, below), at(k + 1, below)];
|
|
32
|
+
const [c, d] = [at(k, ring), at(k + 1, ring)];
|
|
33
|
+
// Counter-clockwise seen from outside
|
|
34
|
+
face(a, c, b);
|
|
35
|
+
face(b, c, d);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
// The bottom closed: seen from below
|
|
39
|
+
const base = rings[0];
|
|
40
|
+
if (base && base[1] > 0) {
|
|
41
|
+
Array.from({ length: sides }, (_, k) => k).forEach((k) => {
|
|
42
|
+
face([0, base[0], 0], at(k, base), at(k + 1, base));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return { positions, normals };
|
|
46
|
+
};
|
|
47
|
+
/** A box from (x0, y0, z0) to (x1, y1, z1) (glTF axes: y up, z the model's front, x its left), its faces outward */
|
|
48
|
+
export const box = (x0, y0, z0, x1, y1, z1) => {
|
|
49
|
+
const positions = [];
|
|
50
|
+
const normals = [];
|
|
51
|
+
// Each face: its normal and its four corners, counter-clockwise seen from outside
|
|
52
|
+
const faces = [
|
|
53
|
+
[
|
|
54
|
+
[1, 0, 0],
|
|
55
|
+
[
|
|
56
|
+
[x1, y0, z0],
|
|
57
|
+
[x1, y1, z0],
|
|
58
|
+
[x1, y1, z1],
|
|
59
|
+
[x1, y0, z1],
|
|
60
|
+
],
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
[-1, 0, 0],
|
|
64
|
+
[
|
|
65
|
+
[x0, y0, z1],
|
|
66
|
+
[x0, y1, z1],
|
|
67
|
+
[x0, y1, z0],
|
|
68
|
+
[x0, y0, z0],
|
|
69
|
+
],
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
[0, 1, 0],
|
|
73
|
+
[
|
|
74
|
+
[x0, y1, z0],
|
|
75
|
+
[x0, y1, z1],
|
|
76
|
+
[x1, y1, z1],
|
|
77
|
+
[x1, y1, z0],
|
|
78
|
+
],
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
[0, -1, 0],
|
|
82
|
+
[
|
|
83
|
+
[x0, y0, z0],
|
|
84
|
+
[x1, y0, z0],
|
|
85
|
+
[x1, y0, z1],
|
|
86
|
+
[x0, y0, z1],
|
|
87
|
+
],
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
[0, 0, 1],
|
|
91
|
+
[
|
|
92
|
+
[x0, y0, z1],
|
|
93
|
+
[x1, y0, z1],
|
|
94
|
+
[x1, y1, z1],
|
|
95
|
+
[x0, y1, z1],
|
|
96
|
+
],
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
[0, 0, -1],
|
|
100
|
+
[
|
|
101
|
+
[x1, y0, z0],
|
|
102
|
+
[x0, y0, z0],
|
|
103
|
+
[x0, y1, z0],
|
|
104
|
+
[x1, y1, z0],
|
|
105
|
+
],
|
|
106
|
+
],
|
|
107
|
+
];
|
|
108
|
+
faces.forEach(([n, [a, b, c, d]]) => {
|
|
109
|
+
[a, b, c, a, c, d].forEach((p) => {
|
|
110
|
+
positions.push(...(p ?? [0, 0, 0]));
|
|
111
|
+
normals.push(...n);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
return { positions, normals };
|
|
115
|
+
};
|
|
116
|
+
/** Parts of one color joined into one */
|
|
117
|
+
export const join = (...parts) => ({
|
|
118
|
+
positions: parts.flatMap((p) => p.positions),
|
|
119
|
+
normals: parts.flatMap((p) => p.normals),
|
|
120
|
+
});
|
|
121
|
+
/** Parts flat-shaded in their colors as a glTF binary: one mesh of a primitive each, its front +Z
|
|
122
|
+
* (`ModelInstance.heading` turns it), standing on its origin */
|
|
123
|
+
export const glb = (parts, colors) => {
|
|
124
|
+
// The buffer: each part's positions then normals, 4-byte floats
|
|
125
|
+
const floats = parts.flatMap((p) => [...p.positions, ...p.normals]);
|
|
126
|
+
const bin = new Float32Array(floats);
|
|
127
|
+
const views = parts.flatMap((p, i) => {
|
|
128
|
+
const before = parts.slice(0, i).reduce((n, q) => n + (q.positions.length + q.normals.length) * 4, 0);
|
|
129
|
+
return [
|
|
130
|
+
{ buffer: 0, byteOffset: before, byteLength: p.positions.length * 4, target: 34962 },
|
|
131
|
+
{ buffer: 0, byteOffset: before + p.positions.length * 4, byteLength: p.normals.length * 4, target: 34962 },
|
|
132
|
+
];
|
|
133
|
+
});
|
|
134
|
+
const accessors = parts.flatMap((p, i) => [
|
|
135
|
+
{ bufferView: i * 2, componentType: 5126, count: p.positions.length / 3, type: 'VEC3', ...bounds(p.positions) },
|
|
136
|
+
{ bufferView: i * 2 + 1, componentType: 5126, count: p.normals.length / 3, type: 'VEC3' },
|
|
137
|
+
]);
|
|
138
|
+
const gltf = {
|
|
139
|
+
asset: { version: '2.0', generator: 'isard' },
|
|
140
|
+
scene: 0,
|
|
141
|
+
scenes: [{ nodes: [0] }],
|
|
142
|
+
nodes: [{ mesh: 0 }],
|
|
143
|
+
meshes: [
|
|
144
|
+
{
|
|
145
|
+
primitives: parts.map((_, i) => ({ attributes: { POSITION: i * 2, NORMAL: i * 2 + 1 }, material: i })),
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
materials: colors.map((color) => ({
|
|
149
|
+
pbrMetallicRoughness: { baseColorFactor: color, metallicFactor: 0, roughnessFactor: 1 },
|
|
150
|
+
// Translucent (a shelter's glass): blended, seen from both sides
|
|
151
|
+
...(color[3] < 1 && { alphaMode: 'BLEND', doubleSided: true }),
|
|
152
|
+
})),
|
|
153
|
+
accessors,
|
|
154
|
+
bufferViews: views,
|
|
155
|
+
buffers: [{ byteLength: bin.byteLength }],
|
|
156
|
+
};
|
|
157
|
+
return glbOf(gltf, new Uint8Array(bin.buffer));
|
|
158
|
+
};
|
|
159
|
+
//# sourceMappingURL=meshes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/basemap/meshes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Small flat-shaded meshes made in the page (the trees, the street furniture) and their glTF binaries: solids of\n * revolution, boxes, parts joined.\n */\n\nimport { bounds, glbOf } from '../util/gltf.ts';\n\n/** A point or a vector: x, y, z */\ntype Vec3 = [number, number, number];\n\n/** A color: linear RGBA, as glTF's `baseColorFactor` */\nexport type Color = [number, number, number, number];\n\n/** A mesh's triangles: their positions and normals (x, y, z each; one normal per face) */\nexport interface Mesh {\n positions: number[];\n normals: number[];\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 */\nexport const revolve = (rings: [height: number, radius: number][], sides: number): Mesh => {\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/** A box from (x0, y0, z0) to (x1, y1, z1) (glTF axes: y up, z the model's front, x its left), its faces outward */\nexport const box = (x0: number, y0: number, z0: number, x1: number, y1: number, z1: number): Mesh => {\n const positions: number[] = [];\n const normals: number[] = [];\n // Each face: its normal and its four corners, counter-clockwise seen from outside\n const faces: [Vec3, Vec3[]][] = [\n [\n [1, 0, 0],\n [\n [x1, y0, z0],\n [x1, y1, z0],\n [x1, y1, z1],\n [x1, y0, z1],\n ],\n ],\n [\n [-1, 0, 0],\n [\n [x0, y0, z1],\n [x0, y1, z1],\n [x0, y1, z0],\n [x0, y0, z0],\n ],\n ],\n [\n [0, 1, 0],\n [\n [x0, y1, z0],\n [x0, y1, z1],\n [x1, y1, z1],\n [x1, y1, z0],\n ],\n ],\n [\n [0, -1, 0],\n [\n [x0, y0, z0],\n [x1, y0, z0],\n [x1, y0, z1],\n [x0, y0, z1],\n ],\n ],\n [\n [0, 0, 1],\n [\n [x0, y0, z1],\n [x1, y0, z1],\n [x1, y1, z1],\n [x0, y1, z1],\n ],\n ],\n [\n [0, 0, -1],\n [\n [x1, y0, z0],\n [x0, y0, z0],\n [x0, y1, z0],\n [x1, y1, z0],\n ],\n ],\n ];\n\n faces.forEach(([n, [a, b, c, d]]) => {\n [a, b, c, a, c, d].forEach((p) => {\n positions.push(...(p ?? [0, 0, 0]));\n normals.push(...n);\n });\n });\n\n return { positions, normals };\n};\n\n/** Parts of one color joined into one */\nexport const join = (...parts: Mesh[]): Mesh => ({\n positions: parts.flatMap((p) => p.positions),\n normals: parts.flatMap((p) => p.normals),\n});\n\n/** Parts flat-shaded in their colors as a glTF binary: one mesh of a primitive each, its front +Z\n * (`ModelInstance.heading` turns it), standing on its origin */\nexport const glb = (parts: Mesh[], colors: Color[]): Uint8Array<ArrayBuffer> => {\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: colors.map((color) => ({\n pbrMetallicRoughness: { baseColorFactor: color, metallicFactor: 0, roughnessFactor: 1 },\n // Translucent (a shelter's glass): blended, seen from both sides\n ...(color[3] < 1 && { alphaMode: 'BLEND', doubleSided: true }),\n })),\n accessors,\n bufferViews: views,\n buffers: [{ byteLength: bin.byteLength }],\n };\n\n return glbOf(gltf, new Uint8Array(bin.buffer));\n};\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Things placed by a vector basemap's workers in its tiles (trees, street lamps, street furniture), as they send them
|
|
3
|
+
* to the page: so many numbers each.
|
|
4
|
+
*/
|
|
5
|
+
/** Numbers of a thing placed: longitude, latitude, scale, heading (degrees), rank (in [0, 1): far from the view, the
|
|
6
|
+
* page keeps the lowest) and kind (its model among those of its kinds) */
|
|
7
|
+
export declare const PLACED_NUMBERS = 6;
|
|
8
|
+
/** Where its rank is among its numbers */
|
|
9
|
+
export declare const PLACED_RANK = 4;
|
|
10
|
+
/** Where its kind is among its numbers */
|
|
11
|
+
export declare const PLACED_KIND = 5;
|
|
12
|
+
/** A heading for a number, the same each time, near numbers turned far apart (7919, a prime) */
|
|
13
|
+
export declare const turned: (n: number) => number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Things placed by a vector basemap's workers in its tiles (trees, street lamps, street furniture), as they send them
|
|
3
|
+
* to the page: so many numbers each.
|
|
4
|
+
*/
|
|
5
|
+
/** Numbers of a thing placed: longitude, latitude, scale, heading (degrees), rank (in [0, 1): far from the view, the
|
|
6
|
+
* page keeps the lowest) and kind (its model among those of its kinds) */
|
|
7
|
+
export const PLACED_NUMBERS = 6;
|
|
8
|
+
/** Where its rank is among its numbers */
|
|
9
|
+
export const PLACED_RANK = 4;
|
|
10
|
+
/** Where its kind is among its numbers */
|
|
11
|
+
export const PLACED_KIND = 5;
|
|
12
|
+
/** A heading for a number, the same each time, near numbers turned far apart (7919, a prime) */
|
|
13
|
+
export const turned = (n) => (n * 7919) % 360;
|
|
14
|
+
//# sourceMappingURL=placed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placed.js","sourceRoot":"","sources":["../../src/basemap/placed.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;0EAC0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,0CAA0C;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,gGAAgG;AAChG,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC","sourcesContent":["/**\n * Things placed by a vector basemap's workers in its tiles (trees, street lamps, street furniture), as they send them\n * to the page: so many numbers each.\n */\n\n/** Numbers of a thing placed: longitude, latitude, scale, heading (degrees), rank (in [0, 1): far from the view, the\n * page keeps the lowest) and kind (its model among those of its kinds) */\nexport const PLACED_NUMBERS = 6;\n\n/** Where its rank is among its numbers */\nexport const PLACED_RANK = 4;\n\n/** Where its kind is among its numbers */\nexport const PLACED_KIND = 5;\n\n/** A heading for a number, the same each time, near numbers turned far apart (7919, a prime) */\nexport const turned = (n: number): number => (n * 7919) % 360;\n"]}
|