isard 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/basemap/grid.js +2 -5
- package/dist/basemap/grid.js.map +1 -1
- package/dist/basemap/models/furniture.d.ts +12 -0
- package/dist/basemap/{furniture.js → models/furniture.js} +6 -8
- package/dist/basemap/models/furniture.js.map +1 -0
- package/dist/basemap/{meshes.js → models/meshes.js} +1 -1
- package/dist/basemap/models/meshes.js.map +1 -0
- package/dist/basemap/models/trees.d.ts +21 -0
- package/dist/basemap/{trees.js → models/trees.js} +4 -36
- package/dist/basemap/models/trees.js.map +1 -0
- package/dist/basemap/placed.d.ts +2 -0
- package/dist/basemap/placed.js +2 -0
- package/dist/basemap/placed.js.map +1 -1
- package/dist/basemap/pmtiles.js +4 -3
- package/dist/basemap/pmtiles.js.map +1 -1
- package/dist/basemap/pmtileslayer.d.ts +4 -4
- package/dist/basemap/pmtileslayer.js +2 -1
- package/dist/basemap/pmtileslayer.js.map +1 -1
- package/dist/basemap/resample.js +3 -2
- package/dist/basemap/resample.js.map +1 -1
- package/dist/basemap/terrain.d.ts +5 -0
- package/dist/basemap/terrain.js +6 -4
- package/dist/basemap/terrain.js.map +1 -1
- package/dist/basemap/vectortiles/context.d.ts +3 -2
- package/dist/basemap/vectortiles/context.js.map +1 -1
- package/dist/basemap/vectortiles/extrusions.js.map +1 -1
- package/dist/basemap/vectortiles/furniture.d.ts +3 -3
- package/dist/basemap/vectortiles/furniture.js +2 -1
- package/dist/basemap/vectortiles/furniture.js.map +1 -1
- package/dist/basemap/vectortiles/labels.js +2 -1
- package/dist/basemap/vectortiles/labels.js.map +1 -1
- package/dist/basemap/vectortiles/lamps.d.ts +3 -3
- package/dist/basemap/vectortiles/lamps.js +1 -1
- package/dist/basemap/vectortiles/lamps.js.map +1 -1
- package/dist/basemap/vectortiles/placed.d.ts +3 -2
- package/dist/basemap/vectortiles/placed.js +5 -10
- package/dist/basemap/vectortiles/placed.js.map +1 -1
- package/dist/basemap/vectortiles/street-wind.js +2 -2
- package/dist/basemap/vectortiles/street-wind.js.map +1 -1
- package/dist/basemap/vectortiles/style.js +7 -8
- package/dist/basemap/vectortiles/style.js.map +1 -1
- package/dist/basemap/vectortiles/tiles.d.ts +1 -3
- package/dist/basemap/vectortiles/tiles.js +1 -1
- package/dist/basemap/vectortiles/tiles.js.map +1 -1
- package/dist/basemap/vectortiles/trees.d.ts +4 -4
- package/dist/basemap/vectortiles/trees.js +2 -1
- package/dist/basemap/vectortiles/trees.js.map +1 -1
- package/dist/basemap/vectortiles/vectors.d.ts +2 -3
- package/dist/basemap/vectortiles/vectors.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +6 -5
- package/dist/basemap/vectortiles.js +4 -3
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/wmts.js +3 -4
- package/dist/basemap/wmts.js.map +1 -1
- package/dist/basemap/{trees.d.ts → woods.d.ts} +2 -19
- package/dist/basemap/woods.js +38 -0
- package/dist/basemap/woods.js.map +1 -0
- package/dist/basemap/workerpool.d.ts +1 -1
- package/dist/basemap/workerpool.js +3 -3
- package/dist/basemap/workerpool.js.map +1 -1
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +23 -22
- package/dist/bind/layers.d.ts +10 -3
- package/dist/bind/layers.js +11 -4
- package/dist/bind/layers.js.map +1 -1
- package/dist/data/collada.js +4 -4
- package/dist/data/collada.js.map +1 -1
- package/dist/data/ifc.js +6 -11
- package/dist/data/ifc.js.map +1 -1
- package/dist/decoder.worker.js +5 -5
- package/dist/decoder.worker.js.map +7 -6
- package/dist/decoding/decoders.js.map +1 -0
- package/dist/{engine → decoding}/loader.js +2 -2
- package/dist/decoding/loader.js.map +1 -0
- package/dist/{engine → decoding}/protocol.d.ts +1 -1
- package/dist/decoding/protocol.js.map +1 -0
- package/dist/engine-loader.d.ts +1 -1
- package/dist/engine-loader.js +3 -2
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +4 -3
- package/dist/geoplateforme.js +8 -10
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +16 -8
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_grid_bg.wasm +0 -0
- package/dist/isard_tess_bg.wasm +0 -0
- package/dist/layers/custom.d.ts +56 -0
- package/dist/layers/custom.js +93 -0
- package/dist/layers/custom.js.map +1 -0
- package/dist/layers/extrusions.d.ts +4 -2
- package/dist/layers/extrusions.js +2 -1
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.d.ts +3 -14
- package/dist/layers/features.js +4 -25
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/flow.d.ts +3 -3
- package/dist/layers/flow.js +3 -4
- package/dist/layers/flow.js.map +1 -1
- package/dist/layers/glyphs.js +5 -3
- package/dist/layers/glyphs.js.map +1 -1
- package/dist/layers/ground.d.ts +57 -0
- package/dist/layers/ground.js +78 -0
- package/dist/layers/ground.js.map +1 -0
- package/dist/layers/icons.js +8 -6
- package/dist/layers/icons.js.map +1 -1
- package/dist/layers/layers.d.ts +2 -199
- package/dist/layers/layers.js +2 -469
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/models.d.ts +48 -0
- package/dist/layers/models.js +111 -0
- package/dist/layers/models.js.map +1 -0
- package/dist/layers/network.d.ts +26 -0
- package/dist/layers/network.js +127 -0
- package/dist/layers/network.js.map +1 -0
- package/dist/layers/panoramas.d.ts +2 -11
- package/dist/layers/panoramas.js +19 -9
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/photos.d.ts +4 -7
- package/dist/layers/photos.js +3 -4
- package/dist/layers/photos.js.map +1 -1
- package/dist/layers/pointclouds.d.ts +3 -2
- package/dist/layers/pointclouds.js +3 -3
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/raster.d.ts +9 -0
- package/dist/layers/raster.js +24 -0
- package/dist/layers/raster.js.map +1 -0
- package/dist/layers/symbols.d.ts +2 -2
- package/dist/layers/symbols.js +2 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/tiles3d.d.ts +15 -0
- package/dist/layers/tiles3d.js +55 -0
- package/dist/layers/tiles3d.js.map +1 -0
- package/dist/layers/trees.d.ts +5 -7
- package/dist/layers/trees.js +2 -1
- package/dist/layers/trees.js.map +1 -1
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/basemap-layers.js +1 -1
- package/dist/map/basemap-layers.js.map +1 -1
- package/dist/map/engine-settings.d.ts +1 -1
- package/dist/map/engine-settings.js +1 -1
- package/dist/map/engine-settings.js.map +1 -1
- package/dist/map/engines.js.map +1 -1
- package/dist/map/layer-spec.d.ts +7 -13
- package/dist/map/layer-spec.js.map +1 -1
- package/dist/map/workers.js +3 -4
- package/dist/map/workers.js.map +1 -1
- package/dist/map.d.ts +15 -58
- package/dist/map.js +39 -52
- package/dist/map.js.map +1 -1
- package/dist/panoramax.d.ts +15 -2
- package/dist/panoramax.js +38 -21
- package/dist/panoramax.js.map +1 -1
- package/dist/react/CustomLayer.d.ts +1 -1
- package/dist/react/CustomLayer.js +5 -4
- package/dist/react/CustomLayer.js.map +1 -1
- package/dist/react/Layer.d.ts +6 -2
- package/dist/react/Layer.js +6 -5
- package/dist/react/Layer.js.map +1 -1
- package/dist/react/VectorGeometry.js +5 -4
- package/dist/react/VectorGeometry.js.map +1 -1
- package/dist/react/VectorTiles.d.ts +2 -2
- package/dist/react/VectorTiles.js +1 -1
- package/dist/react/VectorTiles.js.map +1 -1
- package/dist/react/context.d.ts +3 -0
- package/dist/react/context.js +8 -1
- package/dist/react/context.js.map +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/types.js.map +1 -1
- package/dist/ui/controls.js +2 -1
- package/dist/ui/controls.js.map +1 -1
- package/dist/ui/interaction.js +6 -5
- package/dist/ui/interaction.js.map +1 -1
- package/dist/ui/minimap.js +1 -1
- package/dist/ui/minimap.js.map +1 -1
- package/dist/ui/overlay.js +3 -3
- package/dist/ui/overlay.js.map +1 -1
- package/dist/ui/search.js +1 -1
- package/dist/ui/search.js.map +1 -1
- package/dist/util/animation.js +3 -2
- package/dist/util/animation.js.map +1 -1
- package/dist/util/color.d.ts +10 -0
- package/dist/util/color.js +29 -9
- package/dist/util/color.js.map +1 -1
- package/dist/util/fetch.d.ts +5 -0
- package/dist/util/fetch.js +11 -0
- package/dist/util/fetch.js.map +1 -0
- package/dist/util/geo.d.ts +5 -0
- package/dist/util/geo.js +8 -2
- package/dist/util/geo.js.map +1 -1
- package/dist/util/math.d.ts +3 -0
- package/dist/util/math.js +4 -0
- package/dist/util/math.js.map +1 -0
- package/dist/util/requests.js.map +1 -0
- package/dist/util/roofs.d.ts +0 -2
- package/dist/util/roofs.js +0 -3
- package/dist/util/roofs.js.map +1 -1
- package/dist/wasm/isard.js +1 -1
- package/dist/wasm/isard_core.js +1 -1
- package/dist/workers/basemap/geometry.d.ts +9 -19
- package/dist/workers/{basemap.worker.d.ts → basemap/protocol.d.ts} +29 -23
- package/dist/workers/basemap/street.d.ts +4 -2
- package/dist/workers/basemap/tiles.d.ts +1 -3
- package/dist/workers/basemap/trees.d.ts +2 -2
- package/package.json +1 -1
- package/dist/basemap/furniture.d.ts +0 -26
- package/dist/basemap/furniture.js.map +0 -1
- package/dist/basemap/meshes.js.map +0 -1
- package/dist/basemap/trees.js.map +0 -1
- package/dist/engine/decoders.js.map +0 -1
- package/dist/engine/loader.js.map +0 -1
- package/dist/engine/protocol.js.map +0 -1
- package/dist/engine/requests.js.map +0 -1
- package/dist/workers/basemap/furniture.d.ts +0 -13
- package/dist/workers/basemap/labels.d.ts +0 -24
- package/dist/workers/basemap/lamps.d.ts +0 -10
- package/dist/workers/basemap/raster.d.ts +0 -10
- package/dist/workers/basemap.worker.js +0 -221
- package/dist/workers/basemap.worker.js.map +0 -1
- /package/dist/basemap/{meshes.d.ts → models/meshes.d.ts} +0 -0
- /package/dist/{engine → decoding}/decoders.d.ts +0 -0
- /package/dist/{engine → decoding}/decoders.js +0 -0
- /package/dist/{engine → decoding}/loader.d.ts +0 -0
- /package/dist/{engine → decoding}/protocol.js +0 -0
- /package/dist/{engine → util}/requests.d.ts +0 -0
- /package/dist/{engine → util}/requests.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/labels.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The labels of a vector basemap (`VectorTiles.labels`): the label candidates the workers list for each vector tile in\n * view, shaped in the page once per tile, placed by the engine in a symbol layer of their own.\n */\n\nimport { ExtrusionLayer } from '../../layers/extrusions.ts';\nimport type { Feature, Size } from '../../layers/features.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { SymbolLayer } from '../../layers/symbols.ts';\nimport { VectorLayer } from '../../layers/vectors.ts';\nimport type { Anchor } from '../../ui/overlay.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { Lru } from '../../util/lru.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { Json, LabelCandidate, StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { styleFonts } from './style.ts';\nimport { MAX_TILES, nearPriority, parseTileKey, tileKey, tilesAround, tileTriples } from './tiles.ts';\n\n/** Pause before the labels of tiles that failed are asked for again, when no move brings an update (ms) */\nconst RETRY_LABELS_MS = 3000;\n\n/** Milliseconds between two updates of the labels while the camera moves */\nconst LABELS_MOVE_REFRESH_MS = 250;\n\n/** Vector tiles' labels kept, shaped, the least recently used dropped past it */\nconst CACHED_TILES = 256;\n\n/** Text or icon size of a style (a number, legacy stops, or the stops of a zoom expression made by the worker) as a\n * size for the symbol layer */\nexport const size = (value: Json, fallback = 16): Size => {\n const stop = (s: Json): [number, number] => {\n const [z, v] = Array.isArray(s) ? s : [];\n\n return [Number(z), Number(v)];\n };\n\n if (typeof value === 'number') return value;\n if (Array.isArray(value) && value.length > 0 && value.every(Array.isArray)) return value.map(stop);\n if (isRecord(value) && Array.isArray(value.stops)) return value.stops.map(stop);\n\n return fallback;\n};\n\n/** The anchors of the symbol layer */\nconst ANCHORS: ReadonlySet<string> = new Set<Anchor>([\n 'center',\n 'top',\n 'bottom',\n 'left',\n 'right',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n]);\n\nconst isAnchor = (value: string | undefined): value is Anchor => value !== undefined && ANCHORS.has(value);\n\n/** A style's anchor (`text-anchor`, `icon-anchor`) for the symbol layer: `center` if it is none */\nconst anchor = (value: string | undefined): Anchor => (isAnchor(value) ? value : 'center');\n\n/** The labels of a vector tile: features by style layer (its index in the style), the higher layers first */\ntype TileLabels = [layer: number, features: Feature<LabelCandidate>[]][];\n\n/** Where a candidate is labelled: the line around a text that follows it, a short line along a line's direction (its\n * middle the anchor), or its point */\nconst geometryOf = (p: LabelCandidate): Feature<LabelCandidate>['geometry'] => {\n const { path, along } = p;\n\n if (path) {\n return {\n type: 'LineString',\n coordinates: Array.from({ length: path.length / 2 }, (_, i) => [path[i * 2] ?? 0, path[i * 2 + 1] ?? 0]),\n };\n }\n if (along) {\n return {\n type: 'LineString',\n coordinates: [\n [p.lon - along[0] / 2, p.lat - along[1] / 2],\n [p.lon + along[0] / 2, p.lat + along[1] / 2],\n ],\n };\n }\n\n return { type: 'Point', coordinates: [p.lon, p.lat] };\n};\n\n/** A tile's label candidates as features, by style layer */\nexport const tileLabels = (candidates: readonly LabelCandidate[]): TileLabels => {\n const byLayer = new Map<number, Feature<LabelCandidate>[]>();\n\n candidates.forEach((p) => {\n const feature: Feature<LabelCandidate> = {\n type: 'Feature',\n properties: p,\n geometry: geometryOf(p),\n };\n const list = byLayer.get(p.layer);\n\n if (list) list.push(feature);\n else byLayer.set(p.layer, [feature]);\n });\n\n return [...byLayer].sort((a, b) => b[0] - a[0]);\n};\n\n/** The key of a vector tile's labels: `z/x/y`, then `@zoom` when they are those of a deeper zoom than the tile's */\nconst labelsKey = (z: number, x: number, y: number, zoom: number): string =>\n `${tileKey(z, x, y)}${zoom > z ? `@${zoom}` : ''}`;\n\n/** Whether a layer of the basemap raises its buildings: its extrusions, or a style layer `fill-extrusion` of its\n * vectors shown */\nconst raisesBuildings = (layer: Layer): boolean =>\n layer instanceof ExtrusionLayer ||\n (layer instanceof VectorLayer && layer.layers.some((l) => l.kind === 'extrusion' && l.visible));\n\n/** The options of `VectorTiles.labels` */\nexport interface LabelsOptions {\n layers?: (layer: StyleLayer) => boolean;\n maxTiles?: number;\n /** Hidden by the solids before them (the buildings, the trees, the models) and lifted onto the roofs (default: when\n * these tiles raise buildings; `true` for buildings raised by others, a `<VectorGeometry>` of the same style) */\n occluded?: boolean;\n}\n\nexport const labels = (context: VectorTilesContext, options: LabelsOptions = {}): SymbolLayer<LabelCandidate> => {\n const { map } = context;\n const { layers = () => true, maxTiles = MAX_TILES } = options;\n const symbol = map.addSymbols<LabelCandidate>({\n data: [],\n text: (p) => p.text,\n font: (p) => p.font,\n size: (p) => size(p.size),\n color: (p) => p.color,\n haloColor: (p) => p.haloColor,\n haloWidth: (p) => p.haloWidth,\n anchor: (p) => anchor(p.anchor),\n offset: (p) => p.offset,\n maxWidth: (p) => p.maxWidth,\n lineHeight: (p) => p.lineHeight,\n overlap: (p) => p.overlap,\n placement: (p) => (p.textAlong ? 'line' : 'point'),\n textOptional: (p) => p.textOptional === true,\n icon: (p) => (p.icon ? context.iconPrefix + p.icon.image : ''),\n iconSize: (p) => size(p.icon?.size ?? 1, 1),\n iconAnchor: (p) => anchor(p.icon?.anchor),\n iconOffset: (p) => p.icon?.offset ?? [0, 0],\n iconRotate: (p) => p.icon?.rotate ?? 0,\n iconRotationAlignment: (p) => p.icon?.alignment ?? 'viewport',\n iconOverlap: (p) => p.icon?.overlap ?? false,\n iconOptional: (p) => p.icon?.optional ?? false,\n iconTextFit: (p) => p.icon?.fit ?? 'none',\n iconTextFitPadding: (p) => p.icon?.padding ?? [0, 0, 0, 0],\n iconColor: (p) => p.icon?.color ?? '#000',\n iconOpacity: (p) => p.icon?.opacity ?? 1,\n });\n\n map.keepOnTop(symbol);\n context.layers.push(symbol);\n\n const renderer = context.ready.then(async ({ style }) => {\n // The style's fonts from its own glyphs\n if (style.glyphs) map.glyphs.register(style.glyphs, styleFonts(style));\n\n // Its icons from its sprites, before the first labels\n const icons = style.layers.some((l) => l.type === 'symbol' && l.layout?.['icon-image'] !== undefined);\n\n if (icons) await context.addSprites();\n\n // With the buildings: a label in one stands on its roof\n return context.renderer((l) => (l.type === 'symbol' && layers(l)) || l.type === 'fill-extrusion', []);\n });\n\n renderer.catch(() => undefined);\n\n /** The labels of the tiles, as features by style layer, the higher layers first: each list is given to the symbol\n * layer as a group, shaped once while the tile is kept */\n const tiles = new Lru<string, Promise<TileLabels>>(CACHED_TILES);\n let generation = 0;\n /** The tiles whose labels are shown */\n let shown = '';\n /** The update asked again after tiles failed */\n let retry = 0;\n /** The labels hidden by the buildings the basemap raises, those in one standing on its roof */\n let occluded = false;\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const others = context.layers.filter((l) => l !== symbol);\n\n // Its vectors' style layers known first\n await Promise.all(others.map((l) => (l instanceof VectorLayer ? l.styled : undefined)));\n\n const raised = options.occluded ?? others.some(raisesBuildings);\n\n if (raised !== occluded) {\n occluded = raised;\n symbol.setStyle({ occluded, height: occluded ? (p) => p.height ?? 0 : 0 });\n // The labels asked again, with their heights or without\n tiles.clear();\n shown = '';\n }\n\n const run = ++generation;\n const camera = map.getCamera();\n const zoom = Math.max(0, Math.min(Math.floor(camera.zoom), 24));\n const ground = context.ground();\n const groundTiles = ground && map.hasLayer(ground) ? tileTriples(map.engine.wantedTiles(ground.id)) : [];\n const keys: string[] = [];\n\n if (groundTiles.length > 0) {\n // The ground's tiles, the nearest first: a tile so many levels coarser than the finest in view has its\n // labels of a zoom as many under the view's, past the source's deepest level those of that level at the zoom\n const top = groundTiles.reduce((t, [z]) => Math.max(t, z), 0);\n\n groundTiles.forEach(([z, x, y]) => {\n if (keys.length >= maxTiles) return;\n\n const at = Math.max(0, zoom - (top - z));\n const tz = Math.min(at, maxzoom, z);\n const shift = 2 ** (z - tz);\n const key = labelsKey(tz, Math.floor(x / shift), Math.floor(y / shift), at);\n\n if (!keys.includes(key)) keys.push(key);\n });\n } else {\n const z = Math.min(zoom, maxzoom);\n const wanted = tilesAround(map, camera, z, maxTiles);\n\n // Past the source's deepest level, its tiles' labels at the zoom of the view (the layers of the deeper zooms)\n keys.push(...wanted.map(([x, y]) => labelsKey(z, x, y, zoom)));\n }\n\n // The same tiles as the labels shown: nothing to do\n const set = keys.join(' ');\n\n if (set === shown) return;\n\n const lists = await Promise.all(\n keys.map((k, index) => {\n const cached = tiles.get(k);\n\n if (cached) return cached;\n\n const [tile = '', deeper] = k.split('@');\n const [tz, x, y] = parseTileKey(tile);\n // The nearest tiles first: the others wait for the raster tiles\n const work: BasemapWork = {\n type: 'labels',\n key,\n z: tz,\n x,\n y,\n priority: nearPriority(index),\n ...(deeper === undefined ? {} : { zoom: Number(deeper) }),\n ...(occluded ? { roofs: true } : {}),\n };\n const p = context.request(tz, x, y, work).then(\n (r) => tileLabels('labels' in r ? r.labels : []),\n () => {\n // A network error is not kept: the tile is asked for again on the next update\n tiles.delete(k);\n\n return [];\n },\n );\n\n // A bounded cache of tiles' labels, the least recently used dropped\n tiles.set(k, p);\n\n return p;\n }),\n );\n\n if (run !== generation || context.destroyed()) return;\n // A tile that failed is missing: the next update asks for it again, after a pause if no move brings one\n shown = keys.every((k) => tiles.has(k)) ? set : '';\n if (shown === '' && !retry) {\n retry = window.setTimeout(() => {\n retry = 0;\n refresh();\n }, RETRY_LABELS_MS);\n }\n\n // The labels of the higher style layers first: they win the collisions; for each style layer, the tiles nearest\n // to the center first\n const layerIds = [...new Set(lists.flatMap((list) => list.map(([layer]) => layer)))].sort((a, b) => b - a);\n const groups = layerIds.flatMap((layer) =>\n lists.map((list) => list.find(([l]) => l === layer)?.[1]).filter((group) => group !== undefined),\n );\n\n symbol.setGroups(groups);\n };\n // The style failed to load: reported by `ready`\n const refresh = () => {\n update().catch(() => undefined);\n };\n let timer = 0;\n const schedule = () => {\n if (timer) return;\n timer = window.setTimeout(() => {\n timer = 0;\n refresh();\n }, LABELS_MOVE_REFRESH_MS);\n };\n\n const [offMove, offEnd] = [map.on('move', schedule), map.on('moveend', refresh)];\n\n context.stopWith(symbol, () => {\n offMove();\n offEnd();\n clearTimeout(timer);\n clearTimeout(retry);\n });\n refresh();\n\n return symbol;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/labels.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The labels of a vector basemap (`VectorTiles.labels`): the label candidates the workers list for each vector tile in\n * view, shaped in the page once per tile, placed by the engine in a symbol layer of their own.\n */\n\nimport { ExtrusionLayer } from '../../layers/extrusions.ts';\nimport type { Feature, Size } from '../../layers/features.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { SymbolLayer } from '../../layers/symbols.ts';\nimport { VectorLayer } from '../../layers/vectors.ts';\nimport type { Anchor } from '../../ui/overlay.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { Lru } from '../../util/lru.ts';\nimport { clamp } from '../../util/math.ts';\nimport type { BasemapWork } from '../../workers/basemap/protocol.ts';\nimport type { Json, LabelCandidate, StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { styleFonts } from './style.ts';\nimport { MAX_TILES, nearPriority, parseTileKey, tileKey, tilesAround, tileTriples } from './tiles.ts';\n\n/** Pause before the labels of tiles that failed are asked for again, when no move brings an update (ms) */\nconst RETRY_LABELS_MS = 3000;\n\n/** Milliseconds between two updates of the labels while the camera moves */\nconst LABELS_MOVE_REFRESH_MS = 250;\n\n/** Vector tiles' labels kept, shaped, the least recently used dropped past it */\nconst CACHED_TILES = 256;\n\n/** Text or icon size of a style (a number, legacy stops, or the stops of a zoom expression made by the worker) as a\n * size for the symbol layer */\nexport const size = (value: Json, fallback = 16): Size => {\n const stop = (s: Json): [number, number] => {\n const [z, v] = Array.isArray(s) ? s : [];\n\n return [Number(z), Number(v)];\n };\n\n if (typeof value === 'number') return value;\n if (Array.isArray(value) && value.length > 0 && value.every(Array.isArray)) return value.map(stop);\n if (isRecord(value) && Array.isArray(value.stops)) return value.stops.map(stop);\n\n return fallback;\n};\n\n/** The anchors of the symbol layer */\nconst ANCHORS: ReadonlySet<string> = new Set<Anchor>([\n 'center',\n 'top',\n 'bottom',\n 'left',\n 'right',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n]);\n\nconst isAnchor = (value: string | undefined): value is Anchor => value !== undefined && ANCHORS.has(value);\n\n/** A style's anchor (`text-anchor`, `icon-anchor`) for the symbol layer: `center` if it is none */\nconst anchor = (value: string | undefined): Anchor => (isAnchor(value) ? value : 'center');\n\n/** The labels of a vector tile: features by style layer (its index in the style), the higher layers first */\ntype TileLabels = [layer: number, features: Feature<LabelCandidate>[]][];\n\n/** Where a candidate is labelled: the line around a text that follows it, a short line along a line's direction (its\n * middle the anchor), or its point */\nconst geometryOf = (p: LabelCandidate): Feature<LabelCandidate>['geometry'] => {\n const { path, along } = p;\n\n if (path) {\n return {\n type: 'LineString',\n coordinates: Array.from({ length: path.length / 2 }, (_, i) => [path[i * 2] ?? 0, path[i * 2 + 1] ?? 0]),\n };\n }\n if (along) {\n return {\n type: 'LineString',\n coordinates: [\n [p.lon - along[0] / 2, p.lat - along[1] / 2],\n [p.lon + along[0] / 2, p.lat + along[1] / 2],\n ],\n };\n }\n\n return { type: 'Point', coordinates: [p.lon, p.lat] };\n};\n\n/** A tile's label candidates as features, by style layer */\nexport const tileLabels = (candidates: readonly LabelCandidate[]): TileLabels => {\n const byLayer = new Map<number, Feature<LabelCandidate>[]>();\n\n candidates.forEach((p) => {\n const feature: Feature<LabelCandidate> = {\n type: 'Feature',\n properties: p,\n geometry: geometryOf(p),\n };\n const list = byLayer.get(p.layer);\n\n if (list) list.push(feature);\n else byLayer.set(p.layer, [feature]);\n });\n\n return [...byLayer].sort((a, b) => b[0] - a[0]);\n};\n\n/** The key of a vector tile's labels: `z/x/y`, then `@zoom` when they are those of a deeper zoom than the tile's */\nconst labelsKey = (z: number, x: number, y: number, zoom: number): string =>\n `${tileKey(z, x, y)}${zoom > z ? `@${zoom}` : ''}`;\n\n/** Whether a layer of the basemap raises its buildings: its extrusions, or a style layer `fill-extrusion` of its\n * vectors shown */\nconst raisesBuildings = (layer: Layer): boolean =>\n layer instanceof ExtrusionLayer ||\n (layer instanceof VectorLayer && layer.layers.some((l) => l.kind === 'extrusion' && l.visible));\n\n/** The options of `VectorTiles.labels` */\nexport interface LabelsOptions {\n layers?: (layer: StyleLayer) => boolean;\n maxTiles?: number;\n /** Hidden by the solids before them (the buildings, the trees, the models) and lifted onto the roofs (default: when\n * these tiles raise buildings; `true` for buildings raised by others, a `<VectorGeometry>` of the same style) */\n occluded?: boolean;\n}\n\nexport const labels = (context: VectorTilesContext, options: LabelsOptions = {}): SymbolLayer<LabelCandidate> => {\n const { map } = context;\n const { layers = () => true, maxTiles = MAX_TILES } = options;\n const symbol = map.addSymbols<LabelCandidate>({\n data: [],\n text: (p) => p.text,\n font: (p) => p.font,\n size: (p) => size(p.size),\n color: (p) => p.color,\n haloColor: (p) => p.haloColor,\n haloWidth: (p) => p.haloWidth,\n anchor: (p) => anchor(p.anchor),\n offset: (p) => p.offset,\n maxWidth: (p) => p.maxWidth,\n lineHeight: (p) => p.lineHeight,\n overlap: (p) => p.overlap,\n placement: (p) => (p.textAlong ? 'line' : 'point'),\n textOptional: (p) => p.textOptional === true,\n icon: (p) => (p.icon ? context.iconPrefix + p.icon.image : ''),\n iconSize: (p) => size(p.icon?.size ?? 1, 1),\n iconAnchor: (p) => anchor(p.icon?.anchor),\n iconOffset: (p) => p.icon?.offset ?? [0, 0],\n iconRotate: (p) => p.icon?.rotate ?? 0,\n iconRotationAlignment: (p) => p.icon?.alignment ?? 'viewport',\n iconOverlap: (p) => p.icon?.overlap ?? false,\n iconOptional: (p) => p.icon?.optional ?? false,\n iconTextFit: (p) => p.icon?.fit ?? 'none',\n iconTextFitPadding: (p) => p.icon?.padding ?? [0, 0, 0, 0],\n iconColor: (p) => p.icon?.color ?? '#000',\n iconOpacity: (p) => p.icon?.opacity ?? 1,\n });\n\n map.keepOnTop(symbol);\n context.layers.push(symbol);\n\n const renderer = context.ready.then(async ({ style }) => {\n // The style's fonts from its own glyphs\n if (style.glyphs) map.glyphs.register(style.glyphs, styleFonts(style));\n\n // Its icons from its sprites, before the first labels\n const icons = style.layers.some((l) => l.type === 'symbol' && l.layout?.['icon-image'] !== undefined);\n\n if (icons) await context.addSprites();\n\n // With the buildings: a label in one stands on its roof\n return context.renderer((l) => (l.type === 'symbol' && layers(l)) || l.type === 'fill-extrusion', []);\n });\n\n renderer.catch(() => undefined);\n\n /** The labels of the tiles, as features by style layer, the higher layers first: each list is given to the symbol\n * layer as a group, shaped once while the tile is kept */\n const tiles = new Lru<string, Promise<TileLabels>>(CACHED_TILES);\n let generation = 0;\n /** The tiles whose labels are shown */\n let shown = '';\n /** The update asked again after tiles failed */\n let retry = 0;\n /** The labels hidden by the buildings the basemap raises, those in one standing on its roof */\n let occluded = false;\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const others = context.layers.filter((l) => l !== symbol);\n\n // Its vectors' style layers known first\n await Promise.all(others.map((l) => (l instanceof VectorLayer ? l.styled : undefined)));\n\n const raised = options.occluded ?? others.some(raisesBuildings);\n\n if (raised !== occluded) {\n occluded = raised;\n symbol.setStyle({ occluded, height: occluded ? (p) => p.height ?? 0 : 0 });\n // The labels asked again, with their heights or without\n tiles.clear();\n shown = '';\n }\n\n const run = ++generation;\n const camera = map.getCamera();\n const zoom = clamp(Math.floor(camera.zoom), 0, 24);\n const ground = context.ground();\n const groundTiles = ground && map.hasLayer(ground) ? tileTriples(map.engine.wantedTiles(ground.id)) : [];\n const keys: string[] = [];\n\n if (groundTiles.length > 0) {\n // The ground's tiles, the nearest first: a tile so many levels coarser than the finest in view has its\n // labels of a zoom as many under the view's, past the source's deepest level those of that level at the zoom\n const top = groundTiles.reduce((t, [z]) => Math.max(t, z), 0);\n\n groundTiles.forEach(([z, x, y]) => {\n if (keys.length >= maxTiles) return;\n\n const at = Math.max(0, zoom - (top - z));\n const tz = Math.min(at, maxzoom, z);\n const shift = 2 ** (z - tz);\n const key = labelsKey(tz, Math.floor(x / shift), Math.floor(y / shift), at);\n\n if (!keys.includes(key)) keys.push(key);\n });\n } else {\n const z = Math.min(zoom, maxzoom);\n const wanted = tilesAround(map, camera, z, maxTiles);\n\n // Past the source's deepest level, its tiles' labels at the zoom of the view (the layers of the deeper zooms)\n keys.push(...wanted.map(([x, y]) => labelsKey(z, x, y, zoom)));\n }\n\n // The same tiles as the labels shown: nothing to do\n const set = keys.join(' ');\n\n if (set === shown) return;\n\n const lists = await Promise.all(\n keys.map((k, index) => {\n const cached = tiles.get(k);\n\n if (cached) return cached;\n\n const [tile = '', deeper] = k.split('@');\n const [tz, x, y] = parseTileKey(tile);\n // The nearest tiles first: the others wait for the raster tiles\n const work: BasemapWork = {\n type: 'labels',\n key,\n z: tz,\n x,\n y,\n priority: nearPriority(index),\n ...(deeper === undefined ? {} : { zoom: Number(deeper) }),\n ...(occluded ? { roofs: true } : {}),\n };\n const p = context.request(tz, x, y, work).then(\n (r) => tileLabels('labels' in r ? r.labels : []),\n () => {\n // A network error is not kept: the tile is asked for again on the next update\n tiles.delete(k);\n\n return [];\n },\n );\n\n // A bounded cache of tiles' labels, the least recently used dropped\n tiles.set(k, p);\n\n return p;\n }),\n );\n\n if (run !== generation || context.destroyed()) return;\n // A tile that failed is missing: the next update asks for it again, after a pause if no move brings one\n shown = keys.every((k) => tiles.has(k)) ? set : '';\n if (shown === '' && !retry) {\n retry = window.setTimeout(() => {\n retry = 0;\n refresh();\n }, RETRY_LABELS_MS);\n }\n\n // The labels of the higher style layers first: they win the collisions; for each style layer, the tiles nearest\n // to the center first\n const layerIds = [...new Set(lists.flatMap((list) => list.map(([layer]) => layer)))].sort((a, b) => b - a);\n const groups = layerIds.flatMap((layer) =>\n lists.map((list) => list.find(([l]) => l === layer)?.[1]).filter((group) => group !== undefined),\n );\n\n symbol.setGroups(groups);\n };\n // The style failed to load: reported by `ready`\n const refresh = () => {\n update().catch(() => undefined);\n };\n let timer = 0;\n const schedule = () => {\n if (timer) return;\n timer = window.setTimeout(() => {\n timer = 0;\n refresh();\n }, LABELS_MOVE_REFRESH_MS);\n };\n\n const [offMove, offEnd] = [map.on('move', schedule), map.on('moveend', refresh)];\n\n context.stopWith(symbol, () => {\n offMove();\n offEnd();\n clearTimeout(timer);\n clearTimeout(retry);\n });\n refresh();\n\n return symbol;\n};\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at
|
|
2
2
|
* night */
|
|
3
|
-
import type {
|
|
3
|
+
import type { ModelLayer } from '../../layers/models.ts';
|
|
4
|
+
import type { Placement } from '../../types.ts';
|
|
4
5
|
import type { StyleLayer } from '../vectorstyle.ts';
|
|
5
6
|
import type { VectorTilesContext } from './context.ts';
|
|
6
7
|
/** The options of `VectorTiles.lamps` */
|
|
7
|
-
export interface LampsOptions {
|
|
8
|
+
export interface LampsOptions extends Placement {
|
|
8
9
|
/** The line layers of the streets lit (default: the roads, as the streets glowing at night) */
|
|
9
10
|
layers?: (layer: StyleLayer) => boolean;
|
|
10
11
|
/** Metres between two lamps along a street (default 30, every other one on its other side) */
|
|
@@ -18,6 +19,5 @@ export interface LampsOptions {
|
|
|
18
19
|
maxInstances?: number;
|
|
19
20
|
/** The color of their light at night (CSS; default a warm white) */
|
|
20
21
|
light?: string;
|
|
21
|
-
before?: Layer;
|
|
22
22
|
}
|
|
23
23
|
export declare const lamps: (context: VectorTilesContext, options?: LampsOptions) => ModelLayer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at
|
|
2
2
|
* night */
|
|
3
|
-
import { LAMP_HEAD, lampModel } from "../furniture.js";
|
|
3
|
+
import { LAMP_HEAD, lampModel } from "../models/furniture.js";
|
|
4
4
|
import { placed } from "./placed.js";
|
|
5
5
|
import { isStreet } from "./vectors.js";
|
|
6
6
|
/** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lamps.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/lamps.ts"],"names":[],"mappings":"AAAA;WACW;
|
|
1
|
+
{"version":3,"file":"lamps.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/lamps.ts"],"names":[],"mappings":"AAAA;WACW;AAIX,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;gCACgC;AAChC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAmB9B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAA2B,EAAE,UAAwB,EAAE,EAAc,EAAE;IAC3F,MAAM,EACJ,MAAM,GAAG,QAAQ,EACjB,OAAO,GAAG,EAAE,EACZ,OAAO,GAAG,EAAE,EACZ,QAAQ,GAAG,CAAC,EACZ,QAAQ,GAAG,KAAK,EAChB,YAAY,GAAG,KAAK,EACpB,KAAK,GAAG,SAAS,GAClB,GAAG,OAAO,CAAC;IACZ,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;QAC9B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAChG,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7B,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEhC,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["/** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at\n * night */\n\nimport type { ModelLayer } from '../../layers/models.ts';\nimport type { Placement } from '../../types.ts';\nimport { LAMP_HEAD, lampModel } from '../models/furniture.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { placed } from './placed.ts';\nimport { isStreet } from './vectors.ts';\n\n/** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);\n * past them, fewer and fewer */\nconst LAMPS_NEAR_METRES = 250;\n\n/** The options of `VectorTiles.lamps` */\nexport interface LampsOptions extends Placement {\n /** The line layers of the streets lit (default: the roads, as the streets glowing at night) */\n layers?: (layer: StyleLayer) => boolean;\n /** Metres between two lamps along a street (default 30, every other one on its other side) */\n spacing?: number;\n /** From this zoom on (default 16) */\n minZoom?: number;\n maxTiles?: number;\n /** Lamps in a tile at most (default 20000) */\n maxLamps?: number;\n /** Lamps drawn at most (default 15000) */\n maxInstances?: number;\n /** The color of their light at night (CSS; default a warm white) */\n light?: string;\n}\n\nexport const lamps = (context: VectorTilesContext, options: LampsOptions = {}): ModelLayer => {\n const {\n layers = isStreet,\n spacing = 30,\n minZoom = 16,\n maxTiles = 9,\n maxLamps = 20000,\n maxInstances = 15000,\n light = '#ffd9a0',\n } = options;\n const [layer] = placed(context, {\n models: [{ data: lampModel() }],\n layers: (l) => l.type === 'line' && layers(l),\n work: (key, z, x, y, priority) => ({ type: 'lamps', key, z, x, y, spacing, maxLamps, priority }),\n read: (r) => ('lamps' in r ? r.lamps : undefined),\n near: [LAMPS_NEAR_METRES, 17],\n minZoom,\n maxTiles,\n maxInstances,\n ...(options.before && { before: options.before }),\n });\n\n layer.setGlow(LAMP_HEAD, light);\n\n return layer;\n};\n"]}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a
|
|
4
4
|
* simplified model there when the kind has one), the tiles following the view.
|
|
5
5
|
*/
|
|
6
|
-
import type { Layer
|
|
7
|
-
import type {
|
|
6
|
+
import type { Layer } from '../../layers/layers.ts';
|
|
7
|
+
import type { ModelLayer, ModelOptions } from '../../layers/models.ts';
|
|
8
|
+
import type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap/protocol.ts';
|
|
8
9
|
import type { StyleLayer } from '../vectorstyle.ts';
|
|
9
10
|
import type { VectorTilesContext } from './context.ts';
|
|
10
11
|
/** A model: a glTF binary's URL or bytes */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a
|
|
4
4
|
* simplified model there when the kind has one), the tiles following the view.
|
|
5
5
|
*/
|
|
6
|
-
import { METRES_PER_DEGREE } from "../../util/geo.js";
|
|
6
|
+
import { METRES_PER_DEGREE, RAD } from "../../util/geo.js";
|
|
7
7
|
import { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from "../placed.js";
|
|
8
8
|
import { TileRequests } from "./requests.js";
|
|
9
9
|
import { nearPriority, tileKey, tilesAround } from "./tiles.js";
|
|
@@ -16,10 +16,8 @@ const RESEND_SHARE = 0.05;
|
|
|
16
16
|
* stands behind the center of a tilted view, `FOV` its field of view) */
|
|
17
17
|
const groundUnderCamera = (map) => {
|
|
18
18
|
const { pitch, bearing } = map.getCamera();
|
|
19
|
-
const back = ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *
|
|
20
|
-
|
|
21
|
-
(map.metersPerPixel() ?? 0);
|
|
22
|
-
return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];
|
|
19
|
+
const back = ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) * Math.sin(pitch * RAD) * (map.metersPerPixel() ?? 0);
|
|
20
|
+
return [-back * Math.sin(bearing * RAD), -back * Math.cos(bearing * RAD), back];
|
|
23
21
|
};
|
|
24
22
|
/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or
|
|
25
23
|
* turned or zoomed as much), not at every frame of a drag */
|
|
@@ -28,10 +26,7 @@ const followWhenMoved = (map, radius, send) => {
|
|
|
28
26
|
let sent;
|
|
29
27
|
return () => {
|
|
30
28
|
const { center, zoom, bearing, pitch } = map.getCamera();
|
|
31
|
-
const [x, y] = [
|
|
32
|
-
center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),
|
|
33
|
-
center[1] * METRES_PER_DEGREE,
|
|
34
|
-
];
|
|
29
|
+
const [x, y] = [center[0] * METRES_PER_DEGREE * Math.cos(center[1] * RAD), center[1] * METRES_PER_DEGREE];
|
|
35
30
|
if (sent &&
|
|
36
31
|
Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&
|
|
37
32
|
Math.abs(zoom - sent[2]) < RESEND_SHARE &&
|
|
@@ -62,7 +57,7 @@ export const placed = (context, options) => {
|
|
|
62
57
|
* lowered in proportion: no sort) */
|
|
63
58
|
const send = () => {
|
|
64
59
|
const { center, zoom } = map.getCamera();
|
|
65
|
-
const cos = Math.cos(
|
|
60
|
+
const cos = Math.cos(center[1] * RAD);
|
|
66
61
|
const [ex, ey, back] = groundUnderCamera(map);
|
|
67
62
|
const near = radius(zoom) + back;
|
|
68
63
|
const density = far?.density ?? 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"placed.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/placed.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Things placed by the workers in a vector basemap's tiles around the view (trees, street lamps, street furniture),\n * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a\n * simplified model there when the kind has one), the tiles following the view.\n */\n\nimport type { Layer, ModelLayer, ModelOptions } from '../../layers/layers.ts';\nimport type { GeoMap } from '../../map.ts';\nimport { METRES_PER_DEGREE } from '../../util/geo.ts';\nimport type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from '../placed.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, tileKey, tilesAround } from './tiles.ts';\n\n/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */\nconst FOV = 0.6435011087932844;\n\n/** While the camera moves, the things chosen again once it has gone this share of the near radius (or turned or\n * zoomed as much): going through the tiles' things at every frame of a drag would hold the main thread */\nconst RESEND_SHARE = 0.05;\n\n/** A model: a glTF binary's URL or bytes */\ntype Model = Pick<ModelOptions, 'url' | 'data'>;\n\ninterface PlacedOptions {\n /** A model per kind (`PLACED_KIND`); a kind past them drawn with the first */\n models: [Model, ...Model[]];\n /** Past `near`, the kinds' simplified models (as many), drawn `density` times as densely as the full ones would\n * be, at most `instances` times `maxInstances` */\n far?: { models: Model[]; density: number; instances: number };\n /** The style layers the renderer sends the workers (the tiles' source and its levels) */\n layers: (layer: StyleLayer) => boolean;\n /** The work asked of the worker of a tile (`layers`: the renderer's), and the things in its answer */\n work: (key: string, z: number, x: number, y: number, priority: Priority, layers: StyleLayer[]) => BasemapWork;\n read: (response: BasemapResponse) => Float64Array | undefined;\n /** Metres around the ground under the camera where every one is drawn at a zoom (twice as far a zoom level out) */\n near: [metres: number, zoom: number];\n minZoom: number;\n maxTiles: number;\n /** Things drawn at most, all kinds together (and `far.instances` times as many simplified) */\n maxInstances: number;\n before?: Layer;\n}\n\n/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera\n * stands behind the center of a tilted view, `FOV` its field of view) */\nconst groundUnderCamera = (map: GeoMap): [east: number, north: number, distance: number] => {\n const { pitch, bearing } = map.getCamera();\n const back =\n ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *\n Math.sin((pitch * Math.PI) / 180) *\n (map.metersPerPixel() ?? 0);\n\n return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];\n};\n\n/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or\n * turned or zoomed as much), not at every frame of a drag */\nconst followWhenMoved = (map: GeoMap, radius: (zoom: number) => number, send: () => void): (() => void) => {\n /** The view of the last call: center (metres), zoom, bearing, pitch */\n let sent: [number, number, number, number, number] | undefined;\n\n return () => {\n const { center, zoom, bearing, pitch } = map.getCamera();\n const [x, y] = [\n center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),\n center[1] * METRES_PER_DEGREE,\n ];\n\n if (\n sent &&\n Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&\n Math.abs(zoom - sent[2]) < RESEND_SHARE &&\n Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&\n Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE\n )\n return;\n sent = [x, y, zoom, bearing, pitch];\n send();\n };\n};\n\n/** The layers of the things placed: one per kind, then one per kind's simplified model; the first holds the others\n * (`Layer.companions`) */\nexport const placed = (context: VectorTilesContext, options: PlacedOptions): [ModelLayer, ...ModelLayer[]] => {\n const { map } = context;\n const { models, far, minZoom, maxTiles, maxInstances } = options;\n const add = (model: Model) =>\n map.addModels({ ...model, instances: [], ...(options.before ? { before: options.before } : {}) });\n const [model, ...more] = models;\n const layers: [ModelLayer, ...ModelLayer[]] = [add(model), ...more.map(add), ...(far?.models ?? []).map(add)];\n const renderer = context.renderer(options.layers, []);\n const radius = (zoom: number) => options.near[0] * 2 ** (options.near[1] - zoom);\n\n renderer.catch(() => undefined);\n layers[0].companions.push(...layers.slice(1));\n context.layers.push(...layers);\n\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The things drawn: all of them near the ground under the camera; past it those of a rank under `density` (near /\n * distance)², simplified; at most `maxInstances` near, `far.instances` times as many past (beyond, the rank kept\n * lowered in proportion: no sort) */\n const send = () => {\n const { center, zoom } = map.getCamera();\n const cos = Math.cos((center[1] * Math.PI) / 180);\n const [ex, ey, back] = groundUnderCamera(map);\n const near = radius(zoom) + back;\n const density = far?.density ?? 1;\n /** Each thing that may be drawn: in full (near, or every one without simplified models) or simplified, with its\n * score (the lowest kept first) */\n const visit = (each: (t: Float64Array, at: number, full: boolean, score: number) => void) => {\n found.forEach((t) => {\n for (let at = 0; at < t.length; at += PLACED_NUMBERS) {\n const dx = ((t[at] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[at + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const distance = (dx * dx + dy * dy) / (near * near);\n const rank = t[at + PLACED_RANK] ?? 0;\n\n if (distance <= 1) each(t, at, true, rank);\n else if (rank * (distance / density) < 1) each(t, at, !far, rank * (distance / density));\n }\n });\n };\n let [fullCount, farCount] = [0, 0];\n\n visit((_, __, full) => {\n if (full) fullCount += 1;\n else farCount += 1;\n });\n\n const limits = [\n Math.min(1, maxInstances / Math.max(fullCount, 1)),\n Math.min(1, (maxInstances * (far?.instances ?? 1)) / Math.max(farCount, 1)),\n ];\n // The engine's numbers: longitude, latitude, altitude, heading, pitch, roll, scale\n const out: number[][] = layers.map(() => []);\n\n visit((t, at, full, score) => {\n if (score >= (limits[full ? 0 : 1] ?? 1)) return;\n\n const kind = t[at + PLACED_KIND] ?? 0;\n const k = (full ? 0 : models.length) + (kind < models.length ? kind : 0);\n\n out[k]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n layers.forEach((layer, k) => {\n layer.setInstanceNumbers(Float64Array.from(out[k] ?? []));\n });\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom: z, layers: list } = await renderer;\n const camera = map.getCamera();\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n\n // Out of view: dropped, or no longer asked for\n requests\n .keys()\n .filter((k) => !keys.has(k))\n .forEach((k) => {\n requests.drop(k);\n found.delete(k);\n });\n // Dense around the new center\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n requests.ask(\n k,\n (signal) => context.request(z, x, y, options.work(key, z, x, y, nearPriority(index), list), signal),\n (r) => {\n const things = options.read(r);\n\n if (!things) return;\n found.set(k, things);\n send();\n },\n );\n });\n };\n\n // While the camera moves, the things drawn follow it (dense near it), chosen again once it has gone far enough\n context.followView(layers[0], update, requests, followWhenMoved(map, radius, send));\n\n return layers;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"placed.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/placed.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Things placed by the workers in a vector basemap's tiles around the view (trees, street lamps, street furniture),\n * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a\n * simplified model there when the kind has one), the tiles following the view.\n */\n\nimport type { Layer } from '../../layers/layers.ts';\nimport type { ModelLayer, ModelOptions } from '../../layers/models.ts';\nimport type { GeoMap } from '../../map.ts';\nimport { METRES_PER_DEGREE, RAD } from '../../util/geo.ts';\nimport type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap/protocol.ts';\nimport { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from '../placed.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, tileKey, tilesAround } from './tiles.ts';\n\n/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */\nconst FOV = 0.6435011087932844;\n\n/** While the camera moves, the things chosen again once it has gone this share of the near radius (or turned or\n * zoomed as much): going through the tiles' things at every frame of a drag would hold the main thread */\nconst RESEND_SHARE = 0.05;\n\n/** A model: a glTF binary's URL or bytes */\ntype Model = Pick<ModelOptions, 'url' | 'data'>;\n\ninterface PlacedOptions {\n /** A model per kind (`PLACED_KIND`); a kind past them drawn with the first */\n models: [Model, ...Model[]];\n /** Past `near`, the kinds' simplified models (as many), drawn `density` times as densely as the full ones would\n * be, at most `instances` times `maxInstances` */\n far?: { models: Model[]; density: number; instances: number };\n /** The style layers the renderer sends the workers (the tiles' source and its levels) */\n layers: (layer: StyleLayer) => boolean;\n /** The work asked of the worker of a tile (`layers`: the renderer's), and the things in its answer */\n work: (key: string, z: number, x: number, y: number, priority: Priority, layers: StyleLayer[]) => BasemapWork;\n read: (response: BasemapResponse) => Float64Array | undefined;\n /** Metres around the ground under the camera where every one is drawn at a zoom (twice as far a zoom level out) */\n near: [metres: number, zoom: number];\n minZoom: number;\n maxTiles: number;\n /** Things drawn at most, all kinds together (and `far.instances` times as many simplified) */\n maxInstances: number;\n before?: Layer;\n}\n\n/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera\n * stands behind the center of a tilted view, `FOV` its field of view) */\nconst groundUnderCamera = (map: GeoMap): [east: number, north: number, distance: number] => {\n const { pitch, bearing } = map.getCamera();\n const back =\n ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) * Math.sin(pitch * RAD) * (map.metersPerPixel() ?? 0);\n\n return [-back * Math.sin(bearing * RAD), -back * Math.cos(bearing * RAD), back];\n};\n\n/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or\n * turned or zoomed as much), not at every frame of a drag */\nconst followWhenMoved = (map: GeoMap, radius: (zoom: number) => number, send: () => void): (() => void) => {\n /** The view of the last call: center (metres), zoom, bearing, pitch */\n let sent: [number, number, number, number, number] | undefined;\n\n return () => {\n const { center, zoom, bearing, pitch } = map.getCamera();\n const [x, y] = [center[0] * METRES_PER_DEGREE * Math.cos(center[1] * RAD), center[1] * METRES_PER_DEGREE];\n\n if (\n sent &&\n Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&\n Math.abs(zoom - sent[2]) < RESEND_SHARE &&\n Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&\n Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE\n )\n return;\n sent = [x, y, zoom, bearing, pitch];\n send();\n };\n};\n\n/** The layers of the things placed: one per kind, then one per kind's simplified model; the first holds the others\n * (`Layer.companions`) */\nexport const placed = (context: VectorTilesContext, options: PlacedOptions): [ModelLayer, ...ModelLayer[]] => {\n const { map } = context;\n const { models, far, minZoom, maxTiles, maxInstances } = options;\n const add = (model: Model) =>\n map.addModels({ ...model, instances: [], ...(options.before ? { before: options.before } : {}) });\n const [model, ...more] = models;\n const layers: [ModelLayer, ...ModelLayer[]] = [add(model), ...more.map(add), ...(far?.models ?? []).map(add)];\n const renderer = context.renderer(options.layers, []);\n const radius = (zoom: number) => options.near[0] * 2 ** (options.near[1] - zoom);\n\n renderer.catch(() => undefined);\n layers[0].companions.push(...layers.slice(1));\n context.layers.push(...layers);\n\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The things drawn: all of them near the ground under the camera; past it those of a rank under `density` (near /\n * distance)², simplified; at most `maxInstances` near, `far.instances` times as many past (beyond, the rank kept\n * lowered in proportion: no sort) */\n const send = () => {\n const { center, zoom } = map.getCamera();\n const cos = Math.cos(center[1] * RAD);\n const [ex, ey, back] = groundUnderCamera(map);\n const near = radius(zoom) + back;\n const density = far?.density ?? 1;\n /** Each thing that may be drawn: in full (near, or every one without simplified models) or simplified, with its\n * score (the lowest kept first) */\n const visit = (each: (t: Float64Array, at: number, full: boolean, score: number) => void) => {\n found.forEach((t) => {\n for (let at = 0; at < t.length; at += PLACED_NUMBERS) {\n const dx = ((t[at] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[at + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const distance = (dx * dx + dy * dy) / (near * near);\n const rank = t[at + PLACED_RANK] ?? 0;\n\n if (distance <= 1) each(t, at, true, rank);\n else if (rank * (distance / density) < 1) each(t, at, !far, rank * (distance / density));\n }\n });\n };\n let [fullCount, farCount] = [0, 0];\n\n visit((_, __, full) => {\n if (full) fullCount += 1;\n else farCount += 1;\n });\n\n const limits = [\n Math.min(1, maxInstances / Math.max(fullCount, 1)),\n Math.min(1, (maxInstances * (far?.instances ?? 1)) / Math.max(farCount, 1)),\n ];\n // The engine's numbers: longitude, latitude, altitude, heading, pitch, roll, scale\n const out: number[][] = layers.map(() => []);\n\n visit((t, at, full, score) => {\n if (score >= (limits[full ? 0 : 1] ?? 1)) return;\n\n const kind = t[at + PLACED_KIND] ?? 0;\n const k = (full ? 0 : models.length) + (kind < models.length ? kind : 0);\n\n out[k]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n layers.forEach((layer, k) => {\n layer.setInstanceNumbers(Float64Array.from(out[k] ?? []));\n });\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom: z, layers: list } = await renderer;\n const camera = map.getCamera();\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n\n // Out of view: dropped, or no longer asked for\n requests\n .keys()\n .filter((k) => !keys.has(k))\n .forEach((k) => {\n requests.drop(k);\n found.delete(k);\n });\n // Dense around the new center\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n requests.ask(\n k,\n (signal) => context.request(z, x, y, options.work(key, z, x, y, nearPriority(index), list), signal),\n (r) => {\n const things = options.read(r);\n\n if (!things) return;\n found.set(k, things);\n send();\n },\n );\n });\n };\n\n // While the camera moves, the things drawn follow it (dense near it), chosen again once it has gone far enough\n context.followView(layers[0], update, requests, followWhenMoved(map, radius, send));\n\n return layers;\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */
|
|
2
|
-
import { EARTH_METRES, latitude, longitude, mercatorX, mercatorY } from "../../util/geo.js";
|
|
2
|
+
import { EARTH_METRES, latitude, longitude, mercatorX, mercatorY, RAD } from "../../util/geo.js";
|
|
3
3
|
import { TileRequests } from "./requests.js";
|
|
4
4
|
import { isBuildings, isPolygonLayer } from "./style.js";
|
|
5
5
|
import { STREET_ZOOM } from "./tiles.js";
|
|
@@ -44,7 +44,7 @@ export const streetWind = (context, options = {}) => {
|
|
|
44
44
|
const camera = map.getCamera();
|
|
45
45
|
const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];
|
|
46
46
|
// Half the square in Mercator, at its latitude
|
|
47
|
-
const half = size / 2 / (EARTH_METRES * Math.cos(
|
|
47
|
+
const half = size / 2 / (EARTH_METRES * Math.cos(camera.center[1] * RAD));
|
|
48
48
|
const square = state.square;
|
|
49
49
|
// Off street level: no square (its particles gone, asked for again back at street level)
|
|
50
50
|
if (camera.zoom < minZoom) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"street-wind.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/street-wind.ts"],"names":[],"mappings":"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","sourcesContent":["/** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */\n\nimport type { StreetFlows } from '../../grid-module.ts';\nimport type { FlowField, FlowLayer, FlowOptions } from '../../layers/flow.ts';\nimport { EARTH_METRES, latitude, longitude, mercatorX, mercatorY } from '../../util/geo.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { isBuildings, isPolygonLayer } from './style.ts';\nimport { STREET_ZOOM } from './tiles.ts';\n\n/** Pause before the first square that failed is asked for again (ms) */\nconst RETRY_FIRST_MS = 1000;\n\n/** Longest pause before a square that failed again and again is asked for again (ms) */\nconst RETRY_MAX_MS = 30_000;\n\n/** The options of `VectorTiles.streetWind` */\nexport type StreetWindOptions = Omit<FlowOptions, 'field' | 'fields' | 'time'> & {\n wind?: [u: number, v: number];\n size?: number;\n cell?: number;\n iterations?: number;\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n};\n\n/** The layer of `VectorTiles.streetWind` */\nexport type StreetWindLayer = FlowLayer & { setWind(wind: [u: number, v: number]): void; computed: Promise<void> };\n\nexport const streetWind = (context: VectorTilesContext, options: StreetWindOptions = {}): StreetWindLayer => {\n const { map } = context;\n const { size = 1200, cell = 4, iterations = 300, layers = isBuildings, minZoom = STREET_ZOOM, ...flow } = options;\n const renderer = context.renderer(isPolygonLayer(layers), []);\n /** No square: a field of no value at the view's center, where no particle is born nor moves (the map idles) */\n const empty = (): FlowField => {\n const [lon, lat] = map.getCamera().center;\n\n return {\n width: 2,\n height: 2,\n u: [NaN, NaN, NaN, NaN],\n v: [NaN, NaN, NaN, NaN],\n bounds: [lon, lat, lon + 1e-4, lat + 1e-4],\n };\n };\n const layer = map.addFlow({ height: 3, ...flow, field: empty() });\n const state: {\n wind: [number, number];\n /** The square solved (Mercator: west, north, east, south), its grid, the flows of its basis */\n square?: [number, number, number, number] | undefined;\n grid?: { width: number; height: number; bounds: [number, number, number, number] };\n flows?: StreetFlows | undefined;\n /** Bumped by each square asked for: only the last one's answer is taken */\n asked: number;\n /** After a failure, the square asked for again in `wait` ms (doubled each time) */\n retry?: number;\n wait: number;\n } = { wind: options.wind ?? [3, 2], asked: 0, wait: RETRY_FIRST_MS };\n /** The flow of the wind far away: `u` times the flow towards the east plus `v` times the one towards the north,\n * mixed by the engine (the two flows sent once a square, a new wind two numbers) */\n const send = () => {\n const { flows, grid, wind } = state;\n\n if (!flows || !grid) return;\n layer.setBasis({ ...grid, u: flows.eastU, v: flows.eastV }, { ...grid, u: flows.northU, v: flows.northV }, wind);\n };\n /** The square asked for, its only request (under `square`) */\n const requests = new TileRequests();\n const first: { resolve?: () => void } = {};\n const computed = new Promise<void>((resolve) => {\n first.resolve = resolve;\n });\n const update = async () => {\n if (context.destroyed()) return;\n\n const camera = map.getCamera();\n const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];\n // Half the square in Mercator, at its latitude\n const half = size / 2 / (EARTH_METRES * Math.cos((camera.center[1] * Math.PI) / 180));\n const square = state.square;\n\n // Off street level: no square (its particles gone, asked for again back at street level)\n if (camera.zoom < minZoom) {\n if (state.square) {\n state.asked++;\n state.square = undefined;\n state.flows = undefined;\n requests.abortAll();\n layer.setField(empty());\n }\n\n return;\n }\n // Still in the square's middle: nothing to compute\n if (\n square &&\n Math.abs(x - (square[0] + square[2]) / 2) < half / 3 &&\n Math.abs(y - (square[1] + square[3]) / 2) < half / 3\n ) {\n return;\n }\n\n const { key, maxzoom } = await renderer;\n const bounds: [number, number, number, number] = [x - half, y - half, x + half, y + half];\n const n = 2 ** maxzoom;\n const tiles: number[] = [];\n\n for (let ty = Math.floor(bounds[1] * n); ty <= Math.floor(bounds[3] * n); ty++) {\n for (let tx = Math.floor(bounds[0] * n); tx <= Math.floor(bounds[2] * n); tx++) tiles.push(tx, ty);\n }\n\n const sides = Math.max(8, Math.round(size / cell));\n const work: BasemapWork = {\n type: 'street',\n key,\n module: map.gridUrl,\n z: maxzoom,\n tiles,\n bounds,\n width: sides,\n height: sides,\n iterations,\n };\n const asked = ++state.asked;\n\n requests.abortAll();\n\n const signal = requests.start('square');\n\n state.square = bounds;\n\n const answer = await context\n .request(maxzoom, Math.floor(x * n), Math.floor(y * n), work, signal)\n .catch((error: unknown) => ({ error }));\n\n if (asked !== state.asked || signal.aborted) return;\n // Failed (a tile or the grid module not fetched, a worker of an older build): the square asked for again later,\n // a while after each failure\n if (!('street' in answer)) {\n console.warn(\"isard: the streets' wind not computed, tried again\", 'error' in answer ? answer.error : answer);\n state.square = undefined;\n clearTimeout(state.retry);\n state.retry = window.setTimeout(() => {\n update().catch(() => undefined);\n }, state.wait);\n state.wait = Math.min(state.wait * 2, RETRY_MAX_MS);\n\n return;\n }\n state.wait = RETRY_FIRST_MS;\n state.flows = answer.street;\n state.grid = {\n width: sides,\n height: sides,\n bounds: [longitude(bounds[0]), latitude(bounds[3]), longitude(bounds[2]), latitude(bounds[1])],\n };\n send();\n first.resolve?.();\n };\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n context.followView(layer, update, requests, () => undefined);\n context.stopWith(layer, () => {\n clearTimeout(state.retry);\n });\n\n return Object.assign(layer, {\n computed,\n setWind: (wind: [u: number, v: number]) => {\n state.wind = wind;\n layer.setWeights(wind);\n },\n });\n};\n"]}
|
|
1
|
+
{"version":3,"file":"street-wind.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/street-wind.ts"],"names":[],"mappings":"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","sourcesContent":["/** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */\n\nimport type { StreetFlows } from '../../grid-module.ts';\nimport type { FlowField, FlowLayer, FlowOptions } from '../../layers/flow.ts';\nimport { EARTH_METRES, latitude, longitude, mercatorX, mercatorY, RAD } from '../../util/geo.ts';\nimport type { BasemapWork } from '../../workers/basemap/protocol.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { isBuildings, isPolygonLayer } from './style.ts';\nimport { STREET_ZOOM } from './tiles.ts';\n\n/** Pause before the first square that failed is asked for again (ms) */\nconst RETRY_FIRST_MS = 1000;\n\n/** Longest pause before a square that failed again and again is asked for again (ms) */\nconst RETRY_MAX_MS = 30_000;\n\n/** The options of `VectorTiles.streetWind` */\nexport type StreetWindOptions = Omit<FlowOptions, 'field' | 'fields' | 'time'> & {\n wind?: [u: number, v: number];\n size?: number;\n cell?: number;\n iterations?: number;\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n};\n\n/** The layer of `VectorTiles.streetWind` */\nexport type StreetWindLayer = FlowLayer & { setWind(wind: [u: number, v: number]): void; computed: Promise<void> };\n\nexport const streetWind = (context: VectorTilesContext, options: StreetWindOptions = {}): StreetWindLayer => {\n const { map } = context;\n const { size = 1200, cell = 4, iterations = 300, layers = isBuildings, minZoom = STREET_ZOOM, ...flow } = options;\n const renderer = context.renderer(isPolygonLayer(layers), []);\n /** No square: a field of no value at the view's center, where no particle is born nor moves (the map idles) */\n const empty = (): FlowField => {\n const [lon, lat] = map.getCamera().center;\n\n return {\n width: 2,\n height: 2,\n u: [NaN, NaN, NaN, NaN],\n v: [NaN, NaN, NaN, NaN],\n bounds: [lon, lat, lon + 1e-4, lat + 1e-4],\n };\n };\n const layer = map.addFlow({ height: 3, ...flow, field: empty() });\n const state: {\n wind: [number, number];\n /** The square solved (Mercator: west, north, east, south), its grid, the flows of its basis */\n square?: [number, number, number, number] | undefined;\n grid?: { width: number; height: number; bounds: [number, number, number, number] };\n flows?: StreetFlows | undefined;\n /** Bumped by each square asked for: only the last one's answer is taken */\n asked: number;\n /** After a failure, the square asked for again in `wait` ms (doubled each time) */\n retry?: number;\n wait: number;\n } = { wind: options.wind ?? [3, 2], asked: 0, wait: RETRY_FIRST_MS };\n /** The flow of the wind far away: `u` times the flow towards the east plus `v` times the one towards the north,\n * mixed by the engine (the two flows sent once a square, a new wind two numbers) */\n const send = () => {\n const { flows, grid, wind } = state;\n\n if (!flows || !grid) return;\n layer.setBasis({ ...grid, u: flows.eastU, v: flows.eastV }, { ...grid, u: flows.northU, v: flows.northV }, wind);\n };\n /** The square asked for, its only request (under `square`) */\n const requests = new TileRequests();\n const first: { resolve?: () => void } = {};\n const computed = new Promise<void>((resolve) => {\n first.resolve = resolve;\n });\n const update = async () => {\n if (context.destroyed()) return;\n\n const camera = map.getCamera();\n const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];\n // Half the square in Mercator, at its latitude\n const half = size / 2 / (EARTH_METRES * Math.cos(camera.center[1] * RAD));\n const square = state.square;\n\n // Off street level: no square (its particles gone, asked for again back at street level)\n if (camera.zoom < minZoom) {\n if (state.square) {\n state.asked++;\n state.square = undefined;\n state.flows = undefined;\n requests.abortAll();\n layer.setField(empty());\n }\n\n return;\n }\n // Still in the square's middle: nothing to compute\n if (\n square &&\n Math.abs(x - (square[0] + square[2]) / 2) < half / 3 &&\n Math.abs(y - (square[1] + square[3]) / 2) < half / 3\n ) {\n return;\n }\n\n const { key, maxzoom } = await renderer;\n const bounds: [number, number, number, number] = [x - half, y - half, x + half, y + half];\n const n = 2 ** maxzoom;\n const tiles: number[] = [];\n\n for (let ty = Math.floor(bounds[1] * n); ty <= Math.floor(bounds[3] * n); ty++) {\n for (let tx = Math.floor(bounds[0] * n); tx <= Math.floor(bounds[2] * n); tx++) tiles.push(tx, ty);\n }\n\n const sides = Math.max(8, Math.round(size / cell));\n const work: BasemapWork = {\n type: 'street',\n key,\n module: map.gridUrl,\n z: maxzoom,\n tiles,\n bounds,\n width: sides,\n height: sides,\n iterations,\n };\n const asked = ++state.asked;\n\n requests.abortAll();\n\n const signal = requests.start('square');\n\n state.square = bounds;\n\n const answer = await context\n .request(maxzoom, Math.floor(x * n), Math.floor(y * n), work, signal)\n .catch((error: unknown) => ({ error }));\n\n if (asked !== state.asked || signal.aborted) return;\n // Failed (a tile or the grid module not fetched, a worker of an older build): the square asked for again later,\n // a while after each failure\n if (!('street' in answer)) {\n console.warn(\"isard: the streets' wind not computed, tried again\", 'error' in answer ? answer.error : answer);\n state.square = undefined;\n clearTimeout(state.retry);\n state.retry = window.setTimeout(() => {\n update().catch(() => undefined);\n }, state.wait);\n state.wait = Math.min(state.wait * 2, RETRY_MAX_MS);\n\n return;\n }\n state.wait = RETRY_FIRST_MS;\n state.flows = answer.street;\n state.grid = {\n width: sides,\n height: sides,\n bounds: [longitude(bounds[0]), latitude(bounds[3]), longitude(bounds[2]), latitude(bounds[1])],\n };\n send();\n first.resolve?.();\n };\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n context.followView(layer, update, requests, () => undefined);\n context.stopWith(layer, () => {\n clearTimeout(state.retry);\n });\n\n return Object.assign(layer, {\n computed,\n setWind: (wind: [u: number, v: number]) => {\n state.wind = wind;\n layer.setWeights(wind);\n },\n });\n};\n"]}
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* source resolved (a TileJSON, a PMTiles archive) and its raster sources, the fonts of its labels, the style layers
|
|
4
4
|
* of buildings.
|
|
5
5
|
*/
|
|
6
|
-
import { withHeaders } from "../../engine/requests.js";
|
|
7
6
|
import { IGN_ATTRIBUTION } from "../../geoplateforme.js";
|
|
7
|
+
import { fetchOk } from "../../util/fetch.js";
|
|
8
8
|
import { isRecord } from "../../util/guards.js";
|
|
9
|
+
import { withHeaders } from "../../util/requests.js";
|
|
9
10
|
import { OPENFREEMAP_ATTRIBUTION } from "../basemaps.js";
|
|
10
11
|
import { pmtiles, pmtilesUrl } from "../pmtiles.js";
|
|
11
12
|
import { isStyle, labelFont } from "../vectorstyle.js";
|
|
@@ -49,16 +50,14 @@ const DEFAULT_RASTER_MAXZOOM = 22;
|
|
|
49
50
|
const DEFAULT_RASTER_TILE_SIZE = 512;
|
|
50
51
|
/** Fetches a JSON document (a style, a TileJSON) */
|
|
51
52
|
const json = async (url) => {
|
|
52
|
-
const response = await
|
|
53
|
-
if (!response.ok)
|
|
54
|
-
throw new Error(`${url}: ${response.status}`);
|
|
53
|
+
const response = await fetchOk(url, withHeaders(url));
|
|
55
54
|
return response.json();
|
|
56
55
|
};
|
|
57
56
|
/** A style fetched: a MapLibre style, or an error */
|
|
58
57
|
const fetchStyle = async (url) => {
|
|
59
58
|
const style = await json(url);
|
|
60
59
|
if (!isStyle(style))
|
|
61
|
-
throw new Error(
|
|
60
|
+
throw new Error(`isard: ${url}: not a MapLibre style`);
|
|
62
61
|
return style;
|
|
63
62
|
};
|
|
64
63
|
const isTileJson = (value) => isRecord(value) &&
|
|
@@ -69,7 +68,7 @@ const isTileJson = (value) => isRecord(value) &&
|
|
|
69
68
|
const fetchTileJson = async (url) => {
|
|
70
69
|
const tilejson = await json(url);
|
|
71
70
|
if (!isTileJson(tilejson))
|
|
72
|
-
throw new Error(
|
|
71
|
+
throw new Error(`isard: ${url}: not a TileJSON`);
|
|
73
72
|
return tilejson;
|
|
74
73
|
};
|
|
75
74
|
/**
|
|
@@ -92,14 +91,14 @@ export const loadStyle = async (input) => {
|
|
|
92
91
|
const style = typeof input === 'string' ? await fetchStyle(input) : input;
|
|
93
92
|
const [name, source] = Object.entries(style.sources).find(([, s]) => s.type === 'vector') ?? [];
|
|
94
93
|
if (!name || !source)
|
|
95
|
-
throw new Error('the style has no vector source');
|
|
94
|
+
throw new Error('isard: the style has no vector source');
|
|
96
95
|
const resolved = await resolveSource(source);
|
|
97
96
|
const tilejson = !resolved.tiles && source.url ? await fetchTileJson(source.url) : undefined;
|
|
98
97
|
const tiles = tilejson === undefined ? resolved.tiles : tilejson.tiles;
|
|
99
98
|
const maxzoom = resolved.maxzoom ?? tilejson?.maxzoom;
|
|
100
99
|
const template = tiles?.[0];
|
|
101
100
|
if (!template)
|
|
102
|
-
throw new Error(`source ${name} has no tiles`);
|
|
101
|
+
throw new Error(`isard: the source ${name} has no tiles`);
|
|
103
102
|
// Its raster sources of tiles, drawn into the same images (the shaded relief of a style at low zoom)
|
|
104
103
|
const rasters = {};
|
|
105
104
|
for (const [key, s] of Object.entries(style.sources)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/style.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The styles of the vector basemaps (`VectorTiles`): the known ones and their credits, a style loaded with its vector\n * source resolved (a TileJSON, a PMTiles archive) and its raster sources, the fonts of its labels, the style layers\n * of buildings.\n */\n\nimport { withHeaders } from '../../engine/requests.ts';\nimport { IGN_ATTRIBUTION } from '../../geoplateforme.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { OPENFREEMAP_ATTRIBUTION } from '../basemaps.ts';\nimport { pmtiles, pmtilesUrl } from '../pmtiles.ts';\nimport { isStyle, labelFont, type RasterSource, type Style, type StyleLayer } from '../vectorstyle.ts';\n\n/** OpenFreeMap's styles: OpenStreetMap data in the OpenMapTiles schema, worldwide, free and without a key */\nexport const OPENFREEMAP_STYLES = {\n positron: 'https://tiles.openfreemap.org/styles/positron',\n liberty: 'https://tiles.openfreemap.org/styles/liberty',\n bright: 'https://tiles.openfreemap.org/styles/bright',\n dark: 'https://tiles.openfreemap.org/styles/dark',\n fiord: 'https://tiles.openfreemap.org/styles/fiord',\n} as const;\n\n/** PLAN.IGN vector styles of the Géoplateforme (France) */\nexport const PLAN_STYLES = {\n standard: 'https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json',\n grey: 'https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/gris.json',\n} as const;\n\n/** Vector basemaps by name (see `BasemapName`) */\nexport const VECTOR_BASEMAPS = {\n 'osm-positron': OPENFREEMAP_STYLES.positron,\n 'osm-liberty': OPENFREEMAP_STYLES.liberty,\n 'osm-bright': OPENFREEMAP_STYLES.bright,\n 'osm-dark': OPENFREEMAP_STYLES.dark,\n 'ign-plan-vector': PLAN_STYLES.standard,\n 'ign-plan-grey-vector': PLAN_STYLES.grey,\n} as const;\n\n/** The credits of a known style: OpenFreeMap's, PLAN.IGN's */\nexport const styleAttribution = (style: string | Style): string | undefined => {\n if (typeof style !== 'string') return undefined;\n if (Object.values(OPENFREEMAP_STYLES).some((s) => s === style)) return OPENFREEMAP_ATTRIBUTION;\n if (Object.values(PLAN_STYLES).some((s) => s === style)) return IGN_ATTRIBUTION;\n\n return undefined;\n};\n\n/** Deepest level of a vector source that does not give its own */\nconst DEFAULT_MAXZOOM = 14;\n\n/** Deepest level of a raster source that does not give its own */\nconst DEFAULT_RASTER_MAXZOOM = 22;\n\n/** Tile size of a raster source that does not give its own (pixels) */\nconst DEFAULT_RASTER_TILE_SIZE = 512;\n\n/** A style loaded: its layers of its vector source (and of its raster sources), the source's tiles and deepest level */\nexport interface LoadedStyle {\n style: Style;\n tiles: string;\n maxzoom: number;\n rasters: Record<string, RasterSource>;\n}\n\n/** Fetches a JSON document (a style, a TileJSON) */\nconst json = async (url: string): Promise<unknown> => {\n const response = await fetch(url, withHeaders(url));\n\n if (!response.ok) throw new Error(`${url}: ${response.status}`);\n\n return response.json();\n};\n\n/** A style fetched: a MapLibre style, or an error */\nconst fetchStyle = async (url: string): Promise<Style> => {\n const style = await json(url);\n\n if (!isStyle(style)) throw new Error(`${url}: not a MapLibre style`);\n\n return style;\n};\n\n/** What a basemap reads of a TileJSON */\ninterface TileJson {\n tiles: string[];\n maxzoom?: number;\n}\n\nconst isTileJson = (value: unknown): value is TileJson =>\n isRecord(value) &&\n Array.isArray(value.tiles) &&\n value.tiles.every((t) => typeof t === 'string') &&\n (value.maxzoom === undefined || typeof value.maxzoom === 'number');\n\n/** A TileJSON fetched, or an error */\nconst fetchTileJson = async (url: string): Promise<TileJson> => {\n const tilejson = await json(url);\n\n if (!isTileJson(tilejson)) throw new Error(`${url}: not a TileJSON`);\n\n return tilejson;\n};\n\n/**\n * A style source's tiles and deepest level: a `pmtiles://` archive (its `url`, or a `tiles` template) read for its\n * header, its tiles then named `pmtiles://<absolute archive URL>/{z}/{x}/{y}` for the workers; other sources as they are\n */\nconst resolveSource = async (source: Style['sources'][string]): Promise<{ tiles?: string[]; maxzoom?: number }> => {\n const given = source.url ?? source.tiles?.[0] ?? '';\n const archive = pmtilesUrl(given.replace(/\\/\\{z\\}\\/\\{x\\}\\/\\{y\\}$/, ''));\n\n if (!archive)\n return {\n ...(source.tiles ? { tiles: source.tiles } : {}),\n ...(source.maxzoom === undefined ? {} : { maxzoom: source.maxzoom }),\n };\n\n const header = await pmtiles(archive).header();\n\n return { tiles: [`pmtiles://${archive}/{z}/{x}/{y}`], maxzoom: source.maxzoom ?? header.maxZoom };\n};\n\n/** A style (its URL, or the style itself) loaded, with its first vector source resolved and its raster sources */\nexport const loadStyle = async (input: string | Style): Promise<LoadedStyle> => {\n const style = typeof input === 'string' ? await fetchStyle(input) : input;\n const [name, source] = Object.entries(style.sources).find(([, s]) => s.type === 'vector') ?? [];\n\n if (!name || !source) throw new Error('the style has no vector source');\n\n const resolved = await resolveSource(source);\n const tilejson = !resolved.tiles && source.url ? await fetchTileJson(source.url) : undefined;\n const tiles = tilejson === undefined ? resolved.tiles : tilejson.tiles;\n const maxzoom = resolved.maxzoom ?? tilejson?.maxzoom;\n const template = tiles?.[0];\n\n if (!template) throw new Error(`source ${name} has no tiles`);\n\n // Its raster sources of tiles, drawn into the same images (the shaded relief of a style at low zoom)\n const rasters: Record<string, RasterSource> = {};\n\n for (const [key, s] of Object.entries(style.sources)) {\n if (s.type !== 'raster') continue;\n\n const r = await resolveSource(s);\n const url = r.tiles?.[0];\n\n if (url) {\n rasters[key] = {\n tiles: url,\n maxzoom: r.maxzoom ?? DEFAULT_RASTER_MAXZOOM,\n tileSize: s.tileSize ?? DEFAULT_RASTER_TILE_SIZE,\n };\n }\n }\n\n // Only the layers of those sources (and the background); other types (hillshade, heatmap…) are left out. The\n // application's style object stays as it is\n const layers = style.layers.filter(\n (l) =>\n l.type === 'background' ||\n (l.source === name && l.type !== 'raster') ||\n (l.type === 'raster' && l.source !== undefined && rasters[l.source] !== undefined),\n );\n\n return { style: { ...style, layers }, tiles: template, maxzoom: maxzoom ?? DEFAULT_MAXZOOM, rasters };\n};\n\n/** The fonts of the style's labels, for its glyphs (the first of each `text-font`, as the workers take it) */\nexport const styleFonts = (style: Style): string[] => {\n const fonts = new Set<string>();\n\n style.layers.forEach((layer) => {\n const font = layer.layout?.['text-font'];\n\n if (layer.type === 'symbol' && Array.isArray(font) && typeof font[0] === 'string') fonts.add(labelFont(font[0]));\n });\n\n return [...fonts];\n};\n\n/** The style layers of buildings, by default: PLAN IGN's `bati_surf` (not its built-up areas nor its parks), the\n * OpenMapTiles' `building` */\nexport const isBuildings = (layer: StyleLayer): boolean =>\n ['bati_surf', 'building'].includes(layer['source-layer'] ?? '');\n\n/** Whether a style layer is a fill (or fill-extrusion) layer that `layers` keeps: the polygons extruded or flowed\n * round */\nexport const isPolygonLayer =\n (layers: (layer: StyleLayer) => boolean) =>\n (layer: StyleLayer): boolean =>\n (layer.type === 'fill' || layer.type === 'fill-extrusion') && layers(layer);\n"]}
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/style.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The styles of the vector basemaps (`VectorTiles`): the known ones and their credits, a style loaded with its vector\n * source resolved (a TileJSON, a PMTiles archive) and its raster sources, the fonts of its labels, the style layers\n * of buildings.\n */\n\nimport { IGN_ATTRIBUTION } from '../../geoplateforme.ts';\nimport { fetchOk } from '../../util/fetch.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { withHeaders } from '../../util/requests.ts';\nimport { OPENFREEMAP_ATTRIBUTION } from '../basemaps.ts';\nimport { pmtiles, pmtilesUrl } from '../pmtiles.ts';\nimport { isStyle, labelFont, type RasterSource, type Style, type StyleLayer } from '../vectorstyle.ts';\n\n/** OpenFreeMap's styles: OpenStreetMap data in the OpenMapTiles schema, worldwide, free and without a key */\nexport const OPENFREEMAP_STYLES = {\n positron: 'https://tiles.openfreemap.org/styles/positron',\n liberty: 'https://tiles.openfreemap.org/styles/liberty',\n bright: 'https://tiles.openfreemap.org/styles/bright',\n dark: 'https://tiles.openfreemap.org/styles/dark',\n fiord: 'https://tiles.openfreemap.org/styles/fiord',\n} as const;\n\n/** PLAN.IGN vector styles of the Géoplateforme (France) */\nexport const PLAN_STYLES = {\n standard: 'https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/standard.json',\n grey: 'https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/gris.json',\n} as const;\n\n/** Vector basemaps by name (see `BasemapName`) */\nexport const VECTOR_BASEMAPS = {\n 'osm-positron': OPENFREEMAP_STYLES.positron,\n 'osm-liberty': OPENFREEMAP_STYLES.liberty,\n 'osm-bright': OPENFREEMAP_STYLES.bright,\n 'osm-dark': OPENFREEMAP_STYLES.dark,\n 'ign-plan-vector': PLAN_STYLES.standard,\n 'ign-plan-grey-vector': PLAN_STYLES.grey,\n} as const;\n\n/** The credits of a known style: OpenFreeMap's, PLAN.IGN's */\nexport const styleAttribution = (style: string | Style): string | undefined => {\n if (typeof style !== 'string') return undefined;\n if (Object.values(OPENFREEMAP_STYLES).some((s) => s === style)) return OPENFREEMAP_ATTRIBUTION;\n if (Object.values(PLAN_STYLES).some((s) => s === style)) return IGN_ATTRIBUTION;\n\n return undefined;\n};\n\n/** Deepest level of a vector source that does not give its own */\nconst DEFAULT_MAXZOOM = 14;\n\n/** Deepest level of a raster source that does not give its own */\nconst DEFAULT_RASTER_MAXZOOM = 22;\n\n/** Tile size of a raster source that does not give its own (pixels) */\nconst DEFAULT_RASTER_TILE_SIZE = 512;\n\n/** A style loaded: its layers of its vector source (and of its raster sources), the source's tiles and deepest level */\nexport interface LoadedStyle {\n style: Style;\n tiles: string;\n maxzoom: number;\n rasters: Record<string, RasterSource>;\n}\n\n/** Fetches a JSON document (a style, a TileJSON) */\nconst json = async (url: string): Promise<unknown> => {\n const response = await fetchOk(url, withHeaders(url));\n\n return response.json();\n};\n\n/** A style fetched: a MapLibre style, or an error */\nconst fetchStyle = async (url: string): Promise<Style> => {\n const style = await json(url);\n\n if (!isStyle(style)) throw new Error(`isard: ${url}: not a MapLibre style`);\n\n return style;\n};\n\n/** What a basemap reads of a TileJSON */\ninterface TileJson {\n tiles: string[];\n maxzoom?: number;\n}\n\nconst isTileJson = (value: unknown): value is TileJson =>\n isRecord(value) &&\n Array.isArray(value.tiles) &&\n value.tiles.every((t) => typeof t === 'string') &&\n (value.maxzoom === undefined || typeof value.maxzoom === 'number');\n\n/** A TileJSON fetched, or an error */\nconst fetchTileJson = async (url: string): Promise<TileJson> => {\n const tilejson = await json(url);\n\n if (!isTileJson(tilejson)) throw new Error(`isard: ${url}: not a TileJSON`);\n\n return tilejson;\n};\n\n/**\n * A style source's tiles and deepest level: a `pmtiles://` archive (its `url`, or a `tiles` template) read for its\n * header, its tiles then named `pmtiles://<absolute archive URL>/{z}/{x}/{y}` for the workers; other sources as they are\n */\nconst resolveSource = async (source: Style['sources'][string]): Promise<{ tiles?: string[]; maxzoom?: number }> => {\n const given = source.url ?? source.tiles?.[0] ?? '';\n const archive = pmtilesUrl(given.replace(/\\/\\{z\\}\\/\\{x\\}\\/\\{y\\}$/, ''));\n\n if (!archive)\n return {\n ...(source.tiles ? { tiles: source.tiles } : {}),\n ...(source.maxzoom === undefined ? {} : { maxzoom: source.maxzoom }),\n };\n\n const header = await pmtiles(archive).header();\n\n return { tiles: [`pmtiles://${archive}/{z}/{x}/{y}`], maxzoom: source.maxzoom ?? header.maxZoom };\n};\n\n/** A style (its URL, or the style itself) loaded, with its first vector source resolved and its raster sources */\nexport const loadStyle = async (input: string | Style): Promise<LoadedStyle> => {\n const style = typeof input === 'string' ? await fetchStyle(input) : input;\n const [name, source] = Object.entries(style.sources).find(([, s]) => s.type === 'vector') ?? [];\n\n if (!name || !source) throw new Error('isard: the style has no vector source');\n\n const resolved = await resolveSource(source);\n const tilejson = !resolved.tiles && source.url ? await fetchTileJson(source.url) : undefined;\n const tiles = tilejson === undefined ? resolved.tiles : tilejson.tiles;\n const maxzoom = resolved.maxzoom ?? tilejson?.maxzoom;\n const template = tiles?.[0];\n\n if (!template) throw new Error(`isard: the source ${name} has no tiles`);\n\n // Its raster sources of tiles, drawn into the same images (the shaded relief of a style at low zoom)\n const rasters: Record<string, RasterSource> = {};\n\n for (const [key, s] of Object.entries(style.sources)) {\n if (s.type !== 'raster') continue;\n\n const r = await resolveSource(s);\n const url = r.tiles?.[0];\n\n if (url) {\n rasters[key] = {\n tiles: url,\n maxzoom: r.maxzoom ?? DEFAULT_RASTER_MAXZOOM,\n tileSize: s.tileSize ?? DEFAULT_RASTER_TILE_SIZE,\n };\n }\n }\n\n // Only the layers of those sources (and the background); other types (hillshade, heatmap…) are left out. The\n // application's style object stays as it is\n const layers = style.layers.filter(\n (l) =>\n l.type === 'background' ||\n (l.source === name && l.type !== 'raster') ||\n (l.type === 'raster' && l.source !== undefined && rasters[l.source] !== undefined),\n );\n\n return { style: { ...style, layers }, tiles: template, maxzoom: maxzoom ?? DEFAULT_MAXZOOM, rasters };\n};\n\n/** The fonts of the style's labels, for its glyphs (the first of each `text-font`, as the workers take it) */\nexport const styleFonts = (style: Style): string[] => {\n const fonts = new Set<string>();\n\n style.layers.forEach((layer) => {\n const font = layer.layout?.['text-font'];\n\n if (layer.type === 'symbol' && Array.isArray(font) && typeof font[0] === 'string') fonts.add(labelFont(font[0]));\n });\n\n return [...fonts];\n};\n\n/** The style layers of buildings, by default: PLAN IGN's `bati_surf` (not its built-up areas nor its parks), the\n * OpenMapTiles' `building` */\nexport const isBuildings = (layer: StyleLayer): boolean =>\n ['bati_surf', 'building'].includes(layer['source-layer'] ?? '');\n\n/** Whether a style layer is a fill (or fill-extrusion) layer that `layers` keeps: the polygons extruded or flowed\n * round */\nexport const isPolygonLayer =\n (layers: (layer: StyleLayer) => boolean) =>\n (layer: StyleLayer): boolean =>\n (layer.type === 'fill' || layer.type === 'fill-extrusion') && layers(layer);\n"]}
|
|
@@ -4,15 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { GeoMap } from '../../map.ts';
|
|
6
6
|
import type { Camera } from '../../wasm/isard.js';
|
|
7
|
-
import type { Priority } from '../../workers/basemap.
|
|
7
|
+
import type { Priority } from '../../workers/basemap/protocol.ts';
|
|
8
8
|
/** A tile: its level and its column and row at that level */
|
|
9
9
|
export type TileTriple = [z: number, x: number, y: number];
|
|
10
10
|
/** Street level: the zoom the extrusions, the streets' wind and the trees start at by default */
|
|
11
11
|
export declare const STREET_ZOOM = 15;
|
|
12
12
|
/** Tiles of a layer that follows the view, by default (the extrusions', the labels') */
|
|
13
13
|
export declare const MAX_TILES = 36;
|
|
14
|
-
/** Tiles nearest to the center asked for first: the others wait (for the raster tiles, for instance) */
|
|
15
|
-
export declare const NEAR_TILES = 4;
|
|
16
14
|
/** Milliseconds between two updates of the tiles of a layer while the camera moves */
|
|
17
15
|
export declare const VECTOR_MOVE_REFRESH_MS = 250;
|
|
18
16
|
/** A tile's key, `z/x/y` */
|
|
@@ -8,7 +8,7 @@ export const STREET_ZOOM = 15;
|
|
|
8
8
|
/** Tiles of a layer that follows the view, by default (the extrusions', the labels') */
|
|
9
9
|
export const MAX_TILES = 36;
|
|
10
10
|
/** Tiles nearest to the center asked for first: the others wait (for the raster tiles, for instance) */
|
|
11
|
-
|
|
11
|
+
const NEAR_TILES = 4;
|
|
12
12
|
/** Milliseconds between two updates of the tiles of a layer while the camera moves */
|
|
13
13
|
export const VECTOR_MOVE_REFRESH_MS = 250;
|
|
14
14
|
/** A tile's key, `z/x/y` */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tiles.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/tiles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOzD,iGAAiG;AACjG,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE9B,wFAAwF;AACxF,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAE5B,wGAAwG;AACxG,MAAM,
|
|
1
|
+
{"version":3,"file":"tiles.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/tiles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tiles of the vector layers (`VectorTiles`): the tiles around the view, their keys, the order they are asked\n * for in, and the defaults the layers share.\n */\n\nimport type { GeoMap } from '../../map.ts';\nimport { mercatorX, mercatorY } from '../../util/geo.ts';\nimport type { Camera } from '../../wasm/isard.js';\nimport type { Priority } from '../../workers/basemap/protocol.ts';\n\n/** A tile: its level and its column and row at that level */\nexport type TileTriple = [z: number, x: number, y: number];\n\n/** Street level: the zoom the extrusions, the streets' wind and the trees start at by default */\nexport const STREET_ZOOM = 15;\n\n/** Tiles of a layer that follows the view, by default (the extrusions', the labels') */\nexport const MAX_TILES = 36;\n\n/** Tiles nearest to the center asked for first: the others wait (for the raster tiles, for instance) */\nconst NEAR_TILES = 4;\n\n/** Milliseconds between two updates of the tiles of a layer while the camera moves */\nexport const VECTOR_MOVE_REFRESH_MS = 250;\n\n/** A tile's key, `z/x/y` */\nexport const tileKey = (z: number, x: number, y: number): string => `${z}/${x}/${y}`;\n\n/** The tile of a key `z/x/y` (zeros for the numbers it lacks) */\nexport const parseTileKey = (key: string): TileTriple => {\n const [z = 0, x = 0, y = 0] = key.split('/').map(Number);\n\n return [z, x, y];\n};\n\n/** The tiles of the engine's flat list of z, x, y triples */\nexport const tileTriples = (list: Uint32Array): TileTriple[] =>\n Array.from(\n { length: Math.floor(list.length / 3) },\n (_, i): TileTriple => [list[i * 3] ?? 0, list[i * 3 + 1] ?? 0, list[i * 3 + 2] ?? 0],\n );\n\n/** The priority of the `index`th tile asked for, the nearest first: `near` for the first `NEAR_TILES`, `far` after */\nexport const nearPriority = (index: number, near: Priority = 'auto', far: Priority = 'low'): Priority =>\n index < NEAR_TILES ? near : far;\n\n/** A tile's column at level `z` brought back into the world (the columns past the antimeridian are those of its other\n * side) */\nexport const wrapColumn = (x: number, z: number): number => {\n const n = 2 ** z;\n\n return ((x % n) + n) % n;\n};\n\n/**\n * The tiles of level `z` in view, within a window around the center (a tilted view's bounds reach far), the\n * `maxTiles` nearest to the center first. Across the antimeridian, the window's columns go on round the world (the\n * view's bounds, which stop at ±180°, no longer limit them)\n */\nexport const tilesAround = (map: GeoMap, camera: Camera, z: number, maxTiles: number): [x: number, y: number][] => {\n const n = 2 ** z;\n const [west, south, east, north] = map.getBounds();\n const tx = (lon: number) => Math.floor(mercatorX(lon) * n);\n const ty = (lat: number) => Math.floor(mercatorY(lat) * n);\n const [cx, cy] = [mercatorX(camera.center[0]) * n, mercatorY(camera.center[1]) * n];\n const reach = Math.ceil(Math.sqrt(maxTiles)) + 2;\n const [left, right] = [Math.floor(cx) - reach, Math.floor(cx) + reach];\n const across = left < 0 || right > n - 1;\n const [x0, x1] = across ? [left, right] : [Math.max(left, tx(west)), Math.min(right, tx(east))];\n const [y0, y1] = [Math.max(0, ty(north), Math.floor(cy) - reach), Math.min(n - 1, ty(south), Math.floor(cy) + reach)];\n const wanted = Array.from({ length: Math.max(0, y1 - y0 + 1) }, (_, j) => y0 + j).flatMap((y) =>\n Array.from({ length: Math.max(0, x1 - x0 + 1) }, (_, i): [number, number] => [x0 + i, y]),\n );\n\n wanted.sort((a, b) => Math.hypot(a[0] + 0.5 - cx, a[1] + 0.5 - cy) - Math.hypot(b[0] + 0.5 - cx, b[1] + 0.5 - cy));\n\n // Each tile once (at a low level, the window can go round the whole world)\n const seen = new Set<string>();\n\n return wanted\n .map(([x, y]): [number, number] => [wrapColumn(x, z), y])\n .filter(([x, y]) => {\n const k = `${x}/${y}`;\n\n if (seen.has(k)) return false;\n seen.add(k);\n\n return true;\n })\n .slice(0, maxTiles);\n};\n"]}
|