@tileflow/core 0.1.0-alpha.4 → 0.1.0-alpha.40

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.
Files changed (57) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +318 -26
  3. package/THIRD_PARTY_NOTICES.md +444 -0
  4. package/dist/3d-CzLTD0RK.d.ts +1092 -0
  5. package/dist/3d.d.ts +1 -0
  6. package/dist/3d.js +12514 -0
  7. package/dist/browser.d.ts +2281 -0
  8. package/dist/browser.js +21680 -0
  9. package/dist/build.d.ts +595 -0
  10. package/dist/build.js +29729 -0
  11. package/dist/capture-shot-ChPQvPyi.d.ts +291 -0
  12. package/dist/capture.d.ts +9 -0
  13. package/dist/capture.js +510 -0
  14. package/dist/config-reference.json +40600 -0
  15. package/dist/icon-composition-CcSHApUm.d.ts +2478 -0
  16. package/dist/index.d.ts +1806 -162
  17. package/dist/index.js +26319 -3476
  18. package/dist/manifest-types-DnhSJjCM.d.ts +902 -0
  19. package/dist/manifest.d.ts +9 -0
  20. package/dist/manifest.js +449 -0
  21. package/dist/native-profile.d.ts +206 -0
  22. package/dist/native-profile.js +9339 -0
  23. package/dist/native.d.ts +365 -0
  24. package/dist/native.js +5970 -0
  25. package/dist/runtime.d.ts +1 -0
  26. package/dist/runtime.js +1445 -0
  27. package/dist/worker/camera-tile-worker.global.js +20 -0
  28. package/docs/application-tile-reading.md +86 -0
  29. package/docs/authoring-model.md +269 -0
  30. package/docs/boundary-areas-and-choropleths.md +217 -0
  31. package/docs/buildings-3d.md +594 -0
  32. package/docs/camera-moves-and-tile-cache.md +112 -0
  33. package/docs/capture-scenes.md +40 -0
  34. package/docs/capture-shots.md +173 -0
  35. package/docs/cartographic-defaults.md +210 -0
  36. package/docs/compiled-style-performance.md +286 -0
  37. package/docs/data-is-separate-from-design.md +610 -0
  38. package/docs/depth-markers.md +65 -0
  39. package/docs/dynamic-style-images.md +100 -0
  40. package/docs/globe-atmosphere.md +113 -0
  41. package/docs/hosted-session-authorization.md +106 -0
  42. package/docs/map-and-terrain-examples.md +156 -0
  43. package/docs/map-emphasis.md +89 -0
  44. package/docs/native-artifact-profile.md +152 -0
  45. package/docs/native-resource-urls.md +369 -0
  46. package/docs/nautical-marks.md +308 -0
  47. package/docs/public-api-and-browser-subpath.md +101 -0
  48. package/docs/route-drawing.md +191 -0
  49. package/docs/shared-visual-primitives.md +101 -0
  50. package/docs/street-lights.md +127 -0
  51. package/docs/street-sky.md +156 -0
  52. package/docs/style-states.md +73 -0
  53. package/docs/sun-and-light.md +167 -0
  54. package/docs/theme-transitions-and-blends.md +317 -0
  55. package/docs/themes-and-module-styles.md +156 -0
  56. package/docs/trees-3d.md +295 -0
  57. package/package.json +67 -8
