@tileflow/core 0.1.0-alpha.41 → 0.1.0-alpha.43
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 +51 -69
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/{3d-CzLTD0RK.d.ts → 3d-CW5Ls0An.d.ts} +32 -2
- package/dist/3d.d.ts +1 -1
- package/dist/3d.js +337 -34
- package/dist/browser.d.ts +119 -7
- package/dist/browser.js +754 -61
- package/dist/build.d.ts +8 -4
- package/dist/build.js +284 -4
- package/dist/config-reference.json +4005 -2284
- package/dist/{icon-composition-HUh_Lj8Z.d.ts → icon-composition-Bbw9umUA.d.ts} +46 -3
- package/dist/index.d.ts +22 -5
- package/dist/index.js +254 -6
- package/dist/{manifest-types-DnhSJjCM.d.ts → manifest-types-CwjHd4qc.d.ts} +10 -0
- package/dist/manifest.d.ts +2 -2
- package/dist/native-profile.d.ts +4 -0
- package/dist/native-profile.js +2 -0
- package/dist/native.d.ts +87 -1
- package/dist/native.js +980 -460
- package/dist/runtime.d.ts +1 -1
- package/dist/worker/camera-tile-worker.global.js +2 -2
- package/package.json +4 -5
- package/docs/application-tile-reading.md +0 -86
- package/docs/authoring-model.md +0 -269
- package/docs/boundary-areas-and-choropleths.md +0 -217
- package/docs/buildings-3d.md +0 -608
- package/docs/camera-moves-and-tile-cache.md +0 -112
- package/docs/capture-scenes.md +0 -40
- package/docs/capture-shots.md +0 -173
- package/docs/cartographic-defaults.md +0 -210
- package/docs/compiled-style-performance.md +0 -286
- package/docs/data-is-separate-from-design.md +0 -610
- package/docs/depth-markers.md +0 -65
- package/docs/dynamic-style-images.md +0 -100
- package/docs/globe-atmosphere.md +0 -113
- package/docs/hosted-session-authorization.md +0 -106
- package/docs/map-and-terrain-examples.md +0 -156
- package/docs/map-emphasis.md +0 -89
- package/docs/native-artifact-profile.md +0 -152
- package/docs/native-resource-urls.md +0 -369
- package/docs/nautical-marks.md +0 -308
- package/docs/public-api-and-browser-subpath.md +0 -101
- package/docs/route-drawing.md +0 -191
- package/docs/shared-visual-primitives.md +0 -101
- package/docs/street-lights.md +0 -127
- package/docs/street-sky.md +0 -156
- package/docs/style-states.md +0 -73
- package/docs/sun-and-light.md +0 -167
- package/docs/theme-transitions-and-blends.md +0 -317
- package/docs/themes-and-module-styles.md +0 -156
- package/docs/trees-3d.md +0 -295
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# Dynamic style images
|
|
2
|
-
|
|
3
|
-
Use `registerImage` on an existing `TileflowThemeController` from `@tileflow/core/browser` when an
|
|
4
|
-
application draws RGBA pixels that depend on a theme or style state. The controller owns the image's
|
|
5
|
-
registration, refresh and restoration. The application owns its drawing and prepares asynchronous
|
|
6
|
-
assets before registration. This browser API is tested with MapLibre GL JS 6.13; it is not a Native
|
|
7
|
-
or Static Maps image contract.
|
|
8
|
-
|
|
9
|
-
Start with the [Core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md)
|
|
10
|
-
and [theme controller setup](theme-transitions-and-blends.md#use-the-core-controller).
|
|
11
|
-
The map's symbol layer must already refer to the same image ID in every theme. Register before its
|
|
12
|
-
first placement. Choose an ID that does not exist in the sprite or belong to another application
|
|
13
|
-
resource. Registering an image does not create a layer or add points to a source.
|
|
14
|
-
|
|
15
|
-
## Draw an alert from state
|
|
16
|
-
|
|
17
|
-
This helper runs after browser mounting, with the controller for the existing map. The image is
|
|
18
|
-
64 physical pixels at pixel ratio 2, so it occupies 32 logical pixels before the layer's icon scale.
|
|
19
|
-
|
|
20
|
-
<!-- docs:check -->
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
import type {TileflowThemeController} from '@tileflow/core/browser';
|
|
24
|
-
|
|
25
|
-
export function registerAlert(controller: TileflowThemeController) {
|
|
26
|
-
const canvas = document.createElement('canvas');
|
|
27
|
-
canvas.width = canvas.height = 64;
|
|
28
|
-
const context = canvas.getContext('2d', {willReadFrequently: true});
|
|
29
|
-
if (!context) throw new Error('Canvas 2D is unavailable.');
|
|
30
|
-
|
|
31
|
-
return controller.registerImage('live-alert', {
|
|
32
|
-
width: 64,
|
|
33
|
-
height: 64,
|
|
34
|
-
pixelRatio: 2,
|
|
35
|
-
states: ['alert'],
|
|
36
|
-
render({theme, states}) {
|
|
37
|
-
context.clearRect(0, 0, 64, 64);
|
|
38
|
-
context.beginPath();
|
|
39
|
-
context.arc(32, 32, 24, 0, Math.PI * 2);
|
|
40
|
-
context.fillStyle = states.alert ? '#ee624e' : '#edbd53';
|
|
41
|
-
context.fill();
|
|
42
|
-
context.strokeStyle = theme === 'night' ? '#ffffff' : '#253b42';
|
|
43
|
-
context.lineWidth = 4;
|
|
44
|
-
context.stroke();
|
|
45
|
-
return context.getImageData(0, 0, 64, 64).data;
|
|
46
|
-
},
|
|
47
|
-
onError(error) {
|
|
48
|
-
console.error('Alert image could not refresh:', error);
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export async function activateAlert(controller: TileflowThemeController) {
|
|
54
|
-
await controller.setState('alert', true);
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
The resource receives the states listed in `states`, including intermediate values during numeric
|
|
59
|
-
state transitions. `theme` is the committed theme, or the nearest theme of a blend. `blend` exposes
|
|
60
|
-
its position and ordered theme names for continuous artwork interpolation. States not set through
|
|
61
|
-
this controller remain undefined; an explicit null is distinct from an unset state.
|
|
62
|
-
|
|
63
|
-
## Update and release
|
|
64
|
-
|
|
65
|
-
Theme changes and changes to declared states schedule a refresh. Identical inputs do no work;
|
|
66
|
-
several changes before the next animation frame coalesce. The `setState` promise describes the
|
|
67
|
-
state transition, not completion of the next image frame. There is no independent animation clock.
|
|
68
|
-
For camera values, new application data or another external input, call the returned handle's
|
|
69
|
-
`refresh()`. Read those values inside `render`, and return `undefined` when the existing pixels are
|
|
70
|
-
still correct. Undefined output on the first render creates a transparent image.
|
|
71
|
-
|
|
72
|
-
`render` is synchronous and returns exactly `width * height * 4` RGBA bytes as a `Uint8Array` or
|
|
73
|
-
`Uint8ClampedArray`. The controller copies the buffer. Width and height must be integers from 1
|
|
74
|
-
through 2048; pixel ratio must be positive and finite. All three remain fixed until disposal.
|
|
75
|
-
Changing pixel ratio while keeping physical size would change logical size and collision geometry,
|
|
76
|
-
so choose it at registration rather than following device pixel ratio changes automatically.
|
|
77
|
-
|
|
78
|
-
A style reload restores the last valid image before placement. WebGL context loss suspends image
|
|
79
|
-
work; restoration replays pixels and processes pending inputs. `handle.dispose()` removes only
|
|
80
|
-
that resource's image and cancels its pending work. `controller.dispose()` releases all of its
|
|
81
|
-
images. Map removal cancels work and releases listeners. Disposal is idempotent.
|
|
82
|
-
|
|
83
|
-
Invalid registration throws before claiming a resource. Later render failures keep the last valid
|
|
84
|
-
pixels and call `onError`, or `console.error` when omitted. A later refresh can retry. Another image
|
|
85
|
-
owner is never silently overwritten. The application must not call `addImage`, `updateImage` or
|
|
86
|
-
`removeImage` for a registered ID. Dynamic IDs must stay identical across blended themes; mixing
|
|
87
|
-
them with theme-specific atlas artwork is rejected before the blend replaces the style.
|
|
88
|
-
|
|
89
|
-
## Placement and scope
|
|
90
|
-
|
|
91
|
-
This API changes image pixels only. It does not resize icons, split layers, change padding,
|
|
92
|
-
anchors, sort order, overlap, filters or source features. Native symbol placement and collisions
|
|
93
|
-
remain governed by the authored style. Transparent pixels still occupy the image's existing
|
|
94
|
-
geometry: this API does not define separate visual and collision bounds.
|
|
95
|
-
|
|
96
|
-
All features using an ID share its pixels and state. Independent per-feature animation, SDF
|
|
97
|
-
generation, image loading, GPU composition and automatic framework props are outside this API.
|
|
98
|
-
Keep every selectable icon in the same symbol layer RGBA, including fallbacks; mixing these images
|
|
99
|
-
with SDF icons does not become supported through registration.
|
|
100
|
-
Profile the application's drawing cost and visible symbol rendering on its target devices.
|
package/docs/globe-atmosphere.md
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
# Globe atmosphere
|
|
2
|
-
|
|
3
|
-
Enable atmosphere in the map exported by `tileflow.config.ts`. Install `@tileflow/core` and
|
|
4
|
-
`@tileflow/maps` and use a browser adapter from the same compatible SDK release. The example
|
|
5
|
-
extends the complete Streets map, including its data and text resources.
|
|
6
|
-
|
|
7
|
-
<!-- docs:check -->
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import {defineMap} from '@tileflow/core';
|
|
11
|
-
import {streets} from '@tileflow/maps';
|
|
12
|
-
|
|
13
|
-
export default defineMap({
|
|
14
|
-
id: 'earth',
|
|
15
|
-
version: 1,
|
|
16
|
-
extends: streets,
|
|
17
|
-
projection: 'globe',
|
|
18
|
-
atmosphere: true,
|
|
19
|
-
view: {center: [2.3522, 48.8566], zoom: 2},
|
|
20
|
-
});
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
The result has a pale white rim with a soft blue halo, a muted blue-gray space background, and a
|
|
24
|
-
deterministic field of 1,100 stars per repeating 1,600 × 1,000 CSS-pixel area. The halo follows the
|
|
25
|
-
globe's contour without brightening its surface or adding glow to labels. Stars have a minimum
|
|
26
|
-
radius of 0.6 CSS pixels so the fainter stars remain visible on high-density screens.
|
|
27
|
-
Stars move slightly with the camera. There is no continuous animation while the camera is still.
|
|
28
|
-
The space background, stars, and rim fade between zooms 3 and 6. Native sun scattering is disabled
|
|
29
|
-
when `atmosphere` is enabled, including maps that also declare `sky`. Coordinates are longitude,
|
|
30
|
-
then latitude.
|
|
31
|
-
|
|
32
|
-
Omit `atmosphere` to inherit it from the base map. A map without inherited atmosphere remains
|
|
33
|
-
unchanged. Set `atmosphere: false` to disable an inherited atmosphere. An enabled atmosphere requires
|
|
34
|
-
`projection: 'globe'`; validation rejects a Mercator or unspecified projection. Atmosphere options
|
|
35
|
-
replace the inherited object atomically rather than merging individual fields.
|
|
36
|
-
|
|
37
|
-
## Configure appearance
|
|
38
|
-
|
|
39
|
-
Use an object instead of `true` to override defaults:
|
|
40
|
-
|
|
41
|
-
| Option | Default | Meaning |
|
|
42
|
-
| --------------- | --------- | -------------------------------------------------------------- |
|
|
43
|
-
| `skyColor` | `#263b50` | Near-space sky color |
|
|
44
|
-
| `horizonColor` | `#b6cfe2` | Horizon and outer halo color |
|
|
45
|
-
| `fogColor` | `#d4e1ec` | Native atmospheric fog color |
|
|
46
|
-
| `spaceColor` | `#142233` | Outer space background color |
|
|
47
|
-
| `starColor` | `#e0ebff` | Star color |
|
|
48
|
-
| `starCount` | `1100` | Stars per repeating 1600 × 1000 CSS-pixel area; integer 0–4096 |
|
|
49
|
-
| `starSize` | `1` | Radius multiplier from 0 to 4; 0 hides stars |
|
|
50
|
-
| `starIntensity` | `0.6` | Brightness from 0 to 1; 0 hides stars |
|
|
51
|
-
| `starParallax` | `0.4` | Camera-relative motion from 0 to 1; 0 keeps stars still |
|
|
52
|
-
|
|
53
|
-
Colors follow the usual theme contract: use `token.color(...)`, color operations, or
|
|
54
|
-
`fixed(color, {reason})`. They must resolve to opaque colors. Compilation normalizes them to
|
|
55
|
-
six-digit hexadecimal values in the runtime metadata. Numeric options must be finite and within
|
|
56
|
-
the ranges above. `starCount` controls density rather than the total visible count: the field
|
|
57
|
-
repeats on larger viewports. `starSize` scales both the stars and their glow; changing density
|
|
58
|
-
preserves the positions of existing stars. Unknown properties are rejected. For example, this fragment belongs inside `defineMap(...)`
|
|
59
|
-
and uses `fixed` imported from `@tileflow/core`:
|
|
60
|
-
|
|
61
|
-
```ts
|
|
62
|
-
atmosphere: {
|
|
63
|
-
horizonColor: fixed('#b6cfe2', {reason: 'Earth atmosphere stays blue across map themes'}),
|
|
64
|
-
starCount: 650,
|
|
65
|
-
starSize: 0.8,
|
|
66
|
-
starColor: fixed('#e0ebff', {reason: 'Cool stars across map themes'}),
|
|
67
|
-
starIntensity: 0.5,
|
|
68
|
-
starParallax: 0.25,
|
|
69
|
-
},
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
The browser's reduced-motion preference overrides parallax while keeping the sky and stars visible.
|
|
73
|
-
No additional image, font, API key, or network request is needed for the effect.
|
|
74
|
-
|
|
75
|
-
## Browser integration
|
|
76
|
-
|
|
77
|
-
The compiler emits MapLibre `sky` and versioned `metadata['tileflow:atmosphere']` in every concrete
|
|
78
|
-
style. React, Vue, Svelte, Inspector, and standalone browser capture attach the shared atmosphere
|
|
79
|
-
runtime. Metadata version 2 includes star appearance; the runtime also reads version 1 with
|
|
80
|
-
the established star defaults. Use matching compiler and browser packages for new styles.
|
|
81
|
-
Theme changes update the effect from the newly loaded style. Loading a style without atmosphere
|
|
82
|
-
removes the decoration.
|
|
83
|
-
|
|
84
|
-
When constructing a MapLibre map directly, call `attachTileflowAtmosphere(map)` from
|
|
85
|
-
`@tileflow/core/browser` after constructing the map. Keep its returned cleanup function and call it
|
|
86
|
-
before removing the map; the map's `remove` event also disposes it. The helper creates its own
|
|
87
|
-
noninteractive, accessibility-hidden canvases for the stars and halo behind the map. A custom layer
|
|
88
|
-
reads the globe projection; the halo stays outside theme snapshots, preserving its appearance
|
|
89
|
-
through time-of-day transitions. It does not create a map, change the camera, filter the map canvas,
|
|
90
|
-
or add controls.
|
|
91
|
-
Preserve the renderer's transparent canvas and standard
|
|
92
|
-
MapLibre CSS so space can show around the globe.
|
|
93
|
-
|
|
94
|
-
For a camera-driven presentation, the optional second argument can adjust star speed and direction:
|
|
95
|
-
`attachTileflowAtmosphere(map, {starParallaxScale: -5})` moves stars five times as fast in the
|
|
96
|
-
opposite direction. The multiplier must be finite; it defaults to `1`, and `0` freezes the stars.
|
|
97
|
-
This runtime option does not change the compiled style or animate a stationary map. Reduced motion
|
|
98
|
-
still disables star movement, and stopping the camera also stops the stars.
|
|
99
|
-
Use the map's `starParallax` for its authored appearance; reserve `starParallaxScale` for the
|
|
100
|
-
embedding application's camera presentation. The effective motion multiplies both values, so a
|
|
101
|
-
map declaring `starParallax: 0` remains stationary under any runtime multiplier. Inspector preview
|
|
102
|
-
uses the shared atmosphere helper with its default multiplier, just like the framework adapters.
|
|
103
|
-
|
|
104
|
-
Importing the browser entry is safe during server rendering. Call the attachment only in the
|
|
105
|
-
browser, after mounting. Raw MapLibre consumers must attach the helper to display the globe halo,
|
|
106
|
-
stars, and space background. The compiled sky alone does not include these effects.
|
|
107
|
-
|
|
108
|
-
A map that also declares a [street sky](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/street-sky.md)
|
|
109
|
-
uses the sky's colors for MapLibre's `sky`; the atmosphere keeps its halo, space background and stars.
|
|
110
|
-
|
|
111
|
-
The native artifact profile does not support globe atmosphere and rejects `sky`. This browser
|
|
112
|
-
capability does not establish React Native or hosted Static Maps support. Public availability is
|
|
113
|
-
established by the installed package version, not by this repository's main branch.
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# Hosted session authorization
|
|
2
|
-
|
|
3
|
-
Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
|
|
4
|
-
|
|
5
|
-
The framework adapters use `createTileflowSessionController` to obtain one short-lived session
|
|
6
|
-
grant before eligible hosted style, tile, font, or sprite requests. Concurrent resources share the
|
|
7
|
-
same preflight, grants are attached only to reviewed HTTP(S) origins, and an expired unused session
|
|
8
|
-
rotates once when the server requests it. A controller also rotates after six hours or 10,000
|
|
9
|
-
eligible requests. The preflight has a 10-second client timeout by default; direct controller users
|
|
10
|
-
can set `grantTimeoutMs` from 1 to 120,000 milliseconds.
|
|
11
|
-
|
|
12
|
-
`analytics.enabled: false` disables only the optional analytics beacon. It does not disable this
|
|
13
|
-
server-owned commercial authorization. User `transformRequest` callbacks still run first; Tileflow
|
|
14
|
-
then decorates only the resulting eligible URL and preserves the other request options.
|
|
15
|
-
|
|
16
|
-
Set `analytics.surfaceId` to a stable product location when the same Map appears in several places:
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
const analytics = {surfaceId: 'store-locator'};
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
A Surface ID is 1–64 lowercase ASCII letters, digits, `.`, `_`, or `-`; it starts and ends with a
|
|
23
|
-
letter or digit. Missing or invalid values become `default`. Use a durable integration name such as
|
|
24
|
-
`checkout` or `dealer-search`, not a URL, branch, preview, random component instance, or user ID.
|
|
25
|
-
Surface labels do not change authorization, entitlement, or Session identity.
|
|
26
|
-
|
|
27
|
-
For exact Tileflow World release tiles, framework adapters also use the browser request bridge to
|
|
28
|
-
observe the response's safe fair-use state without adding identity, query parameters, credentials,
|
|
29
|
-
or user headers to the public World URL. The bridge requires the immutable release path and exactly
|
|
30
|
-
one lowercase descriptor digest; the retired mutable World template is never intercepted. Early
|
|
31
|
-
`GRACE` stays silent; signed late `GRACE` creates a compact
|
|
32
|
-
accessible owner-action pill, and `MANAGED_REQUIRED` creates a stronger in-map banner. A missing
|
|
33
|
-
header, absent tile, MapLibre error, or failed response cannot erase an existing manage action; a
|
|
34
|
-
later successful `OPEN` response can clear it. Shaped empty tiles remain render-safe while the owner
|
|
35
|
-
action stays available. Successful World tile bodies are streamed with a 16 MiB maximum: an
|
|
36
|
-
oversized `Content-Length` is rejected before reading, and chunked responses are cancelled as soon
|
|
37
|
-
as their accumulated bytes cross the same bound. Abort signals cancel an active reader; errors do
|
|
38
|
-
not include the remote response body.
|
|
39
|
-
|
|
40
|
-
Other subpaths under `src/`, `themes/`, `templates/`, and `modules/` are internal implementation
|
|
41
|
-
details and can change during alpha releases.
|
|
42
|
-
|
|
43
|
-
Official map definitions and the source assets they own ship together in `@tileflow/maps`, not in
|
|
44
|
-
Core. That package exports the maps and their reusable directory descriptors:
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
import {
|
|
48
|
-
baedeker,
|
|
49
|
-
baedekerFonts,
|
|
50
|
-
baedekerIcons,
|
|
51
|
-
blueprint,
|
|
52
|
-
blueprintIcons,
|
|
53
|
-
civica,
|
|
54
|
-
civicaFonts,
|
|
55
|
-
civicaIcons,
|
|
56
|
-
map1777,
|
|
57
|
-
map1777Icons,
|
|
58
|
-
siegfried,
|
|
59
|
-
siegfriedFonts,
|
|
60
|
-
siegfriedIcons,
|
|
61
|
-
soundings,
|
|
62
|
-
soundingsIcons,
|
|
63
|
-
streets,
|
|
64
|
-
streetsIcons,
|
|
65
|
-
streetsThemes,
|
|
66
|
-
} from '@tileflow/maps';
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
All official maps are complete standalone maps. The sole semantic compiler is implicit; none
|
|
70
|
-
imports or extends another official map, and each declares its own icon directory.
|
|
71
|
-
Streets declares `[streetsIcons]` and exposes its complete coordinated appearances as
|
|
72
|
-
`streetsThemes.light` and `streetsThemes.dark`; image tokens select the matching sidewalk pattern
|
|
73
|
-
without changing the asset collection. Baedeker declares `[baedekerIcons]`, whose eight original
|
|
74
|
-
patterns support its travel-atlas design, and `[baedekerFonts]`, its own Cormorant Garamond
|
|
75
|
-
directory; it derives contours in the browser from unpackaged Mapterhorn terrain tiles. Cívica
|
|
76
|
-
declares `[civicaIcons]` for its original civic-print patterns and destination artwork and
|
|
77
|
-
`[civicaFonts]` for its packaged lettering. Blueprint declares
|
|
78
|
-
`[blueprintIcons]` for its four technical hatches and schematic POI node, derives contours from
|
|
79
|
-
unpackaged Mapterhorn tiles, and uses the canonical Noto Sans glyph provider. The same asset
|
|
80
|
-
operation is available to applications:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
export default defineMap({
|
|
84
|
-
id: 'brand-map',
|
|
85
|
-
version: 1,
|
|
86
|
-
extends: streets,
|
|
87
|
-
icons: [...streets.icons, './icons'],
|
|
88
|
-
});
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
`icons` is a `readonly TileflowIconSource[]`. Omission inherits the parent's exact array,
|
|
92
|
-
declaration replaces it atomically, and `[]` means no icons. Local and package directories, plus
|
|
93
|
-
explicit locked `iconSet('@team/set')` descriptors, apply left to right.
|
|
94
|
-
`<id>.<ext>` publishes an icon as `<id>`; `<id>.pattern.<ext>` publishes an intrinsic-size pattern
|
|
95
|
-
as `<id>`. The published ID must already be canonical lower-kebab; a later exact ID wins and a
|
|
96
|
-
case-only collision fails. There is no built-in selector, mutable external sprite selector, icon
|
|
97
|
-
mapping, icon-specific inheritance, additive command, or compatibility alias. An Icon Set is an
|
|
98
|
-
explicit locked descriptor, not a generic source registry.
|
|
99
|
-
|
|
100
|
-
`@tileflow/dev` resolves local and package directory descriptors, verifies real-path containment,
|
|
101
|
-
and prepares ordinary public artifacts without serializing installation paths. It compiles one
|
|
102
|
-
deterministic sprite from the final icon composition and validates every literal `icon-image`,
|
|
103
|
-
`fill-pattern`, and `line-pattern` in the final style against it. It also prepares any declared font
|
|
104
|
-
directories generically; `baedekerFonts`, `civicaFonts`, and `siegfriedFonts` are
|
|
105
|
-
ordinary package descriptors rather than pipeline special cases. Calling the pure compiler for a map whose style needs unprepared
|
|
106
|
-
assets fails instead of emitting broken runtime references.
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# Map and terrain examples
|
|
2
|
-
|
|
3
|
-
Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
|
|
4
|
-
|
|
5
|
-
Typed Tileflow map contracts, semantic modules, and deterministic MapLibre style compilation.
|
|
6
|
-
|
|
7
|
-
Every public `tileflow.config.ts` exports one map. Most maps import an existing map and override only
|
|
8
|
-
the design fields they own:
|
|
9
|
-
|
|
10
|
-
```ts
|
|
11
|
-
import {
|
|
12
|
-
defineMap,
|
|
13
|
-
defineTheme,
|
|
14
|
-
fixed,
|
|
15
|
-
labels,
|
|
16
|
-
poi,
|
|
17
|
-
roads,
|
|
18
|
-
token,
|
|
19
|
-
water,
|
|
20
|
-
zoom,
|
|
21
|
-
} from '@tileflow/core';
|
|
22
|
-
import {streets, streetsThemes} from '@tileflow/maps';
|
|
23
|
-
|
|
24
|
-
const madridDark = defineTheme(streetsThemes.dark, {
|
|
25
|
-
id: 'madrid-dark',
|
|
26
|
-
version: 1,
|
|
27
|
-
colorScheme: 'dark',
|
|
28
|
-
tokens: {color: {'surface.land': '#0d1320', 'surface.water': '#081e2e'}},
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
export default defineMap({
|
|
32
|
-
id: 'madrid',
|
|
33
|
-
name: 'Madrid',
|
|
34
|
-
version: 1,
|
|
35
|
-
extends: streets,
|
|
36
|
-
themes: {light: streetsThemes.light, dark: madridDark},
|
|
37
|
-
defaultTheme: 'light',
|
|
38
|
-
systemThemes: {light: 'light', dark: 'dark'},
|
|
39
|
-
projection: 'globe',
|
|
40
|
-
modules: {
|
|
41
|
-
water: water({
|
|
42
|
-
bodies: {
|
|
43
|
-
fill: {
|
|
44
|
-
opacity: fixed(0.95, {reason: 'Madrid keeps this water density in every theme'}),
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
}),
|
|
48
|
-
roads: roads({
|
|
49
|
-
detail: 'streets',
|
|
50
|
-
hierarchy: 'strong',
|
|
51
|
-
classes: {
|
|
52
|
-
primary: {
|
|
53
|
-
surface: {
|
|
54
|
-
fill: {
|
|
55
|
-
color: fixed('#E4A85B', {reason: 'Madrid brand roads stay warm in every theme'}),
|
|
56
|
-
width: zoom.linear([
|
|
57
|
-
[7, fixed(0.6, {reason: 'Madrid keeps its primary-road hierarchy across themes'})],
|
|
58
|
-
[16, fixed(8, {reason: 'Madrid keeps its primary-road hierarchy across themes'})],
|
|
59
|
-
]),
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
secondary: {surface: {fill: {color: token.color('roads.secondary')}}},
|
|
64
|
-
},
|
|
65
|
-
}),
|
|
66
|
-
labels: labels({
|
|
67
|
-
language: 'local',
|
|
68
|
-
places: 'all',
|
|
69
|
-
roads: 'streets',
|
|
70
|
-
styles: {
|
|
71
|
-
places: {
|
|
72
|
-
city: {
|
|
73
|
-
text: {
|
|
74
|
-
size: fixed(18, {reason: 'Madrid keeps its city-label scale across themes'}),
|
|
75
|
-
haloWidth: fixed(1.5, {reason: 'Madrid keeps its city-label halo across themes'}),
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
}),
|
|
81
|
-
poi: poi({categories: ['food-drink', 'arts-entertainment', 'transport'], color: 'category'}),
|
|
82
|
-
},
|
|
83
|
-
view: {center: [-3.7038, 40.4168], pitch: 35, zoom: 12},
|
|
84
|
-
});
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Map identity and scenes belong to the leaf and do not inherit. Hosted browser policy is configured
|
|
88
|
-
in Tileflow and does not enter cartographic authoring or compilation.
|
|
89
|
-
|
|
90
|
-
Set `projection: 'globe'` for MapLibre's adaptive globe preset. Global zooms render as a sphere,
|
|
91
|
-
then transition to Mercator between zoom 10 and 12 so detailed streets remain planar. Omit the
|
|
92
|
-
property, or set it to `'mercator'`, for a consistently flat map.
|
|
93
|
-
|
|
94
|
-
Terrain keeps the original `'none' | 'hillshade' | '3d'` shorthand. The object form can style every
|
|
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
|
|
105
|
-
contours without adding a raster source, hillshade, or 3D terrain:
|
|
106
|
-
|
|
107
|
-
```ts
|
|
108
|
-
terrain: {
|
|
109
|
-
mode: 'none',
|
|
110
|
-
encoding: 'terrarium',
|
|
111
|
-
contours: {
|
|
112
|
-
demUrl: 'https://terrain.example.test/{z}/{x}/{y}.webp',
|
|
113
|
-
demMaxZoom: 13,
|
|
114
|
-
maxZoom: 15,
|
|
115
|
-
overzoom: 2,
|
|
116
|
-
thresholds: {
|
|
117
|
-
9: [100, 500],
|
|
118
|
-
11: [50, 250],
|
|
119
|
-
13: [20, 100],
|
|
120
|
-
15: [10, 50],
|
|
121
|
-
},
|
|
122
|
-
minor: {
|
|
123
|
-
color: token.color('terrain.contour.minor'),
|
|
124
|
-
width: token.number('terrain.contour.minor-width'),
|
|
125
|
-
},
|
|
126
|
-
index: {
|
|
127
|
-
color: token.color('terrain.contour.index'),
|
|
128
|
-
width: token.number('terrain.contour.index-width'),
|
|
129
|
-
},
|
|
130
|
-
labels: {
|
|
131
|
-
color: token.color('terrain.contour.label'),
|
|
132
|
-
haloColor: token.color('terrain.contour.halo'),
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Declare those `terrain.*` color and number roles with the same keys in every map theme. The
|
|
139
|
-
compiled source is ordinary MapLibre vector data with source layer `contours`; its tile URL
|
|
140
|
-
contains the safely encoded DEM template and complete generation parameters. Register the generic
|
|
141
|
-
protocol before MapLibre reads the style. It lazily initializes the pinned, locally bundled
|
|
142
|
-
`maplibre-contour@0.1.0` browser module on the first contour tile; no public CDN runtime is needed.
|
|
143
|
-
`overzoom` may not exceed the lowest threshold zoom, so generated DEM requests never use a negative
|
|
144
|
-
zoom. Every index interval must be a whole multiple of its minor interval. Contour labels emit the
|
|
145
|
-
scaled numeric elevation without assuming a display unit. Source and layer visibility cannot begin
|
|
146
|
-
before the first configured threshold zoom. To bound main-thread work, effective minor intervals
|
|
147
|
-
must be at least 250 units at z0–4, 100 at z5–7, 50 at z8–10, 20 at z11–12, and 10 from z13 onward.
|
|
148
|
-
Use a trusted, size-bounded DEM tile service; the protocol intentionally accepts author-supplied
|
|
149
|
-
HTTP(S) templates rather than proxying or republishing terrain data.
|
|
150
|
-
|
|
151
|
-
```ts
|
|
152
|
-
import maplibregl from 'maplibre-gl';
|
|
153
|
-
import {registerTileflowContourProtocol} from '@tileflow/core/browser';
|
|
154
|
-
|
|
155
|
-
registerTileflowContourProtocol({addProtocol: maplibregl.addProtocol});
|
|
156
|
-
```
|
package/docs/map-emphasis.md
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# Map emphasis
|
|
2
|
-
|
|
3
|
-
Start with the [@tileflow/core guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md) for installation and a complete first example.
|
|
4
|
-
|
|
5
|
-
An application that draws its own content over a Tileflow map, such as a route, a selected place, or
|
|
6
|
-
search results, often needs the map to step back so that content reads first. Map emphasis does
|
|
7
|
-
that on the map's own MapLibre instance: chosen modules recede towards the map's ground colour, and
|
|
8
|
-
the map's labels and icons fade, except inside an area the application keeps at full strength. The
|
|
9
|
-
change eases in and out, stays when the theme changes, and follows a theme blend.
|
|
10
|
-
|
|
11
|
-
Emphasis needs a browser document and MapLibre GL JS. It changes only the layers a Tileflow map
|
|
12
|
-
compiled, so an application's own layers, such as the route it draws, keep their appearance.
|
|
13
|
-
|
|
14
|
-
## Show an emphasis
|
|
15
|
-
|
|
16
|
-
Create the theme controller for the map, then ask for an emphasis. This example assumes an existing
|
|
17
|
-
MapLibre map named `map` that shows the `dark` theme of a published Tileflow map, and a route the
|
|
18
|
-
application has already drawn:
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
import type {Map as MapLibreMap} from 'maplibre-gl';
|
|
22
|
-
import {createTileflowThemeController} from '@tileflow/core/browser';
|
|
23
|
-
|
|
24
|
-
export function focusOnRoute(map: MapLibreMap, styleUrl: string) {
|
|
25
|
-
const controller = createTileflowThemeController({
|
|
26
|
-
initial: {style: styleUrl, theme: 'dark'},
|
|
27
|
-
map,
|
|
28
|
-
});
|
|
29
|
-
void controller.setEmphasis(
|
|
30
|
-
{
|
|
31
|
-
labels: 0.6,
|
|
32
|
-
recede: {boundaries: 0.55, roads: 0.5, transit: 0.5},
|
|
33
|
-
},
|
|
34
|
-
{transition: {duration: 560}},
|
|
35
|
-
);
|
|
36
|
-
return () => controller.setEmphasis(undefined, {transition: {duration: 560}});
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Roads, transit, and boundaries move halfway or a little more towards the ground colour, labels and
|
|
41
|
-
icons keep 60 % of their opacity, and the change eases in over 560 milliseconds. Calling
|
|
42
|
-
`setEmphasis(undefined)` eases the map back to its design. Each call supersedes the previous one;
|
|
43
|
-
the promise of a superseded call resolves with `status: 'superseded'`.
|
|
44
|
-
|
|
45
|
-
## Choose what steps back
|
|
46
|
-
|
|
47
|
-
- `recede` maps module names to an amount from 0 (as designed) to 1 (the ground colour itself). The
|
|
48
|
-
modules are the semantic domains a map compiles, such as `roads`, `transit`, `boundaries`,
|
|
49
|
-
`water`, `land`, `buildings`, and `vegetation`. Every colour of a receding layer moves towards the
|
|
50
|
-
ground colour, including the colours inside zoom curves and data cases. Artwork that cannot be
|
|
51
|
-
recoloured, such as a pattern, fades by the same amount instead.
|
|
52
|
-
- `labels` is the share of their opacity that the map's labels and icons keep, from 0 to 1.
|
|
53
|
-
- `keep` is a GeoJSON `Polygon` or `MultiPolygon`. Labels and icons whose features fall inside it
|
|
54
|
-
keep their full strength. It can hold up to 4,096 positions. A corridor round a route is a
|
|
55
|
-
typical keep area.
|
|
56
|
-
|
|
57
|
-
The ground colour is the map's background colour. During a blend it is the blended background, so
|
|
58
|
-
receding colours follow the hour as the blend moves.
|
|
59
|
-
|
|
60
|
-
## How it changes over time
|
|
61
|
-
|
|
62
|
-
Values that depend only on the camera, such as a colour or an opacity with a zoom curve, ease every
|
|
63
|
-
frame. A value that MapLibre evaluates per feature, such as a road colour chosen by class or any
|
|
64
|
-
label opacity once a keep area is given, would make MapLibre lay its source out again on every
|
|
65
|
-
change. Such values change once, at the start of the change, under a snapshot of the map that fades
|
|
66
|
-
out as the transition runs. When the browser asks for reduced motion, every change happens at once.
|
|
67
|
-
|
|
68
|
-
An emphasis stays through `setTheme` and `setBlend`: after a new style is applied, the emphasis is
|
|
69
|
-
written again under the same cross-fade, and each blend position recomputes the receded colours.
|
|
70
|
-
|
|
71
|
-
## How it finds modules
|
|
72
|
-
|
|
73
|
-
Every compiled layer names its semantic module in its metadata:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{"id": "tileflow-road-major-fill", "metadata": {"tileflow:domain": "roads"}}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Layers that a theme blend splits or copies keep the same entry. Applications can read the key from
|
|
80
|
-
`tileflowLayerDomainMetadataKey` in `@tileflow/core/browser`. Physical layer IDs remain diagnostic;
|
|
81
|
-
use the module name instead. Styles compiled before this metadata existed have no module names, so
|
|
82
|
-
an emphasis leaves them unchanged.
|
|
83
|
-
|
|
84
|
-
## Cost
|
|
85
|
-
|
|
86
|
-
Each eased frame writes only the values that changed, with `setPaintProperty` and without
|
|
87
|
-
validation. For a detailed city map with roads, transit, and boundaries receding, that is about 150
|
|
88
|
-
values a frame on a desktop computer. Writing values directly is faster than reading a MapLibre
|
|
89
|
-
global state from every value, because a global state change re-evaluates every layer that reads it.
|