@tileflow/core 0.1.0-alpha.35 → 0.1.0-alpha.37
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/README.md +28 -28
- package/dist/browser.d.ts +766 -419
- package/dist/browser.js +3176 -495
- package/dist/build.d.ts +3 -3
- package/dist/build.js +2947 -1618
- package/dist/config-reference.json +7165 -3899
- package/dist/{icon-composition-DSjIKmrK.d.ts → icon-composition-C5X3Q9Ya.d.ts} +622 -98
- package/dist/index.d.ts +322 -129
- package/dist/index.js +4368 -2142
- package/dist/{manifest-types-Bzxon3dx.d.ts → manifest-types-jrBdBrES.d.ts} +29 -8
- package/dist/manifest.d.ts +2 -2
- package/dist/native.js +57 -57
- package/dist/runtime.d.ts +1 -1
- package/dist/worker/buildings-3d-worker.global.js +1 -0
- package/docs/authoring-model.md +8 -3
- package/docs/boundary-areas-and-choropleths.md +217 -0
- package/docs/buildings-3d.md +203 -30
- package/docs/cartographic-defaults.md +142 -0
- package/docs/data-is-separate-from-design.md +66 -33
- package/docs/hosted-session-authorization.md +2 -4
- package/docs/map-and-terrain-examples.md +10 -3
- package/docs/nautical-marks.md +200 -0
- package/docs/public-api-and-browser-subpath.md +4 -1
- package/docs/street-lights.md +22 -6
- package/docs/sun-and-light.md +42 -2
- package/docs/themes-and-module-styles.md +66 -0
- package/docs/trees-3d.md +22 -9
- package/package.json +2 -2
|
@@ -92,9 +92,16 @@ then transition to Mercator between zoom 10 and 12 so detailed streets remain pl
|
|
|
92
92
|
property, or set it to `'mercator'`, for a consistently flat map.
|
|
93
93
|
|
|
94
94
|
Terrain keeps the original `'none' | 'hillshade' | '3d'` shorthand. The object form can style every
|
|
95
|
-
MapLibre hillshade paint control
|
|
96
|
-
|
|
97
|
-
`
|
|
95
|
+
MapLibre hillshade paint control. Raster terrain accepts either a TileJSON `url` or explicit `tiles`
|
|
96
|
+
templates, with optional `tileSize` (256 or 512) and native `minZoom`/`maxZoom` limits. The templates
|
|
97
|
+
must contain `{z}`, `{x}` and `{y}` and use HTTPS (HTTP is allowed for loopback development).
|
|
98
|
+
These source limits control DEM requests independently of `hillshade.minZoom`/`maxZoom` visibility;
|
|
99
|
+
the renderer reuses the highest available native resolution for closer views. Select resolution
|
|
100
|
+
limits supported by the provider and retain its required attribution.
|
|
101
|
+
|
|
102
|
+
Contours generate vector lines in the browser from their own explicit DEM tile template. They
|
|
103
|
+
require `demUrl`, `demMaxZoom`, and zoom-indexed `[minor, index]` `thresholds`; these are separate
|
|
104
|
+
from the raster source's `url` or `tiles`. Set `mode: 'none'` to compile
|
|
98
105
|
contours without adding a raster source, hillshade, or 3D terrain:
|
|
99
106
|
|
|
100
107
|
```ts
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Nautical marks
|
|
2
|
+
|
|
3
|
+
The `nautical` module draws navigation marks from a `nautical-v1` vector source: buoys, beacons,
|
|
4
|
+
lighthouses, lights, rocks and other hazards, wrecks, reefs, navigation areas, routes, cables,
|
|
5
|
+
harbours, ports, and a restrained indication of where a provider publishes marks. It is reference
|
|
6
|
+
cartography for general-purpose maps. It is not a nautical chart, and a map that draws it always
|
|
7
|
+
shows a "Not for navigation" notice.
|
|
8
|
+
|
|
9
|
+
## Enable Nautical on a map
|
|
10
|
+
|
|
11
|
+
Nautical is opt-in through the map's `marine` option. `'nautical'` adds it alone, `'chart'` adds it
|
|
12
|
+
with Bathymetry, and the object form selects or replaces each member. The official Soundings map
|
|
13
|
+
enables it with its own chart symbols; every other official map draws it with the module's default
|
|
14
|
+
symbology once the map opts in.
|
|
15
|
+
|
|
16
|
+
<!-- docs:check -->
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import {defineMap} from '@tileflow/core';
|
|
20
|
+
import {streets} from '@tileflow/maps';
|
|
21
|
+
|
|
22
|
+
export default defineMap({
|
|
23
|
+
id: 'harbour-guide',
|
|
24
|
+
version: 1,
|
|
25
|
+
extends: streets,
|
|
26
|
+
marine: 'nautical',
|
|
27
|
+
view: {center: [-1.3, 50.77], zoom: 12},
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`marine` is atomic: declaring it replaces the inherited value. Without a URL, the source is the
|
|
32
|
+
TileJSON at `/tiles/nautical/tiles.json` on the map's API base, with the style source ID
|
|
33
|
+
`tileflow-nautical`. Compiling a map that names this URL does not establish that a hosted Nautical
|
|
34
|
+
source is available to it. To use any schema-compatible source, name its TileJSON or PMTiles
|
|
35
|
+
archive and, when the TileJSON does not carry one, its attribution:
|
|
36
|
+
|
|
37
|
+
<!-- docs:check -->
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import {defineMap} from '@tileflow/core';
|
|
41
|
+
import {streets} from '@tileflow/maps';
|
|
42
|
+
|
|
43
|
+
export default defineMap({
|
|
44
|
+
id: 'harbour-guide',
|
|
45
|
+
version: 1,
|
|
46
|
+
extends: streets,
|
|
47
|
+
marine: {
|
|
48
|
+
bathymetry: false,
|
|
49
|
+
nautical: {
|
|
50
|
+
url: 'https://tiles.example.com/nautical/tiles.json',
|
|
51
|
+
attribution: '© Example © OpenStreetMap contributors',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The selected TileJSON owns the provider credit. Core never invents a nautical provider or
|
|
58
|
+
attribution, and an explicit `attribution` replaces the one the TileJSON supplies.
|
|
59
|
+
|
|
60
|
+
## The "Not for navigation" notice
|
|
61
|
+
|
|
62
|
+
When any layer of the compiled style reads the Nautical source, the style declares a notice in its
|
|
63
|
+
`tileflow:notices` metadata:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
[
|
|
67
|
+
{
|
|
68
|
+
"id": "nautical-not-for-navigation",
|
|
69
|
+
"sources": ["tileflow-nautical"],
|
|
70
|
+
"text": "Not for navigation"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
React, Vue, Svelte, the development preview, and standalone capture render it as a compact,
|
|
76
|
+
always-visible control beside the attribution, and keep it in step with style replacements. A map
|
|
77
|
+
that does not draw Nautical, including one whose `nautical` module is disabled, declares no notice.
|
|
78
|
+
The notice is separate from the source attribution, so the provider credit stays complete.
|
|
79
|
+
|
|
80
|
+
A direct MapLibre integration attaches the same control after constructing the map:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import maplibregl from 'maplibre-gl';
|
|
84
|
+
import {attachTileflowNotices} from '@tileflow/core/browser';
|
|
85
|
+
|
|
86
|
+
const map = new maplibregl.Map({
|
|
87
|
+
container: 'map',
|
|
88
|
+
style: '/tileflow/styles/harbour-guide/light.json',
|
|
89
|
+
});
|
|
90
|
+
const detach = attachTileflowNotices(map, {position: 'bottom-right'});
|
|
91
|
+
// Call detach() to remove the control early; removing the map also removes it.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`readTileflowNotices(style.metadata)` returns the bounded notices of a style for an application
|
|
95
|
+
that draws its own legend or exports images by other means. Show the notice wherever such a map is
|
|
96
|
+
displayed.
|
|
97
|
+
|
|
98
|
+
## Source layers and fields
|
|
99
|
+
|
|
100
|
+
Every feature carries `provider`, `provenance`, `edition`, `coverage`, `licence`, and `min_zoom`,
|
|
101
|
+
the first zoom at which the feature appears. `rank` (1 is the most important feature of its layer)
|
|
102
|
+
and `name` are optional. Colours are S-57 colour names, and multi-valued colours and categories are
|
|
103
|
+
comma-separated in source order, for example `black,yellow`. `tileflowNauticalV1Schema` lists the
|
|
104
|
+
field names, layers, and geometry types.
|
|
105
|
+
|
|
106
|
+
| Source layer | Geometry | Fields the module reads |
|
|
107
|
+
| ----------------- | -------------------------- | -------------------------------------------------------- |
|
|
108
|
+
| `aid` | Point | `class`, `subclass`, `category`, `color`, `rank`, `name` |
|
|
109
|
+
| `light` | Point | `class` (`major` or `minor`), `color`, `label`, `rank` |
|
|
110
|
+
| `hazard` | Point, LineString, Polygon | `class`, `water_level`, `name` |
|
|
111
|
+
| `wreck` | Point, Polygon | `class`, `name` |
|
|
112
|
+
| `reef` | Polygon | `name` |
|
|
113
|
+
| `navigation_area` | Point, LineString, Polygon | `class`, `size`, `rank`, `name` |
|
|
114
|
+
| `coverage` | Polygon | `families` |
|
|
115
|
+
| `sounding` | Point | `depth` |
|
|
116
|
+
|
|
117
|
+
Every layer filters on `min_zoom`, so a compatible source that keeps features in lower-zoom tiles
|
|
118
|
+
still shows each one from its own first zoom. Point groups place a lower `rank` first.
|
|
119
|
+
|
|
120
|
+
## Semantic groups
|
|
121
|
+
|
|
122
|
+
Each group is a style option of `nautical(...)`, with the same marker, symbol, area, and line style
|
|
123
|
+
objects as other modules.
|
|
124
|
+
|
|
125
|
+
| Option | Draws | Default symbology |
|
|
126
|
+
| ----------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
127
|
+
| `buoys` | `aid` buoys, light floats, and light vessels | Circle in the first colour, ringed with the second |
|
|
128
|
+
| `beacons` | `aid` beacons and daymarks | Small circle in the first colour |
|
|
129
|
+
| `lighthouses` | `aid` lighthouses | Ink circle and name |
|
|
130
|
+
| `aids` | Other `aid` classes, such as moorings, fog signals, and racons | Small hollow circle |
|
|
131
|
+
| `lights` | `light` points, one per sector | Flare in the light's first colour and its chart `label` |
|
|
132
|
+
| `hazards` | `hazard` points | `+` for rocks, `*` for rocks that show; circled obstacles |
|
|
133
|
+
| `hazardAreas` | `hazard` polygons; the outline also strokes linear hazards | Accent wash with a dotted outline |
|
|
134
|
+
| `wrecks` | `wreck` points | `Wk`, in the accent colour when dangerous |
|
|
135
|
+
| `wreckAreas` | `wreck` polygons | Ink wash with a dashed outline |
|
|
136
|
+
| `reefs` | `reef` polygons | Sand wash with a dotted outline |
|
|
137
|
+
| `navigationAreas` | `navigation_area` polygons | Dashed outlines; accent for operational areas |
|
|
138
|
+
| `routes` | `navigation_area` lines of class `route` and `traffic-separation` | Dashed line; accent for traffic separation |
|
|
139
|
+
| `cables` | `navigation_area` lines of class `cable`, `pipeline`, and their area classes | Fine dashed accent line |
|
|
140
|
+
| `harbours` | `navigation_area` points of class `harbour` | Ink circle and name |
|
|
141
|
+
| `ports` | `navigation_area` points of class `port` | Ink circle and name sized by `size`, from low zooms |
|
|
142
|
+
| `coverage` | `coverage` polygons that cover every family | Faint tint at low zooms only |
|
|
143
|
+
| `soundings` | `sounding` points | Depth figure |
|
|
144
|
+
| `labels` | Names inside hazard, navigation-area, reef, and wreck polygons; coverage opt-in | Collision-aware text |
|
|
145
|
+
|
|
146
|
+
Operational areas are restricted, military, anchorage, anchor-berth, dumping-ground, and
|
|
147
|
+
traffic-separation areas. Marks keep their conventional colours in every theme; a white light is
|
|
148
|
+
drawn as a warm yellow so it remains visible on pale water. Ink, halo, and accent come from the
|
|
149
|
+
theme's `hydro.label`, `hydro.water`, and `poi.transport` colours, so a theme can restyle Nautical
|
|
150
|
+
without new options. Override any group like any other module style:
|
|
151
|
+
|
|
152
|
+
<!-- docs:check -->
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import {defineMap, fixed, nautical} from '@tileflow/core';
|
|
156
|
+
import {streets} from '@tileflow/maps';
|
|
157
|
+
|
|
158
|
+
export default defineMap({
|
|
159
|
+
id: 'harbour-guide',
|
|
160
|
+
version: 1,
|
|
161
|
+
extends: streets,
|
|
162
|
+
marine: 'nautical',
|
|
163
|
+
modules: {
|
|
164
|
+
nautical: nautical({
|
|
165
|
+
buoys: {minZoom: 12},
|
|
166
|
+
cables: {visible: false},
|
|
167
|
+
navigationAreas: {
|
|
168
|
+
fill: {opacity: fixed(0.04, {reason: 'Keep operational areas quiet on the base map'})},
|
|
169
|
+
},
|
|
170
|
+
labels: {coverage: {visible: true}},
|
|
171
|
+
}),
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Chart symbols from the theme
|
|
177
|
+
|
|
178
|
+
A theme that declares the image tokens below replaces a point group's circle marker with that icon.
|
|
179
|
+
Buoy variants fall back to `nautical.buoy`. `tileflowNauticalImageRoles` lists the tokens.
|
|
180
|
+
|
|
181
|
+
| Token | Group |
|
|
182
|
+
| ------------------------- | ------------------------------------------ |
|
|
183
|
+
| `nautical.buoy` | `buoys` |
|
|
184
|
+
| `nautical.buoy.port` | Lateral buoys of a port-hand category |
|
|
185
|
+
| `nautical.buoy.starboard` | Lateral buoys of a starboard-hand category |
|
|
186
|
+
| `nautical.buoy.cardinal` | Cardinal buoys |
|
|
187
|
+
| `nautical.beacon` | `beacons` |
|
|
188
|
+
| `nautical.lighthouse` | `lighthouses` |
|
|
189
|
+
| `nautical.light` | `lights` |
|
|
190
|
+
| `nautical.aid` | `aids` |
|
|
191
|
+
| `nautical.wreck` | `wrecks` |
|
|
192
|
+
| `nautical.harbour` | `harbours` |
|
|
193
|
+
| `nautical.port` | `ports` |
|
|
194
|
+
|
|
195
|
+
Buoys, beacons, other aids, and lights colour their icon with the mark's own colour, so declare
|
|
196
|
+
them as [SDF icons](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/docs/native-icons.md)
|
|
197
|
+
that share one representation within each group. The defaults size icons for the SDF profile,
|
|
198
|
+
whose drawing occupies the central 12 of 24 pixels; set `icon.size` for other artwork. Soundings
|
|
199
|
+
declares these tokens with its own buoy, light, lighthouse, wreck, and harbour symbols and keeps
|
|
200
|
+
beacons as coloured dots.
|
|
@@ -79,13 +79,16 @@ import {
|
|
|
79
79
|
attachTileflowAtmosphere,
|
|
80
80
|
attachTileflowFairUseNotice,
|
|
81
81
|
attachTileflowMapLifecycle,
|
|
82
|
+
attachTileflowNotices,
|
|
82
83
|
createTileflowSessionStarter,
|
|
83
84
|
createTileflowTransformRequest,
|
|
84
85
|
registerTileflowWorldRequestBridge,
|
|
85
86
|
} from '@tileflow/core/browser';
|
|
86
87
|
```
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
`attachTileflowNotices(map)` renders the notices a compiled style declares, such as Nautical's
|
|
90
|
+
"Not for navigation", as a compact map control; see
|
|
91
|
+
[Nautical marks](nautical-marks.md). The browser entry is not re-exported from the root. It is SSR-safe to import, has no MapLibre
|
|
89
92
|
runtime dependency, and reads no browser global during module evaluation. See the
|
|
90
93
|
[framework browser runtime contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/framework-browser-runtime.md) and the
|
|
91
94
|
[cartographic authoring contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/cartographic-authoring.md). Exact field
|
package/docs/street-lights.md
CHANGED
|
@@ -6,6 +6,9 @@ glowing head. Streets and pavements the data maps as lit, but whose lamps it doe
|
|
|
6
6
|
soft light along them that claims no lamp's place. As the theme controller's sun darkens the map,
|
|
7
7
|
the lights switch on one by one; they go out as day comes.
|
|
8
8
|
|
|
9
|
+
Street lights are off by default in the SDK and in Streets. A compiled map must explicitly set
|
|
10
|
+
`roads.streetLights.enabled: true` before the renderer or preview will show lamp glows.
|
|
11
|
+
|
|
9
12
|
It is a custom WebGL2 layer for MapLibre GL JS, drawn above the map's buildings and below its
|
|
10
13
|
labels. When `createTileflowBuildings3D` raises the buildings, they hide the lamps behind them. It
|
|
11
14
|
needs WebGL2 and the Mercator projection, and shines from zoom 14 by default.
|
|
@@ -13,7 +16,8 @@ needs WebGL2 and the Mercator projection, and shines from zoom 14 by default.
|
|
|
13
16
|
## Light the streets
|
|
14
17
|
|
|
15
18
|
This example assumes an existing MapLibre map showing a Tileflow map whose vector source is called
|
|
16
|
-
`tileflow`, as Tileflow's maps call World,
|
|
19
|
+
`tileflow`, as Tileflow's maps call World, with `roads.streetLights.enabled: true` in its map
|
|
20
|
+
definition and a theme controller for it:
|
|
17
21
|
|
|
18
22
|
<!-- docs:check -->
|
|
19
23
|
|
|
@@ -56,12 +60,12 @@ lit streets, others almost none. Where the data says nothing, the streets stay d
|
|
|
56
60
|
|
|
57
61
|
The map describes its street lights in its roads module, next to the other details drawn from
|
|
58
62
|
street furniture, and publishes them with its style for every theme; `stats.declared` tells whether
|
|
59
|
-
it does. Without
|
|
63
|
+
it does. Without an enabled description the renderer stays off and mounts no layer:
|
|
60
64
|
|
|
61
65
|
<!-- docs:check -->
|
|
62
66
|
|
|
63
67
|
```ts
|
|
64
|
-
import {defineMap, refine} from '@tileflow/core';
|
|
68
|
+
import {defineMap, fixed, refine} from '@tileflow/core';
|
|
65
69
|
import {streets} from '@tileflow/maps';
|
|
66
70
|
|
|
67
71
|
export default defineMap({
|
|
@@ -71,7 +75,14 @@ export default defineMap({
|
|
|
71
75
|
extends: streets,
|
|
72
76
|
modules: {
|
|
73
77
|
// Sodium-orange light, a little brighter, on every street of tiles that map few lamps.
|
|
74
|
-
roads: refine({
|
|
78
|
+
roads: refine({
|
|
79
|
+
streetLights: {
|
|
80
|
+
enabled: true,
|
|
81
|
+
color: fixed('#ffb35c', {reason: 'Constant sodium-lamp color.'}),
|
|
82
|
+
intensity: 1.3,
|
|
83
|
+
estimate: 'streets',
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
75
86
|
},
|
|
76
87
|
});
|
|
77
88
|
```
|
|
@@ -89,11 +100,16 @@ street rather than as lamps that may not stand there.
|
|
|
89
100
|
|
|
90
101
|
`color` is the light of the lamps whose data gives no colour, a warm white by default, and
|
|
91
102
|
`intensity` scales the light from 0 to 2 (1 by default); both may be theme tokens and mix during a
|
|
92
|
-
blend. `streetLights: {enabled: false}` gives
|
|
103
|
+
blend. These settings apply only after `enabled: true`; `streetLights: {enabled: false}` gives
|
|
104
|
+
the map none.
|
|
93
105
|
|
|
94
106
|
## Options
|
|
95
107
|
|
|
96
|
-
The layer
|
|
108
|
+
The layer follows the compiled map by default. `createTileflowStreetLights({map, controller,
|
|
109
|
+
enabled: true})` explicitly enables the fallback design for a style without street-light metadata;
|
|
110
|
+
`enabled: false` keeps the renderer off even when the map declares lights.
|
|
111
|
+
|
|
112
|
+
The delivery options are `minzoom` (14 by default) and `maxTiles` (25
|
|
97
113
|
by default, at most 64) bound where and how far the lights shine, `beforeId` places the layer before
|
|
98
114
|
another one, and `transformRequest` applies the map's request rules to the tiles it reads.
|
|
99
115
|
|
package/docs/sun-and-light.md
CHANGED
|
@@ -15,8 +15,8 @@ application's own WebGL layers to draw, from the values `getSun()` returns.
|
|
|
15
15
|
## Describe a theme's sun
|
|
16
16
|
|
|
17
17
|
Set `lighting.sun` and `lighting.ambient` in the theme. Every value is optional; unset values take
|
|
18
|
-
the defaults in `tileflowDefaultSunPreset` (azimuth 210°, altitude 60°, white light at 0.
|
|
19
|
-
|
|
18
|
+
the defaults in `tileflowDefaultSunPreset` (azimuth 210°, altitude 60°, white light at 0.2, full
|
|
19
|
+
shadow strength, a white sky at 0.8 for soft daylight shadows):
|
|
20
20
|
|
|
21
21
|
<!-- docs:check -->
|
|
22
22
|
|
|
@@ -43,6 +43,46 @@ others are inherited. The compiled style carries the resolved sun in its metadat
|
|
|
43
43
|
direction in `lighting.position` no longer apply to a theme with a sun. A theme without `sun` or
|
|
44
44
|
`ambient` compiles exactly as before.
|
|
45
45
|
|
|
46
|
+
## Replace inherited lighting
|
|
47
|
+
|
|
48
|
+
`defineTheme(base, definition)` normally merges lighting field by field. An empty `lighting`,
|
|
49
|
+
`sun`, or `ambient` object therefore preserves inherited values. Use the existing `reset()`
|
|
50
|
+
operation to remove a preset explicitly while keeping the base theme's palette and typography:
|
|
51
|
+
|
|
52
|
+
<!-- docs:check -->
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import {defineTheme, reset} from '@tileflow/core';
|
|
56
|
+
import {streetsThemes} from '@tileflow/maps';
|
|
57
|
+
|
|
58
|
+
export const studio = defineTheme(streetsThemes.light, {
|
|
59
|
+
id: 'studio',
|
|
60
|
+
version: 1,
|
|
61
|
+
colorScheme: 'light',
|
|
62
|
+
lighting: {
|
|
63
|
+
sun: reset(),
|
|
64
|
+
ambient: reset(),
|
|
65
|
+
anchor: 'viewport',
|
|
66
|
+
position: [1.15, 180, 40],
|
|
67
|
+
color: '#FFFFFF',
|
|
68
|
+
intensity: 0.15,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Removing both presets lets the native extrusion light use the authored `anchor` and `position`.
|
|
74
|
+
Resetting only `sun` keeps an inherited ambient preset, and resetting only `ambient` keeps the sun;
|
|
75
|
+
the missing counterpart then uses the SDK defaults. `lighting: reset()` clears all inherited
|
|
76
|
+
lighting properties. A direct property such as `position`, `color`, or `intensity` can also be
|
|
77
|
+
reset. The result is a complete theme with those properties absent; it contains no reset nodes.
|
|
78
|
+
To replace a whole sun or ambient object, first derive a theme that resets that object, then derive
|
|
79
|
+
the replacement values from the cleared theme.
|
|
80
|
+
|
|
81
|
+
Removing a preset does not turn off the renderer's lighting, cast shadows, or ambient occlusion.
|
|
82
|
+
The SDK's 3D scene uses its fallback light when no preset is published. For a graphic building
|
|
83
|
+
style, choose the building module's `lighting: 'style'`, `shadows: false`, and `occlusion: false`
|
|
84
|
+
explicitly. A single static theme needs no time-of-day family or running clock.
|
|
85
|
+
|
|
46
86
|
## Read the sun in an application
|
|
47
87
|
|
|
48
88
|
`themeController.getSun()` returns the sun the map shows:
|
|
@@ -15,6 +15,61 @@ same token keys, so changing a theme can never change map structure or silently
|
|
|
15
15
|
role. `defineTheme(base, definition)` is an authoring convenience that returns a fully materialized
|
|
16
16
|
document; it does not leave an inheritance edge in the resolved config.
|
|
17
17
|
|
|
18
|
+
## Start with one appearance
|
|
19
|
+
|
|
20
|
+
A map can have one appearance for its entire lifetime. Neither `systemThemes` nor `timeOfDay` is
|
|
21
|
+
required. This complete theme supplies the twelve base color roles the semantic compiler needs;
|
|
22
|
+
copy it and change its colors to start an independent design without inheriting an official map:
|
|
23
|
+
|
|
24
|
+
<!-- docs:check -->
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {defineTheme} from '@tileflow/core';
|
|
28
|
+
|
|
29
|
+
export const paper = defineTheme({
|
|
30
|
+
id: 'paper',
|
|
31
|
+
version: 1,
|
|
32
|
+
colorScheme: 'light',
|
|
33
|
+
tokens: {
|
|
34
|
+
color: {
|
|
35
|
+
'surface.background': '#F6F7F3',
|
|
36
|
+
'surface.land': '#F1F3ED',
|
|
37
|
+
'surface.water': '#A9D3F5',
|
|
38
|
+
'surface.park': '#CDE8B5',
|
|
39
|
+
'surface.building': '#E6E3DA',
|
|
40
|
+
'roads.default': '#FFFFFF',
|
|
41
|
+
'roads.major': '#F4C95D',
|
|
42
|
+
'roads.casing': '#D9DEE2',
|
|
43
|
+
'boundaries.default': '#C9D1D9',
|
|
44
|
+
'labels.primary': '#3C4043',
|
|
45
|
+
'labels.muted': '#727B84',
|
|
46
|
+
'labels.halo': '#FFFFFF',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
An existing map definition can select this appearance with `themes: {paper}` and
|
|
53
|
+
`defaultTheme: 'paper'`. Supply that map's data and font assets separately; the default typography
|
|
54
|
+
uses `Noto Sans Regular`. A theme without these base roles is a valid appearance document but cannot
|
|
55
|
+
compile a semantic map. Colors above are an editable starting point, including for monochrome,
|
|
56
|
+
historical, dark-only, or imagined worlds; `colorScheme` describes the appearance for consumers and
|
|
57
|
+
does not generate a palette or choose a time of day.
|
|
58
|
+
|
|
59
|
+
The compiler derives more specific roles when they are absent. For example, primary and motorway
|
|
60
|
+
roads initially use `roads.major`; declaring `roads.motorway` replaces only that derived color.
|
|
61
|
+
Land-use fills, road casings, and label colors have their own semantic roles, so an explicit role
|
|
62
|
+
always wins over its fallback. Use `color.mix()` and `token.color()` in a theme when the relationship
|
|
63
|
+
itself should be authored and inspectable. Derivations resolve during compilation, without a clock
|
|
64
|
+
or a per-frame palette calculation.
|
|
65
|
+
|
|
66
|
+
Add named appearances when the map needs them. A day/night pair does not need dawn or dusk, and a
|
|
67
|
+
theme named `paper` or `fantasy` does not need a temporal family. Declare `timeOfDay` only when the
|
|
68
|
+
application should offer those artistic moments; see
|
|
69
|
+
[time-of-day selection](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/theme-transitions-and-blends.md#time-of-day).
|
|
70
|
+
|
|
71
|
+
## Compose and replace appearance values
|
|
72
|
+
|
|
18
73
|
Some optional tokens are for the application rather than the map's own layers. Route inks
|
|
19
74
|
(`route.line`, `route.casing`, `route.core`, `route.glow`, `route.alternative`,
|
|
20
75
|
`route.glow.opacity` and `route.core.opacity`) set how an application draws its routes; a theme
|
|
@@ -83,6 +138,17 @@ deterministic OKLCH `color.mix()` keep derived palette logic inspectable. Unknow
|
|
|
83
138
|
cross-category refs, token-schema drift, and unresolved visual nodes fail before Style JSON is
|
|
84
139
|
emitted.
|
|
85
140
|
|
|
141
|
+
Theme lighting also supports explicit removal during `defineTheme` composition. Use
|
|
142
|
+
`lighting: reset()` to remove the entire inherited lighting configuration, or
|
|
143
|
+
`lighting: {sun: reset(), ambient: reset()}` to remove those presets while retaining other light
|
|
144
|
+
properties. The same operation can remove a direct property such as `position` or `color`.
|
|
145
|
+
Omitting a property, or supplying an empty object, continues to inherit it. Reset operations are
|
|
146
|
+
materialized immediately and never enter the resolved theme or Style JSON. Removing a lighting
|
|
147
|
+
preset restores the renderer's fallback; it does not disable 3D shadows or occlusion. Those remain
|
|
148
|
+
explicit building settings. See
|
|
149
|
+
[sun and light](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/sun-and-light.md#replace-inherited-lighting)
|
|
150
|
+
for a complete example.
|
|
151
|
+
|
|
86
152
|
There is no physical-layer override for the Tileflow basemap or separate official-map authoring
|
|
87
153
|
surface. Basemap behavior belongs to a typed control or owner-local render stack. Every
|
|
88
154
|
official and application map therefore follows the same schema, inheritance rules, diagnostics,
|
package/docs/trees-3d.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
`createTileflowTrees3D` stands the trees of a Tileflow map's vector tiles round the camera as 3D
|
|
4
4
|
trees, lit by the theme controller's sun. Each tree takes the form and the size its data gives:
|
|
5
5
|
palms, conifers, columns and three broadleaf forms, at their mapped height and crown where the data
|
|
6
|
-
has them. Trees cast shadows on the ground and, with `createTileflowBuildings3D`, on the buildings,
|
|
6
|
+
has them. The data's hedges stand beside them as clipped green walls. Trees cast shadows on the ground and, with `createTileflowBuildings3D`, on the buildings,
|
|
7
7
|
and take the buildings' shadows; nearer buildings hide them.
|
|
8
8
|
|
|
9
9
|
The map describes how its trees look; the renderer only stands them. A map that declares
|
|
@@ -107,7 +107,7 @@ sunk or the layer leaves the map.
|
|
|
107
107
|
|
|
108
108
|
`stats.declared` tells whether the map's style describes 3D trees. When it is false the layer draws
|
|
109
109
|
nothing: declare `vegetation({mode: '3d'})` in the map. `stats` also counts the tiles, the trees
|
|
110
|
-
placed and the trees drawn in the last frame.
|
|
110
|
+
placed, the pieces of hedge placed and the trees drawn in the last frame.
|
|
111
111
|
|
|
112
112
|
## What the trees come from
|
|
113
113
|
|
|
@@ -120,6 +120,10 @@ The renderer reads the source's z15 tiles round the camera:
|
|
|
120
120
|
- World's `canopy` layer, where the data has it: decorative points in urban parks and gardens, each
|
|
121
121
|
standing one to three trees by its canopy cover, inside the room it leaves before a path, a
|
|
122
122
|
building or the park's edge. They stand for measured canopy, not for mapped trees.
|
|
123
|
+
- World's `traffic_control` layer: its hedges (`subclass` `hedge`), the lines OpenStreetMap maps and
|
|
124
|
+
the hedges it maps as areas. A hedge stands as pieces 1.2 metres apart along each line and round
|
|
125
|
+
each area, 0.8 metres thick, at its `height` or 1.3 metres, a metre higher where `hedge` says
|
|
126
|
+
`hedge_bank`. The style still draws the hedge flat underneath, and fences and walls stay flat.
|
|
123
127
|
|
|
124
128
|
| Form | From the data |
|
|
125
129
|
| ---------- | ---------------------------------------------------------------------------- |
|
|
@@ -139,8 +143,12 @@ tile's buffer belong to the neighbouring tile, so no tree stands twice.
|
|
|
139
143
|
|
|
140
144
|
Colours come from the theme: `vegetation.tree.bark`, `vegetation.tree.broadleaf.a` to `.d`,
|
|
141
145
|
`vegetation.tree.conifer.a` to `.c` and `vegetation.tree.palm.a` to `.c`, sunlit, from darkest to
|
|
142
|
-
lightest.
|
|
143
|
-
|
|
146
|
+
lightest. Hedges take `hedgeColors`, the two darkest broadleaf colours unless the map gives its own;
|
|
147
|
+
Streets gives its flat hedge's colours, so a hedge keeps its colour as it rises. `hedges: false`
|
|
148
|
+
leaves hedges flat. A crown facing a sunlit sky takes its colour; shade takes the sky's light, as on 3D
|
|
149
|
+
buildings. At night a neutral lift keeps crown tops visible; grey materials stay grey under neutral
|
|
150
|
+
lighting, while coloured scene lighting can tint them. The vegetation module's `threeDimensional`
|
|
151
|
+
options refine them for one map:
|
|
144
152
|
|
|
145
153
|
<!-- docs:check -->
|
|
146
154
|
|
|
@@ -239,16 +247,20 @@ the same name; omitting `models` inherits them, and `[]` declares none.
|
|
|
239
247
|
The light comes from `controller.getSun()`: the theme's sun, mixed during a blend, or the sun an
|
|
240
248
|
application places by direction or by date and place (see
|
|
241
249
|
[sun and light](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/sun-and-light.md)).
|
|
250
|
+
Without a controller, trees read the compiled style's sun and light direction, falling back to
|
|
251
|
+
SDK daylight, just as 3D buildings do. This cached light refreshes when the style changes.
|
|
242
252
|
Leaves take light round their edges and glow a little against a low sun; the underside and the
|
|
243
253
|
inside of a crown stay darker.
|
|
244
254
|
|
|
245
255
|
Trees and 3D buildings on one map share one shadow map: trees cast shadows on the ground and on the
|
|
246
256
|
buildings, and stand in the buildings' shade. The flat map darkens under both. Without 3D buildings
|
|
247
|
-
the trees darken the map themselves.
|
|
257
|
+
the trees darken the map themselves. The depth pass uses the same visible tree ranks, near/far
|
|
258
|
+
models and distance fade as the colour pass, so hidden trees do not leave full shadows behind.
|
|
259
|
+
Shadow direction stops lowering at 15° above the horizon; the actual scene light keeps its angle.
|
|
248
260
|
|
|
249
261
|
## Options
|
|
250
262
|
|
|
251
|
-
`minzoom` (15 by default) and `maxTiles` (25 by default, at most 64) bound where and how far trees
|
|
263
|
+
`minzoom` (15 by default, fading to full coverage at 15.25 like buildings) and `maxTiles` (25 by default, at most 64) bound where and how far trees
|
|
252
264
|
stand; trees thin out and fade with distance from the map's centre, and near trees take more detail
|
|
253
265
|
than far ones. `canopySource` names a vector source with canopy points when they are not in the
|
|
254
266
|
map's World source. `beforeId` places the layer before another one; `transformRequest` applies the
|
|
@@ -258,9 +270,10 @@ tile's download.
|
|
|
258
270
|
## Cost
|
|
259
271
|
|
|
260
272
|
A near tree has 60 to 120 triangles and a far one about 20, and each form is one instanced draw per
|
|
261
|
-
tile. The shadow map
|
|
262
|
-
|
|
263
|
-
|
|
273
|
+
tile. The shared shadow map concentrates resolution on the view when its public camera methods
|
|
274
|
+
provide a safe planar fit. It is drawn again when that focused area, the light, visible tree
|
|
275
|
+
selection, fading or geometry changes. Unchanged views reuse it. Over the Champ de Mars in Paris,
|
|
276
|
+
where OpenStreetMap maps every tree, about 13,000 trees stand in a pitched view at zoom 16.6.
|
|
264
277
|
|
|
265
278
|
## Limits
|
|
266
279
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tileflow/core",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.37",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Typed Tileflow config and MapLibre style compiler.",
|
|
6
6
|
"type": "module",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"whatwg-url": "17.2.0"
|
|
91
91
|
},
|
|
92
92
|
"scripts": {
|
|
93
|
-
"build": "tsup --config tsup.build.config.ts && tsup --config tsup.native-profile.config.ts && tsup
|
|
93
|
+
"build": "tsup --config tsup.build.config.ts && tsup --config tsup.native-profile.config.ts && tsup --config tsup.browser.config.ts && tsup --config tsup.native.config.ts && cp ../../docs/modules-api-reference.json dist/config-reference.json",
|
|
94
94
|
"reference:check": "tsx scripts/generate-config-reference.ts --check",
|
|
95
95
|
"reference:generate": "tsx scripts/generate-config-reference.ts --write",
|
|
96
96
|
"verify": "pnpm run build && tsx --test test/*.test.ts",
|