@@ -0,0 +1,286 @@
1
+ # Compiled-style performance
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 semantic compiler resolves semantic modules and their owned contributions first, then compacts equivalent
6
+ physical MapLibre layers. At high-detail zooms, road classes become a small set of data-driven
7
+ cohorts; equivalent road labels and tunnel hatches share compatible buckets; and land-cover,
8
+ land-use, and waterway classes share compatible buckets. Compaction selects
9
+ cohorts from compiler-owned semantic targets, not by parsing physical IDs; its temporary
10
+ owner/slot/target provenance is stripped from the public Style JSON.
11
+
12
+ After physical planning, Core embeds a bounded private `tileflow:interaction-manifest` lookup for the
13
+ final POI representations. `@tileflow/interactions/maplibre` validates and consumes that metadata
14
+ so applications can bind to `domain: 'poi'` without depending on physical layer IDs. The lookup is
15
+ paired atomically with the exact style it describes; it is not a public style-authoring API.
16
+
17
+ Use the exported structural sweep to enforce budgets without loading tiles or a browser:
18
+
19
+ ```ts
20
+ import {analyzeTileflowStylePerformance, createStyle} from '@tileflow/core';
21
+ import map from './tileflow.config';
22
+
23
+ const report = analyzeTileflowStylePerformance(createStyle(map));
24
+ console.log(report.zooms[16]);
25
+ ```
26
+
27
+ The report covers z0–z22 by default and includes active layers, conservative bucket estimates,
28
+ symbols, and active layers per source-layer. It is intended for regression gates; browser traces
29
+ remain the source of truth for decode, upload, placement, and frame time.
30
+
31
+ A `SymbolStyle` root zoom range governs its text/icon layer and is inherited by its marker layer.
32
+ Because a marker is materialized as a separate circle layer, an explicit marker range may refine
33
+ that inherited default. Text and icon ranges must agree because MapLibre renders them together.
34
+
35
+ The road module distinguishes the path family semantically:
36
+
37
+ ```ts
38
+ roads({
39
+ extras: {paths: true},
40
+ crossings: {image: token.image('roads.crosswalk')},
41
+ sidewalks: {
42
+ surface: {color: token.color('roads.city.casing'), minZoom: 17},
43
+ pattern: {
44
+ pattern: token.image('roads.sidewalkPattern'),
45
+ minZoom: 17,
46
+ opacity: fixed(0.6, {reason: 'Sidewalk texture strength is invariant'}),
47
+ },
48
+ },
49
+ roundabouts: {
50
+ casing: {strokeColor: token.color('roads.default.casing')},
51
+ fill: {strokeColor: token.color('roads.default')},
52
+ },
53
+ areas: {
54
+ pedestrian: {
55
+ fill: {color: token.color('surface.land')},
56
+ outline: {
57
+ color: token.color('roads.default.casing'),
58
+ width: fixed(1, {reason: 'Pedestrian-area outline weight is invariant'}),
59
+ },
60
+ },
61
+ },
62
+ classes: {
63
+ primary: {
64
+ tunnel: {
65
+ casing: {
66
+ color: token.color('roads.city.tunnelCasing'),
67
+ width: fixed(10, {reason: 'Primary-tunnel hierarchy is invariant'}),
68
+ },
69
+ fill: {
70
+ color: token.color('roads.city.tunnel'),
71
+ width: fixed(8, {reason: 'Primary-tunnel hierarchy is invariant'}),
72
+ },
73
+ hatch: {
74
+ color: token.color('roads.city.tunnelCasing'),
75
+ opacity: fixed(0.25, {reason: 'Tunnel hatch strength is invariant'}),
76
+ spacing: fixed(10, {reason: 'Tunnel hatch rhythm is invariant'}),
77
+ },
78
+ },
79
+ },
80
+ pedestrian: {
81
+ surface: {
82
+ fill: {
83
+ color: token.color('roads.path.transition'),
84
+ width: fixed(6, {reason: 'Pedestrian-road hierarchy is invariant'}),
85
+ },
86
+ },
87
+ },
88
+ footway: {
89
+ surface: {
90
+ fill: {
91
+ color: token.color('roads.path'),
92
+ width: fixed(1.2, {reason: 'Path hierarchy is invariant'}),
93
+ },
94
+ },
95
+ },
96
+ cycleway: {
97
+ surface: {
98
+ fill: {
99
+ color: token.color('roads.cycleway'),
100
+ width: fixed(1.5, {reason: 'Cycleway hierarchy is invariant'}),
101
+ },
102
+ },
103
+ },
104
+ steps: {
105
+ surface: {
106
+ fill: {
107
+ color: token.color('roads.path.casing'),
108
+ width: fixed(1.4, {reason: 'Step hierarchy is invariant'}),
109
+ },
110
+ },
111
+ },
112
+ pathway: {
113
+ surface: {
114
+ fill: {
115
+ color: token.color('roads.path'),
116
+ width: fixed(1.2, {reason: 'Path hierarchy is invariant'}),
117
+ },
118
+ },
119
+ },
120
+ },
121
+ modifiers: {
122
+ expressway: {widthScale: 1.06},
123
+ ramp: {widthScale: 0.7},
124
+ unpaved: {surface: {fill: {color: token.color('roads.path')}}},
125
+ construction: {
126
+ surface: {
127
+ fill: {opacity: fixed(0.7, {reason: 'Construction emphasis is invariant'})},
128
+ },
129
+ },
130
+ indoor: {
131
+ surface: {fill: {opacity: fixed(0.4, {reason: 'Indoor-road emphasis is invariant'})}},
132
+ },
133
+ },
134
+ restrictions: {
135
+ access: {
136
+ surface: {fill: {opacity: fixed(0.55, {reason: 'Restricted-road emphasis is invariant'})}},
137
+ },
138
+ toll: {
139
+ surface: {
140
+ casing: {color: fixed('#C5B7D8', {reason: 'Toll ink is regulatory and invariant'})},
141
+ },
142
+ },
143
+ },
144
+ serviceTypes: {
145
+ driveway: {widthScale: 0.75},
146
+ parkingAisle: {widthScale: 0.6},
147
+ },
148
+ });
149
+ ```
150
+
151
+ These targets are non-overlapping translations of the OpenMapTiles road class and subclass. The
152
+ same names are available under `labels().roadClasses` and `labels().styles.roads`. Surface, tunnel,
153
+ and bridge phases can be controlled independently for each target; each structure has
154
+ `shadow`/`casing`/`fill` and an optional `hatch`. Glyph hatch marks inherit the resolved fill width
155
+ when `size` is omitted and never participate in label collision. Setting `hatch.pattern` instead
156
+ emits a repeated sprite texture clipped to the resolved fill width. No raw source filter or generated
157
+ layer ID is needed. `hatch.patternWidths` can list intrinsic sprite heights named
158
+ `${pattern}-${width}`; the compiler selects the nearest height from the resolved road width so the
159
+ texture's marks remain approximately constant in screen pixels across classes, ramps, and zooms.
160
+
161
+ `classes.pedestrian` styles line-like pedestrian ways. Polygon pedestrian plazas are a distinct
162
+ geometry and use `areas.pedestrian`, including optional fill opacity, outline color, or sprite
163
+ pattern. This prevents plazas from degrading into a thin polygon outline. With a
164
+ `transportationOutline` binding, as in Tileflow World, area outlines stroke only the outer boundary
165
+ of each area, never its holes.
166
+
167
+ Road treatments refine a class without creating another class or exposing source fields.
168
+ `construction`, `expressway`, `indoor`, `official`, `ramp`, and `unpaved` live under `modifiers`;
169
+ general, bicycle, foot, horse, and toll restrictions live under `restrictions`; `alley`,
170
+ `crossover`, `driveway`, `parkingAisle`, and `yard` live under `serviceTypes`; and exact
171
+ mountain-bike difficulty values, which apply to paths and tracks, live under `mountainBike`. Treatments reuse
172
+ surface/tunnel/bridge and casing/fill/shadow paint controls, plus a relative `widthScale`. The
173
+ compiler emits feature-driven paint expressions inside the existing stable class layers rather
174
+ than multiplying every possible combination.
175
+
176
+ A solid dash, `[1, 0]`, is emitted as no `line-dasharray` at all, so MapLibre draws the line with
177
+ its solid-line shader rather than its dash shader. A treatment's dash that depends on the road
178
+ class is settled for each class layer: a dash for construction paths leaves a motorway's layers
179
+ solid. Roundabout rings state their road widths at each zoom as numbers where the widths allow,
180
+ and name the feature conditions they repeat once with `let`, which keeps their style compact and
181
+ quick to validate.
182
+
183
+ Road names, shields, and motorway junctions remain label concerns:
184
+
185
+ ```ts
186
+ labels({
187
+ roads: 'all',
188
+ shields: 'major',
189
+ junctions: true,
190
+ styles: {
191
+ shields: {
192
+ default: {
193
+ icon: {
194
+ image: token.image('roads.shield.rectangleNeutral'),
195
+ optional: false,
196
+ pitchAlignment: 'viewport',
197
+ rotationAlignment: 'viewport',
198
+ textFit: 'width',
199
+ textFitPadding: [0, 4, 0, 4],
200
+ },
201
+ text: {
202
+ color: token.color('labels.shieldDark'),
203
+ font: token.font('places'),
204
+ optional: false,
205
+ pitchAlignment: 'viewport',
206
+ rotationAlignment: 'viewport',
207
+ },
208
+ },
209
+ overview: {minZoom: 6, maxZoom: 11, placement: 'point'},
210
+ detail: {minZoom: 11, placement: 'line', spacing: 400},
211
+ kinds: {
212
+ 'rectangle-neutral': {image: token.image('roads.shield.rectangleNeutral')},
213
+ 'rectangle-blue': {image: token.image('roads.shield.rectangleBlue')},
214
+ },
215
+ textColors: {
216
+ dark: {color: token.color('labels.shieldDark')},
217
+ light: {color: token.color('labels.shieldLight')},
218
+ },
219
+ },
220
+ junctions: {
221
+ text: {
222
+ color: token.color('labels.strong'),
223
+ haloColor: token.color('labels.halo'),
224
+ haloWidth: fixed(2, {reason: 'Junction halo weight is invariant'}),
225
+ },
226
+ },
227
+ },
228
+ });
229
+ ```
230
+
231
+ `icon.textFit` and `icon.textFitPadding` let a symbol background grow with its text. Setting both
232
+ icon and text `optional: false` keeps a route shield atomic during collision placement: neither an
233
+ empty badge nor a detached reference can render alone. `overview` renders producer-selected points
234
+ at low zoom and `detail` switches to line placement at street zooms; exclusive `maxZoom: 11` and
235
+ inclusive `minZoom: 11` make that handoff atomic. Keeping both icon and text aligned to `viewport`
236
+ makes the badge horizontal regardless of road bearing.
237
+
238
+ `kinds` and `textColors` are closed presentation tables. The vector producer supplies semantic
239
+ `shield_kind`, `shield_text_color`, `shield_text`, and `shield_rank` values; Core only matches them
240
+ against the authored tables and falls back to `default`. Country, route-prefix, and network-shape
241
+ rules therefore stay in the data authority instead of leaking into a map theme or multiplying
242
+ runtime layers.
243
+
244
+ Tileflow World owns POI classification, editorial zoom eligibility, and cross-source ranking. Its
245
+ canonical `poi` layer exposes `category`, `type`, `icon`, `min_zoom`, `filter_rank`, and `size_rank`;
246
+ Core validates that complete contract and never reconstructs those decisions from OpenMapTiles
247
+ `class`, `subclass`, or `rank`. `filter_rank` is an
248
+ integer from 0 through 5, with lower values reserved for the strongest candidates. The numeric
249
+ `density` option is an inclusive threshold from 1 through 5 and defaults to 3. World publishes
250
+ every eligible POI at z15, its last POI zoom, and higher zooms overzoom those tiles with more room,
251
+ so the threshold rises by one rank at z16 and by two from z17. At the default density every rank is
252
+ eligible from z17, and collision placement keeps what fits. `size_rank` is an
253
+ integer from 0 through 16 used to order eligible candidates before MapLibre performs final
254
+ collision placement.
255
+
256
+ The closed category vocabulary is `arts-entertainment`, `education`, `food-drink`, `landmark`,
257
+ `lodging`, `medical`, `park-nature`, `public-services`, `religion`, `retail`, `sport-leisure`,
258
+ `transport`, and `visitor-amenity`. Producer `type` and `icon` values use stable snake_case names.
259
+ When an `icon` sprite exists it is used directly; an unknown or absent icon safely falls back to the
260
+ category's themed image role. `labels` and `icons` are booleans. Category styles control only
261
+ presentation and never promote candidates above the producer's selection.
262
+ `placement.coupleIconAndLabel` keeps a POI's icon and label atomic during collision placement:
263
+ both are required.
264
+
265
+ MapLibre orders symbol placement only within a layer, so the module compiles every category into
266
+ one layer per representation and orders it by `filter_rank` and `size_rank`: a station is placed
267
+ before a cash machine whatever their categories. Per-category appearance becomes a `match` on
268
+ `category`; zoom curves are hoisted above it so each category keeps its exact curve. Categories that
269
+ need different layer-wide properties use `placement.order: 'categories'`, one layer per category in
270
+ listed order. `placement.prominentRank` places the most important ranks in a second layer above road
271
+ and place labels, which keeps landmarks visible on maps whose labels give street names priority.
272
+ When icons and labels are both drawn, unnamed POIs are omitted except the self-explanatory types in
273
+ `placement.iconOnlyTypes` (parking and public toilets by default), which draw only their pictogram.
274
+
275
+ ```ts
276
+ poi({
277
+ categories: ['food-drink', 'landmark', 'transport'],
278
+ density: 3,
279
+ icons: true,
280
+ labels: true,
281
+ });
282
+ ```
283
+
284
+ The same contract drives regular POI layers, custom HUD treatments, semantic interactions, and
285
+ feature inspection. There is intentionally no compatibility path for the former class mapping,
286
+ rank ceilings, per-category densities, or named density/detail presets.