@tileflow/core 0.1.0-alpha.33 → 0.1.0-alpha.34

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.
@@ -444,6 +444,24 @@ type TileflowRoadRoundaboutStyle = {
444
444
  casing?: TileflowCircleStyle;
445
445
  fill?: TileflowCircleStyle;
446
446
  };
447
+ /**
448
+ * How Core's street lights renderer lights the map's streets at night, from the lamps and lit
449
+ * streets its data holds.
450
+ */
451
+ type TileflowRoadStreetLightStyle = {
452
+ /** The light of lamps whose data gives no colour; a warm white by default. */
453
+ color?: TileflowThemeColorValue;
454
+ /** Whether the map has street lights; defaults to true where the data binds street furniture. */
455
+ enabled?: boolean;
456
+ /**
457
+ * Where light is estimated where the data maps no lamps: `lit` (the default) along streets and
458
+ * pavements mapped as lit; `streets` also along streets the data says nothing about, in tiles
459
+ * that map few lamps, which invents light; `none` nowhere.
460
+ */
461
+ estimate?: 'lit' | 'streets' | 'none';
462
+ /** How bright the lights shine, from 0 to 2; defaults to 1. */
463
+ intensity?: TileflowThemeNumberValue;
464
+ };
447
465
  type TileflowRoadSidewalkStyle = {
448
466
  outline?: TileflowLineStyle;
449
467
  pattern?: TileflowFillStyle;
@@ -465,6 +483,7 @@ type TileflowRoadsModuleConfig = {
465
483
  roundabouts?: TileflowRoadRoundaboutStyle;
466
484
  serviceTypes?: Partial<Record<TileflowRoadServiceType, TileflowRoadTreatmentStyle>>;
467
485
  sidewalks?: TileflowRoadSidewalkStyle;
486
+ streetLights?: TileflowRoadStreetLightStyle;
468
487
  structures?: Partial<Record<TileflowRoadStructure, TileflowRoadLayerStyle>>;
469
488
  weight?: TileflowRoadWeight;
470
489
  widthScale?: Partial<Record<TileflowRoadClass, TileflowThemeNumberValue>>;
@@ -804,4 +823,4 @@ type TileflowRuntimeManifest = {
804
823
  version: typeof tileflowRuntimeManifestVersion;
805
824
  };
806
825
 
807
- export { type TileflowManifestFetchOptions as $, type TileflowAreaStyle as A, type TileflowBackgroundPaint as B, type TileflowCirclePaint as C, type TileflowColor as D, type TileflowColorStyleValue as E, type TileflowExtrusionPaint as F, type TileflowFillPaint as G, type TileflowIconAnchor as H, type TileflowIconLayout as I, type TileflowIconPaint as J, type TileflowIconStyle as K, type TileflowIconTextFit as L, type MapLibreStyle as M, type TileflowImageStyleValue as N, type TileflowLabelDetail as O, type TileflowLabelLanguage as P, type TileflowLabelStyles as Q, type TileflowLayerRange as R, type TileflowLight as S, type TileflowRuntimeManifest as T, type TileflowLineCap as U, type ValidationMessage as V, type TileflowLineHatchStyle as W, type TileflowLineJoin as X, type TileflowLineLayout as Y, type TileflowLinePaint as Z, type TileflowLineStackStyle as _, type TileflowRuntimeColorScheme as a, type TileflowTextAnchor as a$, type TileflowManifestLoadOptions as a0, type TileflowMapMode as a1, type TileflowMapModeOptions as a2, type TileflowMarkerSymbolStyle as a3, type TileflowMountainBikeScale as a4, type TileflowNumberInsetsStyleValue as a5, type TileflowNumberStyleValue as a6, type TileflowPlaceLabelClass as a7, type TileflowPoiCategory as a8, type TileflowPoiCategoryStyle as a9, type TileflowRoadWeight as aA, type TileflowRuntimeCenterLike as aB, type TileflowRuntimeManifestMap as aC, type TileflowRuntimeSource as aD, type TileflowRuntimeSourceValidation as aE, type TileflowRuntimeStyle as aF, type TileflowRuntimeStyleOptions as aG, type TileflowRuntimeViewOptions as aH, type TileflowSessionController as aI, type TileflowSessionGrantResponse as aJ, type TileflowStringStyleValue as aK, type TileflowStructuralStyleValue as aL, type TileflowStyleFontFace as aM, type TileflowStyleValue as aN, type TileflowSymbolOverlap as aO, type TileflowSymbolPlacement as aP, type TileflowSymbolPlacementStyle as aQ, type TileflowSymbolZOrder as aR, type TileflowTerrain as aS, type TileflowTerrainConfig as aT, type TileflowTerrainContourLabelStyle as aU, type TileflowTerrainContourLineStyle as aV, type TileflowTerrainContoursConfig as aW, type TileflowTerrainEncoding as aX, type TileflowTerrainHillshadeStyle as aY, type TileflowTerrainLayerRange as aZ, type TileflowTerrainMode as a_, type TileflowPoiColorMode as aa, type TileflowPoiDensity as ab, type TileflowPriorityOrder as ac, type TileflowProjection as ad, type TileflowResolvedRuntimeTheme as ae, type TileflowRoadAreaStyle as af, type TileflowRoadClass as ag, type TileflowRoadClassStyle as ah, type TileflowRoadCrossingStyle as ai, type TileflowRoadDetail as aj, type TileflowRoadExtras as ak, type TileflowRoadHierarchy as al, type TileflowRoadLabelDetail as am, type TileflowRoadLayerStyle as an, type TileflowRoadModifier as ao, type TileflowRoadOutline as ap, type TileflowRoadRestriction as aq, type TileflowRoadRoundaboutStyle as ar, type TileflowRoadServiceType as as, type TileflowRoadShieldDetail as at, type TileflowRoadShieldStyles as au, type TileflowRoadSidewalkStyle as av, type TileflowRoadStructure as aw, type TileflowRoadTreatmentLayerStyle as ax, type TileflowRoadTreatmentLineStyle as ay, type TileflowRoadTreatmentStyle as az, type TileflowRuntimeManifestMapEntry as b, type TileflowTextBackground as b0, type TileflowTextJustify as b1, type TileflowTextLayout as b2, type TileflowTextPaint as b3, type TileflowTextStyle as b4, type TileflowThemeBlendSelection as b5, type TileflowThemeColorAlpha as b6, type TileflowThemeColorMix as b7, type TileflowThemeColorValue as b8, type TileflowThemeFontValue as b9, normalizeTileflowUrl as bA, resolveTileflowAnalyticsRequestUrl as bB, resolveTileflowManifestMap as bC, resolveTileflowMapMode as bD, resolveTileflowRuntimeStyle as bE, resolveTileflowRuntimeTheme as bF, resolveTileflowRuntimeThemeBlend as bG, resolveTileflowRuntimeView as bH, resolveTileflowStaticImageUrl as bI, shouldLoadTileflowManifest as bJ, startTileflowSession as bK, tileflowPoiCategories as bL, tileflowStyleFontFaceLimits as bM, tileflowStyleFontFacesMetadataKey as bN, tileflowThemeBlendLimits as bO, tileflowThemeTokenCategories as bP, token as bQ, validateTileflowRuntimeSource as bR, validateTileflowThemeBlendSelection as bS, validateTileflowThemeSelection as bT, zoom as bU, type TileflowTypographyStyle as bV, type ResolvedTileflowTypography as bW, normalizeTileflowSurfaceId as bX, type TileflowThemeImageValue as ba, type TileflowThemeNumberValue as bb, type TileflowThemeSelection as bc, type TileflowThemeTokenCategory as bd, type TileflowThemeValue as be, type TileflowViewConfig as bf, type TileflowWaterLabelClass as bg, type TileflowZoomInterpolation as bh, type TileflowZoomValue as bi, type ValidationResult as bj, assertValidTileflowRuntimeSource as bk, clearTileflowManifestCache as bl, color as bm, createTileflowSessionController as bn, createTileflowSessionId as bo, defaultTileflowManifestUrl as bp, defaultTileflowRuntimeView as bq, fixed as br, getTileflowAnalyticsApiUrl as bs, getTileflowStyleFontFaces as bt, inferTileflowAnalyticsFromStyleUrl as bu, loadTileflowManifest as bv, mergeTileflowAnalytics as bw, nearestTileflowBlendTheme as bx, normalizeTileflowRuntimeCenter as by, normalizeTileflowStaticImageSize as bz, type TileflowRuntimeManifestTheme as c, type TileflowRuntimeSystemThemes as d, tileflowRuntimeManifestVersion as e, type TileflowExpression as f, type TileflowFixedValue as g, type TileflowThemeTokenReference as h, type TileflowThemeColorOperation as i, type TileflowBackgroundStyle as j, type TileflowCircleStyle as k, type TileflowExtrusionStyle as l, type TileflowFillStyle as m, type TileflowLineStyle as n, type TileflowSymbolStyle as o, type TileflowRoadsModuleOptions as p, type TileflowRoadsModuleConfig as q, type TileflowLabelsModuleOptions as r, type TileflowLabelsModuleConfig as s, tileflowRuntimeManifestLimits as t, type TileflowPoiModuleOptions as u, type TileflowPoiModuleConfig as v, type MapLibreSprite as w, type TileflowAerodromeCodeDetail as x, type TileflowAlignment as y, type TileflowAnalytics as z };
826
+ export { type TileflowManifestFetchOptions as $, type TileflowAreaStyle as A, type TileflowBackgroundPaint as B, type TileflowCirclePaint as C, type TileflowColor as D, type TileflowColorStyleValue as E, type TileflowExtrusionPaint as F, type TileflowFillPaint as G, type TileflowIconAnchor as H, type TileflowIconLayout as I, type TileflowIconPaint as J, type TileflowIconStyle as K, type TileflowIconTextFit as L, type MapLibreStyle as M, type TileflowImageStyleValue as N, type TileflowLabelDetail as O, type TileflowLabelLanguage as P, type TileflowLabelStyles as Q, type TileflowLayerRange as R, type TileflowLight as S, type TileflowRuntimeManifest as T, type TileflowLineCap as U, type ValidationMessage as V, type TileflowLineHatchStyle as W, type TileflowLineJoin as X, type TileflowLineLayout as Y, type TileflowLinePaint as Z, type TileflowLineStackStyle as _, type TileflowRuntimeColorScheme as a, type TileflowTerrainMode as a$, type TileflowManifestLoadOptions as a0, type TileflowMapMode as a1, type TileflowMapModeOptions as a2, type TileflowMarkerSymbolStyle as a3, type TileflowMountainBikeScale as a4, type TileflowNumberInsetsStyleValue as a5, type TileflowNumberStyleValue as a6, type TileflowPlaceLabelClass as a7, type TileflowPoiCategory as a8, type TileflowPoiCategoryStyle as a9, type TileflowRoadTreatmentStyle as aA, type TileflowRoadWeight as aB, type TileflowRuntimeCenterLike as aC, type TileflowRuntimeManifestMap as aD, type TileflowRuntimeSource as aE, type TileflowRuntimeSourceValidation as aF, type TileflowRuntimeStyle as aG, type TileflowRuntimeStyleOptions as aH, type TileflowRuntimeViewOptions as aI, type TileflowSessionController as aJ, type TileflowSessionGrantResponse as aK, type TileflowStringStyleValue as aL, type TileflowStructuralStyleValue as aM, type TileflowStyleFontFace as aN, type TileflowStyleValue as aO, type TileflowSymbolOverlap as aP, type TileflowSymbolPlacement as aQ, type TileflowSymbolPlacementStyle as aR, type TileflowSymbolZOrder as aS, type TileflowTerrain as aT, type TileflowTerrainConfig as aU, type TileflowTerrainContourLabelStyle as aV, type TileflowTerrainContourLineStyle as aW, type TileflowTerrainContoursConfig as aX, type TileflowTerrainEncoding as aY, type TileflowTerrainHillshadeStyle as aZ, type TileflowTerrainLayerRange as a_, type TileflowPoiColorMode as aa, type TileflowPoiDensity as ab, type TileflowPriorityOrder as ac, type TileflowProjection as ad, type TileflowResolvedRuntimeTheme as ae, type TileflowRoadAreaStyle as af, type TileflowRoadClass as ag, type TileflowRoadClassStyle as ah, type TileflowRoadCrossingStyle as ai, type TileflowRoadDetail as aj, type TileflowRoadExtras as ak, type TileflowRoadHierarchy as al, type TileflowRoadLabelDetail as am, type TileflowRoadLayerStyle as an, type TileflowRoadModifier as ao, type TileflowRoadOutline as ap, type TileflowRoadRestriction as aq, type TileflowRoadRoundaboutStyle as ar, type TileflowRoadServiceType as as, type TileflowRoadShieldDetail as at, type TileflowRoadShieldStyles as au, type TileflowRoadSidewalkStyle as av, type TileflowRoadStreetLightStyle as aw, type TileflowRoadStructure as ax, type TileflowRoadTreatmentLayerStyle as ay, type TileflowRoadTreatmentLineStyle as az, type TileflowRuntimeManifestMapEntry as b, type TileflowTextAnchor as b0, type TileflowTextBackground as b1, type TileflowTextJustify as b2, type TileflowTextLayout as b3, type TileflowTextPaint as b4, type TileflowTextStyle as b5, type TileflowThemeBlendSelection as b6, type TileflowThemeColorAlpha as b7, type TileflowThemeColorMix as b8, type TileflowThemeColorValue as b9, normalizeTileflowStaticImageSize as bA, normalizeTileflowUrl as bB, resolveTileflowAnalyticsRequestUrl as bC, resolveTileflowManifestMap as bD, resolveTileflowMapMode as bE, resolveTileflowRuntimeStyle as bF, resolveTileflowRuntimeTheme as bG, resolveTileflowRuntimeThemeBlend as bH, resolveTileflowRuntimeView as bI, resolveTileflowStaticImageUrl as bJ, shouldLoadTileflowManifest as bK, startTileflowSession as bL, tileflowPoiCategories as bM, tileflowStyleFontFaceLimits as bN, tileflowStyleFontFacesMetadataKey as bO, tileflowThemeBlendLimits as bP, tileflowThemeTokenCategories as bQ, token as bR, validateTileflowRuntimeSource as bS, validateTileflowThemeBlendSelection as bT, validateTileflowThemeSelection as bU, zoom as bV, type TileflowTypographyStyle as bW, type ResolvedTileflowTypography as bX, normalizeTileflowSurfaceId as bY, type TileflowThemeFontValue as ba, type TileflowThemeImageValue as bb, type TileflowThemeNumberValue as bc, type TileflowThemeSelection as bd, type TileflowThemeTokenCategory as be, type TileflowThemeValue as bf, type TileflowViewConfig as bg, type TileflowWaterLabelClass as bh, type TileflowZoomInterpolation as bi, type TileflowZoomValue as bj, type ValidationResult as bk, assertValidTileflowRuntimeSource as bl, clearTileflowManifestCache as bm, color as bn, createTileflowSessionController as bo, createTileflowSessionId as bp, defaultTileflowManifestUrl as bq, defaultTileflowRuntimeView as br, fixed as bs, getTileflowAnalyticsApiUrl as bt, getTileflowStyleFontFaces as bu, inferTileflowAnalyticsFromStyleUrl as bv, loadTileflowManifest as bw, mergeTileflowAnalytics as bx, nearestTileflowBlendTheme as by, normalizeTileflowRuntimeCenter as bz, type TileflowRuntimeManifestTheme as c, type TileflowRuntimeSystemThemes as d, tileflowRuntimeManifestVersion as e, type TileflowExpression as f, type TileflowFixedValue as g, type TileflowThemeTokenReference as h, type TileflowThemeColorOperation as i, type TileflowBackgroundStyle as j, type TileflowCircleStyle as k, type TileflowExtrusionStyle as l, type TileflowFillStyle as m, type TileflowLineStyle as n, type TileflowSymbolStyle as o, type TileflowRoadsModuleOptions as p, type TileflowRoadsModuleConfig as q, type TileflowLabelsModuleOptions as r, type TileflowLabelsModuleConfig as s, tileflowRuntimeManifestLimits as t, type TileflowPoiModuleOptions as u, type TileflowPoiModuleConfig as v, type MapLibreSprite as w, type TileflowAerodromeCodeDetail as x, type TileflowAlignment as y, type TileflowAnalytics as z };
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { T as TileflowRuntimeManifest } from './manifest-types-E7m23eXL.js';
3
- export { a as TileflowRuntimeColorScheme, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, d as TileflowRuntimeSystemThemes, t as tileflowRuntimeManifestLimits, e as tileflowRuntimeManifestVersion } from './manifest-types-E7m23eXL.js';
2
+ import { T as TileflowRuntimeManifest } from './manifest-types-hmzy2bBX.js';
3
+ export { a as TileflowRuntimeColorScheme, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, d as TileflowRuntimeSystemThemes, t as tileflowRuntimeManifestLimits, e as tileflowRuntimeManifestVersion } from './manifest-types-hmzy2bBX.js';
4
4
 
5
5
  declare const tileflowRuntimeManifestSchema: z.ZodType<TileflowRuntimeManifest>;
6
6
  declare function parseTileflowRuntimeManifest(input: unknown): TileflowRuntimeManifest;
package/dist/runtime.d.ts CHANGED
@@ -1 +1 @@
1
- export { z as TileflowAnalytics, $ as TileflowManifestFetchOptions, a0 as TileflowManifestLoadOptions, a1 as TileflowMapMode, a2 as TileflowMapModeOptions, ae as TileflowResolvedRuntimeTheme, aB as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aC as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aD as TileflowRuntimeSource, aE as TileflowRuntimeSourceValidation, aF as TileflowRuntimeStyle, aG as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aH as TileflowRuntimeViewOptions, aI as TileflowSessionController, aJ as TileflowSessionGrantResponse, aM as TileflowStyleFontFace, b5 as TileflowThemeBlendSelection, bc as TileflowThemeSelection, bk as assertValidTileflowRuntimeSource, bl as clearTileflowManifestCache, bn as createTileflowSessionController, bo as createTileflowSessionId, bp as defaultTileflowManifestUrl, bq as defaultTileflowRuntimeView, bs as getTileflowAnalyticsApiUrl, bt as getTileflowStyleFontFaces, bu as inferTileflowAnalyticsFromStyleUrl, bv as loadTileflowManifest, bw as mergeTileflowAnalytics, bx as nearestTileflowBlendTheme, by as normalizeTileflowRuntimeCenter, bz as normalizeTileflowStaticImageSize, bX as normalizeTileflowSurfaceId, bA as normalizeTileflowUrl, bB as resolveTileflowAnalyticsRequestUrl, bC as resolveTileflowManifestMap, bD as resolveTileflowMapMode, bE as resolveTileflowRuntimeStyle, bF as resolveTileflowRuntimeTheme, bG as resolveTileflowRuntimeThemeBlend, bH as resolveTileflowRuntimeView, bI as resolveTileflowStaticImageUrl, bJ as shouldLoadTileflowManifest, bK as startTileflowSession, bM as tileflowStyleFontFaceLimits, bN as tileflowStyleFontFacesMetadataKey, bO as tileflowThemeBlendLimits, bR as validateTileflowRuntimeSource, bS as validateTileflowThemeBlendSelection, bT as validateTileflowThemeSelection } from './manifest-types-E7m23eXL.js';
1
+ export { z as TileflowAnalytics, $ as TileflowManifestFetchOptions, a0 as TileflowManifestLoadOptions, a1 as TileflowMapMode, a2 as TileflowMapModeOptions, ae as TileflowResolvedRuntimeTheme, aC as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aD as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aE as TileflowRuntimeSource, aF as TileflowRuntimeSourceValidation, aG as TileflowRuntimeStyle, aH as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aI as TileflowRuntimeViewOptions, aJ as TileflowSessionController, aK as TileflowSessionGrantResponse, aN as TileflowStyleFontFace, b6 as TileflowThemeBlendSelection, bd as TileflowThemeSelection, bl as assertValidTileflowRuntimeSource, bm as clearTileflowManifestCache, bo as createTileflowSessionController, bp as createTileflowSessionId, bq as defaultTileflowManifestUrl, br as defaultTileflowRuntimeView, bt as getTileflowAnalyticsApiUrl, bu as getTileflowStyleFontFaces, bv as inferTileflowAnalyticsFromStyleUrl, bw as loadTileflowManifest, bx as mergeTileflowAnalytics, by as nearestTileflowBlendTheme, bz as normalizeTileflowRuntimeCenter, bA as normalizeTileflowStaticImageSize, bY as normalizeTileflowSurfaceId, bB as normalizeTileflowUrl, bC as resolveTileflowAnalyticsRequestUrl, bD as resolveTileflowManifestMap, bE as resolveTileflowMapMode, bF as resolveTileflowRuntimeStyle, bG as resolveTileflowRuntimeTheme, bH as resolveTileflowRuntimeThemeBlend, bI as resolveTileflowRuntimeView, bJ as resolveTileflowStaticImageUrl, bK as shouldLoadTileflowManifest, bL as startTileflowSession, bN as tileflowStyleFontFaceLimits, bO as tileflowStyleFontFacesMetadataKey, bP as tileflowThemeBlendLimits, bS as validateTileflowRuntimeSource, bT as validateTileflowThemeBlendSelection, bU as validateTileflowThemeSelection } from './manifest-types-hmzy2bBX.js';
@@ -74,6 +74,9 @@ state on the map.
74
74
  - **Requests.** `transformRequest` rewrites each request as a MapLibre map's option does. Pass the
75
75
  map's own so tile reads follow the same rules. The browser's HTTP cache applies as for any
76
76
  request.
77
+ - **Archives.** A source served from a Tileflow PMTiles archive (a `tileflow-pmtiles://` address)
78
+ is read through Core's PMTiles protocol, sharing the archives the page's map has opened. A
79
+ `fetch` of your own replaces both.
77
80
 
78
81
  The reader has no DOM dependency, so it also runs in a module worker: post the tile address and
79
82
  zooms to the worker and create the reader there. `decodeTileflowVectorTile(bytes, {layers})`
@@ -89,7 +89,8 @@ TypeScript imports.
89
89
 
90
90
  `icons` is an intentional exception to implicit array composition: omission inherits the exact
91
91
  parent array, any declaration replaces it atomically, and `[]` disables map icons. Compose with a
92
- spread when the child should keep a parent's directories. `fonts` and `glyphs` are mutually
92
+ spread when the child should keep a parent's directories. `models`, the directories of a map's own
93
+ 3D models, follows the same rule. `fonts` and `glyphs` are mutually
93
94
  exclusive text providers; declaring either atomically replaces an inherited provider of either
94
95
  kind. Unknown keys and former compatibility shapes are rejected.
95
96
 
@@ -42,7 +42,59 @@ The renderer reads the source's z15 tiles round the camera (z15 is where World's
42
42
  their heights; a source that stops earlier is read at its own maximum zoom), up to `maxTiles`
43
43
  tiles (25 by default), and meshes them a few milliseconds per frame. It reads World's
44
44
  `render_height`, `render_min_height`, `hide_3d`, `building_tone` and `night_use`, and the places in
45
- World's `poi` layer (see [night light](#night-light)).
45
+ World's `poi` layer (see [night light](#night-light)). `stats.declared` tells whether the map's
46
+ style describes its 3D buildings; a style compiled before this description gets the defaults below.
47
+
48
+ ## Design the buildings in the map
49
+
50
+ The map describes how its 3D buildings look, in its buildings module, and publishes it with its
51
+ style for every theme; the renderer follows theme changes and blends. The design is visible in
52
+ `tileflow preview` and validated with the rest of the map:
53
+
54
+ <!-- docs:check -->
55
+
56
+ ```ts
57
+ import {defineMap, expr, field, refine, refineRenderTarget} from '@tileflow/core';
58
+ import {streets} from '@tileflow/maps';
59
+
60
+ const floors = expr.divide(expr.toNumber(expr.get(field('renderHeight')), 0), 3.2);
61
+
62
+ export default defineMap({
63
+ id: 'lit-city',
64
+ name: 'Lit city',
65
+ version: 1,
66
+ extends: streets,
67
+ modules: {
68
+ buildings: refine({
69
+ threeDimensional: {windows: true, nightLight: 0.6, edgeColor: '#2b2a33'},
70
+ renderStack: {
71
+ // Core's 3D buildings take the colour of the map's 3D building pass.
72
+ tints: refineRenderTarget({
73
+ target: 'buildings.render.extrusion',
74
+ renderer: 'extrusion',
75
+ style: {
76
+ color: expr.step(expr.modulo(floors, 3), '#e8d9c4', [
77
+ [1, '#d6e2d8'],
78
+ [2, '#e5d4e6'],
79
+ ]),
80
+ },
81
+ }),
82
+ },
83
+ }),
84
+ },
85
+ });
86
+ ```
87
+
88
+ - Colour: each building takes the colour the map gives its 3D buildings: Streets' 3D building pass
89
+ (the theme's `buildings.extrusion`), else the buildings module's extrusion, else its roofs. A
90
+ colour that depends on the building's data is evaluated per building and theme when a tile or the
91
+ set of themes changes, and the themes either side of a blend's position mix on the GPU, so a
92
+ moving blend costs nothing per frame.
93
+ - `threeDimensional.shadows` and `occlusion` (the band at the foot of the walls and the darker tight
94
+ corners) default to true. `windows: true` adds invented night windows, lit by rooms; they are
95
+ decoration, not data, and are off by default.
96
+ - `threeDimensional.edges` and `edgeColor` set the [edges](#edges), and `nightLight` the
97
+ [night light](#night-light). Numbers and colours may be theme tokens.
46
98
 
47
99
  ## Light and shadows
48
100
 
@@ -59,11 +111,9 @@ any wall, so roofs and walls read apart under the moon.
59
111
  MapLibre's own layers take no shadows, so the renderer darkens the map it is drawn over: after its
60
112
  buildings, it multiplies the ground by the shadows and by a band at the foot of the walls. Labels
61
113
  and icons drawn above it keep their colours. Layers kept under 3D content with
62
- `createTileflowGroundLayers` are darkened with the ground.
63
-
64
- `shadows` and `occlusion` (the band at the foot of the walls and the darker tight corners) default
65
- to true and can be turned off. `windows: true` adds invented night windows, lit by rooms; they are
66
- decoration, not data, and are off by default.
114
+ `createTileflowGroundLayers` are darkened with the ground. Other Core 3D layers on the map, such as
115
+ [3D trees](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/trees-3d.md), share
116
+ the buildings' shadows.
67
117
 
68
118
  ## Edges
69
119
 
@@ -73,30 +123,9 @@ each building is a little lighter or darker than its colour (up to 6%), so neigh
73
123
  stay apart. The lines are strongest at night; diagonals inside a roof, inner corners and the cuts at
74
124
  a tile's edge draw none. `edges` sets their strength from 0 (none) to 1, the default.
75
125
 
76
- `edgeColor` gives the lines a colour of the application's own, as a CSS colour or per theme: a dark
77
- outline as on a printed map, or a neon one at night. It is drawn as it is, unlit, at the full
78
- `edges` strength by day and night. The renderer asks for each theme's colour once and mixes the
79
- colours of the themes either side of a blend's position; a theme without a valid colour keeps the
80
- default.
81
-
82
- <!-- docs:check -->
83
-
84
- ```ts
85
- import {
86
- createTileflowBuildings3D,
87
- type TileflowBuildings3DMap,
88
- type TileflowThemeController,
89
- } from '@tileflow/core/browser';
90
-
91
- export function neonEdges(map: TileflowBuildings3DMap, controller: TileflowThemeController) {
92
- return createTileflowBuildings3D({
93
- map,
94
- controller,
95
- // Cyan outlines at night, a dark ink by day.
96
- edgeColor: (theme) => (theme === 'night' ? '#7fd8ff' : '#2b2a33'),
97
- });
98
- }
99
- ```
126
+ `edgeColor` gives the lines a colour of the map's own, per theme through a token: a dark outline as
127
+ on a printed map, or a neon one at night. It is drawn as it is, unlit, at the full `edges` strength
128
+ by day and night, mixed between the themes either side of a blend's position.
100
129
 
101
130
  ## Night light
102
131
 
@@ -112,8 +141,8 @@ default:
112
141
  dark.
113
142
 
114
143
  The night use comes from World's `night_use` on each building. In tiles whose buildings do not
115
- carry it, the renderer finds it in the tile's places (`placesLayer`, `poi` by default): a place
116
- inside a building, or within a few metres of its facade, gives the building its use.
144
+ carry it, the renderer finds it in the tile's places: a place inside a building, or within a few
145
+ metres of its facade, gives the building its use.
117
146
 
118
147
  `nightLight` sets how bright all of this shines, from 0 (none) to 2; it defaults to 1.
119
148
 
@@ -122,37 +151,11 @@ For the streets themselves, see
122
151
  which draws over the buildings so they hide the lamps behind them; both layers share each tile's
123
152
  download.
124
153
 
125
- ## Colours
154
+ ## Options
126
155
 
127
- Without `color`, buildings take the theme's 3D building colour, the colour Tileflow's buildings
128
- module compiles for its extrusion, and follow theme changes and blends.
129
-
130
- `color(properties, theme)` colours each building from its feature properties for each theme, as a
131
- CSS colour. The renderer calls it once per building and theme when a tile or the set of themes
132
- changes, and mixes the colours of the themes either side of a blend's position on the GPU, so a
133
- moving blend costs nothing per frame:
134
-
135
- <!-- docs:check -->
136
-
137
- ```ts
138
- import {createTileflowBuildings3D, type TileflowBuildings3DMap} from '@tileflow/core/browser';
139
-
140
- const tints: Record<string, readonly string[]> = {
141
- day: ['#f1d4cd', '#d3e8da', '#f6e0b5', '#e2d5f0', '#cfe3f2'],
142
- night: ['#353d41', '#2f3a3d', '#3a3b44', '#33363f', '#2d3540'],
143
- };
144
-
145
- export function tintedCity(map: TileflowBuildings3DMap) {
146
- return createTileflowBuildings3D({
147
- map,
148
- color(properties, theme) {
149
- const floors = Math.floor(Number(properties.render_height ?? 5) / 3.2);
150
- const palette = tints[theme] ?? tints.day!;
151
- return palette[floors % palette.length]!;
152
- },
153
- });
154
- }
155
- ```
156
+ The renderer's own options say only how it is delivered: `minzoom` (14.5 by default), `maxTiles`,
157
+ `beforeId` to place the layer before another one, and `transformRequest` to apply the map's request
158
+ rules to the tiles it reads.
156
159
 
157
160
  ## Cost
158
161
 
@@ -166,3 +169,4 @@ way kept the frame pacing of the same city drawn without shadows.
166
169
  - No terrain: buildings stand on flat ground.
167
170
  - One building colour per feature and theme; facades, roof shapes and building parts as separate
168
171
  shapes are not drawn.
172
+ - A colour expression is evaluated at zoom 16.
@@ -45,13 +45,37 @@ detail:
45
45
  - Lamps from World's `street_furniture` points whose `subclass` is `street_lamp`. Where the data
46
46
  gives them, a lamp's `height`, `lamp_mount`, `light_count`, `lamp_type` and `light_colour` set how
47
47
  high it stands, how far its light reaches and its colour: sodium lamps shine orange, LED and
48
- metal-halide lamps white. Other lamps take `color`, a warm white by default.
48
+ metal-halide lamps white. Other lamps take the map's light colour.
49
49
  - Streets in World's `transportation` layer, and pavements in its `sidewalk` layer, that the data
50
50
  maps as lit (`lit`). A street mapped as unlit never takes light.
51
51
 
52
52
  How much of this a city's data holds varies widely: some map most of their lamps or most of their
53
53
  lit streets, others almost none. Where the data says nothing, the streets stay dark.
54
54
 
55
+ ## Design the lights in the map
56
+
57
+ The map describes its street lights in its roads module, next to the other details drawn from
58
+ street furniture, and publishes them with its style for every theme; `stats.declared` tells whether
59
+ it does. Without a description the lights take the defaults below:
60
+
61
+ <!-- docs:check -->
62
+
63
+ ```ts
64
+ import {defineMap, refine} from '@tileflow/core';
65
+ import {streets} from '@tileflow/maps';
66
+
67
+ export default defineMap({
68
+ id: 'night-city',
69
+ name: 'Night city',
70
+ version: 1,
71
+ extends: streets,
72
+ modules: {
73
+ // Sodium-orange light, a little brighter, on every street of tiles that map few lamps.
74
+ roads: refine({streetLights: {color: '#ffb35c', intensity: 1.3, estimate: 'streets'}}),
75
+ },
76
+ });
77
+ ```
78
+
55
79
  `estimate` chooses where the layer adds light the data does not map as lamps:
56
80
 
57
81
  - `lit` (the default): along the streets and pavements mapped as lit.
@@ -63,12 +87,15 @@ lit streets, others almost none. Where the data says nothing, the streets stay d
63
87
  Estimated light keeps to the middle of its street and shows no lamp head, so it reads as a lit
64
88
  street rather than as lamps that may not stand there.
65
89
 
90
+ `color` is the light of the lamps whose data gives no colour, a warm white by default, and
91
+ `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 the map none.
93
+
66
94
  ## Options
67
95
 
68
- `intensity` scales the light from 0 to 2 (1 by default). `minzoom` (14 by default) and `maxTiles`
69
- (25 by default, at most 64) bound where and how far the lights shine. `beforeId` places the layer
70
- before another one; `source` names a vector source other than `tileflow`; `transformRequest`
71
- applies the map's request rules to the tiles the layer reads.
96
+ The layer's own options say only how it is delivered: `minzoom` (14 by default) and `maxTiles` (25
97
+ by default, at most 64) bound where and how far the lights shine, `beforeId` places the layer before
98
+ another one, and `transformRequest` applies the map's request rules to the tiles it reads.
72
99
 
73
100
  Layers that read the same source share each tile's download, so the street lights and the 3D
74
101
  buildings fetch a tile once between them.
@@ -0,0 +1,211 @@
1
+ # 3D trees
2
+
3
+ `createTileflowTrees3D` stands the trees of a Tileflow map's vector tiles round the camera as 3D
4
+ trees, lit by the theme controller's sun. Each tree takes the form and the size its data gives:
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,
7
+ and take the buildings' shadows; nearer buildings hide them.
8
+
9
+ The map describes how its trees look; the renderer only stands them. A map that declares
10
+ `vegetation({mode: '3d'})`, as Streets does, publishes its tree colours, scales and forms in the
11
+ style it compiles, for every theme, and the renderer follows theme changes and blends.
12
+
13
+ It is a custom WebGL2 layer for MapLibre GL JS, drawn above the map's buildings and below its
14
+ labels. It needs WebGL2 and the Mercator projection, and the trees stand from zoom 15 by default.
15
+ Elsewhere (Capture, Static Maps, Native, or a browser without WebGL2) the map draws the vegetation
16
+ module's flat trees.
17
+
18
+ ## Stand the trees
19
+
20
+ This example assumes an existing MapLibre map showing a Tileflow map whose vector source is called
21
+ `tileflow`, as Tileflow's maps call World, and a theme controller for it:
22
+
23
+ <!-- docs:check -->
24
+
25
+ ```ts
26
+ import {
27
+ createTileflowTrees3D,
28
+ type TileflowThemeController,
29
+ type TileflowTrees3DMap,
30
+ } from '@tileflow/core/browser';
31
+
32
+ export function standTheTrees(map: TileflowTrees3DMap, controller: TileflowThemeController) {
33
+ const trees = createTileflowTrees3D({map, controller});
34
+ // The trees grow out of the ground over a second.
35
+ void trees.show({transition: {duration: 1000}});
36
+ return trees;
37
+ }
38
+ ```
39
+
40
+ `show()` grows the trees, `hide()` sinks them back into the ground, and `grow(scale)` eases them to
41
+ a share of their size, from 0 to 1. Each returns a promise that resolves once the motion ends; a
42
+ newer call takes over from where the trees stand. A browser preference for reduced motion changes at
43
+ once. `dispose()` takes the layer off the map.
44
+
45
+ While they stand, the 3D trees stand in for the map's flat trees: the layers the vegetation module
46
+ draws them with are hidden when the trees are shown, and come back as they were once the trees have
47
+ sunk or the layer leaves the map.
48
+
49
+ `stats.declared` tells whether the map's style describes 3D trees. When it is false the layer draws
50
+ nothing: declare `vegetation({mode: '3d'})` in the map. `stats` also counts the tiles, the trees
51
+ placed and the trees drawn in the last frame.
52
+
53
+ ## What the trees come from
54
+
55
+ The renderer reads the source's z15 tiles round the camera:
56
+
57
+ - World's `tree` layer: the trees OpenStreetMap maps one by one, as points, and its rows of trees,
58
+ as lines, along which a tree stands every 8 metres. A tree's `leaf_type`, `genus`, `species` and
59
+ `taxon` choose its form; its `height` and `diameter_crown` its size, and a trunk's
60
+ `circumference` sizes a tree with neither. A row's attributes apply to each of its trees.
61
+ - World's `canopy` layer, where the data has it: decorative points in urban parks and gardens, each
62
+ standing one to three trees by its canopy cover, inside the room it leaves before a path, a
63
+ building or the park's edge. They stand for measured canopy, not for mapped trees.
64
+
65
+ | Form | From the data |
66
+ | ---------- | ---------------------------------------------------------------------------- |
67
+ | `palm` | `leaf_type` `palm`, `taxon` `Arecaceae`, or a palm genus such as `Roystonea` |
68
+ | `columnar` | the cypress genera `Cupressus`, `Calocedrus` and `Thuja` |
69
+ | `conifer` | `leaf_type` `needleleaved`, or a conifer genus such as `Pinus` or `Cedrus` |
70
+ | `open` | spreading genera such as `Quercus`, `Olea`, `Ficus` or `Jacaranda` |
71
+ | `tall` | upright genera such as `Platanus`, `Populus`, `Ulmus` or `Ginkgo` |
72
+ | `round` | rounded genera such as `Acer`, `Tilia`, `Aesculus` or `Prunus` |
73
+
74
+ A tree whose data gives no form, and every canopy tree, takes one of the three broadleaf forms; a
75
+ tree the data calls broadleaved keeps to them. Each tree's form, size, turn and shade come from a
76
+ stable hash of where it stands, so it looks the same at every zoom and on every device. Points in a
77
+ tile's buffer belong to the neighbouring tile, so no tree stands twice.
78
+
79
+ ## Design the trees in the map
80
+
81
+ Colours come from the theme: `vegetation.tree.bark`, `vegetation.tree.broadleaf.a` to `.d`,
82
+ `vegetation.tree.conifer.a` to `.c` and `vegetation.tree.palm.a` to `.c`, sunlit, from darkest to
83
+ lightest. A crown facing a sunlit sky takes its colour; shade takes the sky's light, as on 3D
84
+ buildings. The vegetation module's `threeDimensional` options refine them for one map:
85
+
86
+ <!-- docs:check -->
87
+
88
+ ```ts
89
+ import {defineMap, token, vegetation} from '@tileflow/core';
90
+ import {streets} from '@tileflow/maps';
91
+
92
+ export default defineMap({
93
+ id: 'subtropical-city',
94
+ name: 'Subtropical city',
95
+ version: 1,
96
+ extends: streets,
97
+ modules: {
98
+ vegetation: vegetation({
99
+ mode: '3d',
100
+ threeDimensional: {
101
+ barkColor: token.color('vegetation.tree.bark'),
102
+ heightScale: 1.1,
103
+ finish: 'toon',
104
+ edges: 1,
105
+ // Along this coast most trees the data does not describe are palms.
106
+ regions: [{bounds: [-81.0, 24.4, -79.8, 26.9], unknownForms: {palm: 3, round: 1, open: 1}}],
107
+ },
108
+ }),
109
+ },
110
+ });
111
+ ```
112
+
113
+ `finish` sets how trees take the light: `faceted` (the default), low-poly facets softened towards a
114
+ round crown; `smooth`, round crowns; or `toon`, three bands of light and a crisp shadow, as a drawn
115
+ tree has them. `edges` rings each tree with an outline a constant width on screen, from 0 (none,
116
+ the default) to 1, in `edgeColor` or the crown's darkest colour deepened; buildings use the same
117
+ two words for their outlines.
118
+
119
+ `heightScale` and `crownScale` stretch every tree, and `forms` each form on top of them, such as
120
+ `forms: {palm: {heightScale: 1.2}}` for taller palms. `unknownForms` sets, as relative weights, the
121
+ forms of trees whose data gives none, and `regions` sets them inside `[west, south, east, north]`
122
+ bounds in degrees, the first region holding a tree applying. They are a choice of look, not data:
123
+ they never change a tree whose data gives its form, and as mapping improves they apply to fewer
124
+ trees.
125
+
126
+ ## Your own trees
127
+
128
+ A map can draw a form with its own models. Put glTF binaries (`.glb`) in a directory, declare it in
129
+ the map's `models`, and name the models a form draws by their file names:
130
+
131
+ <!-- docs:check -->
132
+
133
+ ```ts
134
+ import {defineMap, vegetation} from '@tileflow/core';
135
+ import {streets} from '@tileflow/maps';
136
+
137
+ export default defineMap({
138
+ id: 'palm-coast',
139
+ name: 'Palm coast',
140
+ version: 1,
141
+ extends: streets,
142
+ // ./models holds sabal-palm.glb and royal-palm.glb, and sabal-palm.far.glb for far trees.
143
+ models: ['./models'],
144
+ modules: {
145
+ vegetation: vegetation({
146
+ mode: '3d',
147
+ threeDimensional: {
148
+ forms: {palm: {models: ['sabal-palm', 'royal-palm'], heightScale: 1.1}},
149
+ },
150
+ }),
151
+ },
152
+ });
153
+ ```
154
+
155
+ Each tree of the form draws one of its models, one to four, by its stable hash, so a palm keeps its
156
+ model wherever it is read. The data still chooses each tree's form and size: a model replaces how a
157
+ form looks, not which trees take it.
158
+
159
+ How to prepare a model:
160
+
161
+ - **Materials name the parts.** Name each material `bark`, `leaves`, `fronds` or `stem` (an
162
+ exporter's `.001` suffix is ignored). Each part takes its theme colours, as Core's trees do; the
163
+ material's colour and any vertex colours set how light or dark each part of the model is within
164
+ them, so the model follows the theme from day to night.
165
+ - **The origin is where the trunk meets the ground**, with the tree above it. Tileflow stands the
166
+ model as a unit tree: its top is the tree's height, and its widest leaf half its crown.
167
+ - **Budgets.** A model has at most 1,000 triangles and 4,096 vertices; `<id>.far.glb`, drawn
168
+ beyond the nearest tiles, at most 120 triangles. Without a far model, the form's own far tree
169
+ stands in. A map draws at most 16 models.
170
+ - **What is read.** Triangles of the default scene with their node transforms; textures,
171
+ animations and compressed geometry (Draco or meshopt) are not. Export without compression.
172
+
173
+ `tileflow preview` and every build read the models, report a problem with the file and what to
174
+ change, and watch the directories. The models travel inside the compiled style, so they need no
175
+ files of their own when the map is deployed. A later directory's model replaces an earlier one of
176
+ the same name; omitting `models` inherits them, and `[]` declares none.
177
+
178
+ ## Light and shadows
179
+
180
+ The light comes from `controller.getSun()`: the theme's sun, mixed during a blend, or the sun an
181
+ application places by direction or by date and place (see
182
+ [sun and light](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/sun-and-light.md)).
183
+ Leaves take light round their edges and glow a little against a low sun; the underside and the
184
+ inside of a crown stay darker.
185
+
186
+ Trees and 3D buildings on one map share one shadow map: trees cast shadows on the ground and on the
187
+ buildings, and stand in the buildings' shade. The flat map darkens under both. Without 3D buildings
188
+ the trees darken the map themselves.
189
+
190
+ ## Options
191
+
192
+ `minzoom` (15 by default) and `maxTiles` (25 by default, at most 64) bound where and how far trees
193
+ stand; trees thin out and fade with distance from the map's centre, and near trees take more detail
194
+ than far ones. `canopySource` names a vector source with canopy points when they are not in the
195
+ map's World source. `beforeId` places the layer before another one; `transformRequest` applies the
196
+ map's request rules to the tiles the layer reads. Layers that read the same source share each
197
+ tile's download.
198
+
199
+ ## Cost
200
+
201
+ A near tree has 60 to 120 triangles and a far one about 20, and each form is one instanced draw per
202
+ tile. The shadow map is drawn again only when the sun, the trees on screen or their size change, not
203
+ when the camera moves. Over the Champ de Mars in Paris, where OpenStreetMap maps every tree, about
204
+ 13,000 trees stand in a pitched view at zoom 16.6.
205
+
206
+ ## Limits
207
+
208
+ - Mercator only; the layer draws nothing below its `minzoom`.
209
+ - No terrain: trees stand on flat ground.
210
+ - No wind or seasons; one form per tree.
211
+ - Models replace a form's look; a model per genus or species is not available.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/core",
3
- "version": "0.1.0-alpha.33",
3
+ "version": "0.1.0-alpha.34",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Typed Tileflow config and MapLibre style compiler.",
6
6
  "type": "module",