isard 0.2.1 → 0.4.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +8 -4
  3. package/dist/animation.d.ts +18 -0
  4. package/dist/animation.js +84 -0
  5. package/dist/animation.js.map +1 -0
  6. package/dist/basemap.worker.d.ts +26 -4
  7. package/dist/basemap.worker.js +2 -2
  8. package/dist/basemap.worker.js.map +9 -5
  9. package/dist/crs.d.ts +72 -0
  10. package/dist/crs.js +243 -0
  11. package/dist/crs.js.map +1 -0
  12. package/dist/decoder.worker.js +4 -4
  13. package/dist/decoder.worker.js.map +4 -4
  14. package/dist/engine-loader.d.ts +28 -0
  15. package/dist/engine-loader.js +112 -0
  16. package/dist/engine-loader.js.map +1 -0
  17. package/dist/features.d.ts +8 -0
  18. package/dist/features.js +17 -10
  19. package/dist/features.js.map +1 -1
  20. package/dist/geo.d.ts +16 -0
  21. package/dist/geo.js +32 -0
  22. package/dist/geo.js.map +1 -0
  23. package/dist/geoplateforme.d.ts +21 -5
  24. package/dist/geoplateforme.js +47 -12
  25. package/dist/geoplateforme.js.map +1 -1
  26. package/dist/glyphs.d.ts +13 -3
  27. package/dist/glyphs.js +26 -4
  28. package/dist/glyphs.js.map +1 -1
  29. package/dist/gpx.d.ts +11 -0
  30. package/dist/gpx.js +74 -0
  31. package/dist/gpx.js.map +1 -0
  32. package/dist/grid.d.ts +81 -0
  33. package/dist/grid.js +270 -0
  34. package/dist/grid.js.map +1 -0
  35. package/dist/icons.d.ts +146 -0
  36. package/dist/icons.js +333 -0
  37. package/dist/icons.js.map +1 -0
  38. package/dist/index.d.ts +11 -4
  39. package/dist/index.js +6 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/interaction.d.ts +0 -4
  42. package/dist/interaction.js +8 -4
  43. package/dist/interaction.js.map +1 -1
  44. package/dist/isard_bg.wasm +0 -0
  45. package/dist/isard_core_bg.wasm +0 -0
  46. package/dist/kml.d.ts +12 -0
  47. package/dist/kml.js +159 -0
  48. package/dist/kml.js.map +1 -0
  49. package/dist/layers.d.ts +89 -2
  50. package/dist/layers.js +171 -15
  51. package/dist/layers.js.map +1 -1
  52. package/dist/lru.d.ts +22 -0
  53. package/dist/lru.js +52 -0
  54. package/dist/lru.js.map +1 -0
  55. package/dist/map.d.ts +45 -7
  56. package/dist/map.js +138 -310
  57. package/dist/map.js.map +1 -1
  58. package/dist/resample.d.ts +41 -0
  59. package/dist/resample.js +164 -0
  60. package/dist/resample.js.map +1 -0
  61. package/dist/settings.d.ts +39 -0
  62. package/dist/settings.js +104 -0
  63. package/dist/settings.js.map +1 -0
  64. package/dist/symbols.d.ts +54 -9
  65. package/dist/symbols.js +278 -55
  66. package/dist/symbols.js.map +1 -1
  67. package/dist/terrain.d.ts +19 -7
  68. package/dist/terrain.js +40 -28
  69. package/dist/terrain.js.map +1 -1
  70. package/dist/topojson.d.ts +29 -0
  71. package/dist/topojson.js +66 -0
  72. package/dist/topojson.js.map +1 -0
  73. package/dist/types.d.ts +14 -6
  74. package/dist/types.js.map +1 -1
  75. package/dist/vectorstyle.d.ts +32 -3
  76. package/dist/vectorstyle.js.map +1 -1
  77. package/dist/vectortiles.d.ts +19 -7
  78. package/dist/vectortiles.js +117 -69
  79. package/dist/vectortiles.js.map +1 -1
  80. package/dist/wasm/isard.d.ts +55 -7
  81. package/dist/wasm/isard.js +117 -6
  82. package/dist/wasm/isard_core.d.ts +29 -4
  83. package/dist/wasm/isard_core.js +84 -5
  84. package/dist/wmts.d.ts +14 -0
  85. package/dist/wmts.js +76 -0
  86. package/dist/wmts.js.map +1 -0
  87. package/dist/xml.d.ts +26 -0
  88. package/dist/xml.js +109 -0
  89. package/dist/xml.js.map +1 -0
  90. package/package.json +1 -1
  91. package/dist/equirectangular.d.ts +0 -35
  92. package/dist/equirectangular.js +0 -143
  93. package/dist/equirectangular.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"interaction.js","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mouse, touch and keyboard controls. Every gesture only updates the camera and asks for a frame: the engine draws at most\n * once per display refresh, whatever the event rate of the device.\n */\nimport type { GeoMap } from './map.ts';\nimport type { Point } from './types.ts';\nimport type { Camera } from './wasm/isard.js';\n\n/** Zoom levels per wheel pixel (a mouse notch is about 100 px: 1/3 of a level) */\nconst WHEEL_RATE = 1 / 300;\n/** Share of the remaining wheel zoom applied per frame (smooth, about 150 ms to settle) */\nconst WHEEL_EASE = 0.3;\n/** Degrees per pixel when rotating or tilting with the mouse */\nconst ROTATE_RATE = 0.4;\n/** A press that moves less than this (CSS pixels) is a click */\nconst CLICK_TOLERANCE = 4;\n/** Pan speed kept on release, decaying with this time constant (ms) */\nconst INERTIA_DECAY = 280;\n\n/** CSS pixels per arrow key press */\nconst KEY_PAN = 100;\n/** Degrees per Shift + left or right arrow */\nconst KEY_BEARING = 15;\n/** Degrees per Shift + up or down arrow */\nconst KEY_PITCH = 10;\n/** Duration of the moves made by keys, milliseconds */\nconst KEY_DURATION = 300;\n\n/** What a key does to the camera: a pan in CSS pixels, a zoom, rotation or tilt step, or facing north */\nexport type KeyAction = { pan: Point } | { zoom: number } | { bearing: number } | { pitch: number } | { reset: true };\n\n/** The action of a key (`KeyboardEvent.key`), as MapLibre's: arrows pan (with Shift: rotate and tilt), + and - zoom\n * (with Shift: two levels), 0 faces north and levels the view */\nexport function keyAction(key: string, shift: boolean): KeyAction | undefined {\n switch (key) {\n case 'ArrowLeft':\n return shift ? { bearing: -KEY_BEARING } : { pan: [-KEY_PAN, 0] };\n case 'ArrowRight':\n return shift ? { bearing: KEY_BEARING } : { pan: [KEY_PAN, 0] };\n case 'ArrowUp':\n return shift ? { pitch: KEY_PITCH } : { pan: [0, -KEY_PAN] };\n case 'ArrowDown':\n return shift ? { pitch: -KEY_PITCH } : { pan: [0, KEY_PAN] };\n case '+':\n case '=':\n return { zoom: shift ? 2 : 1 };\n case '-':\n case '_':\n return { zoom: shift ? -2 : -1 };\n case '0':\n return { reset: true };\n default:\n return undefined;\n }\n}\n\n/** The camera after a key's action: a pan moves the center by that many CSS pixels on screen (the ground in view,\n * turned with the bearing, stretched by the tilt) */\nexport function keyCamera(action: KeyAction, camera: Camera): Partial<Camera> {\n if ('zoom' in action) return { zoom: camera.zoom + action.zoom };\n if ('bearing' in action) return { bearing: camera.bearing + action.bearing };\n if ('pitch' in action) return { pitch: Math.max(0, camera.pitch + action.pitch) };\n if ('reset' in action) return { bearing: 0, pitch: 0 };\n const b = (camera.bearing * Math.PI) / 180;\n const [sx, sy] = [action.pan[0], action.pan[1] / Math.max(0.25, Math.cos((camera.pitch * Math.PI) / 180))];\n // Web Mercator units (0 to 1 across the world, y down); the world is 512 CSS pixels at zoom 0\n const world = 512 * 2 ** camera.zoom;\n const dx = (sx * Math.cos(b) - sy * Math.sin(b)) / world;\n const dy = (sx * Math.sin(b) + sy * Math.cos(b)) / world;\n const [lon, lat] = camera.center;\n const phi = (Math.max(-85.0511, Math.min(85.0511, lat)) * Math.PI) / 180;\n const x = (lon + 180) / 360 + dx;\n const y = Math.max(0, Math.min(1, (1 - Math.log(Math.tan(phi) + 1 / Math.cos(phi)) / Math.PI) / 2 + dy));\n const wrapped = ((((x * 360) % 360) + 360) % 360) - 180;\n return { center: [wrapped, (Math.atan(Math.sinh(Math.PI * (1 - 2 * y))) * 180) / Math.PI] };\n}\n\n/** An element that takes the keys typed in it */\nfunction editable(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return target.isContentEditable || ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName);\n}\n\ninterface Pointer {\n point: Point;\n start: Point;\n button: number;\n rotate: boolean;\n}\n\nexport class Interaction {\n private readonly pointers = new Map<number, Pointer>();\n private readonly cleanup: (() => void)[] = [];\n private wheel = { pending: 0, at: [0, 0] as Point };\n /** Recent pan moves, for the release speed: [time, dx, dy] */\n private trail: [number, number, number][] = [];\n private moved = false;\n /** The canvas's place on the page, read once: reading it on every pointer move would force a layout each time.\n * Read again after a resize, a scroll, and when a pointer comes in or goes down */\n private rect: DOMRect | undefined;\n\n constructor(\n private readonly map: GeoMap,\n options: { keyboard?: boolean } = {},\n ) {\n const canvas = map.canvas;\n const listen = <K extends keyof HTMLElementEventMap>(\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => {\n canvas.addEventListener(type, handler, options);\n this.cleanup.push(() => canvas.removeEventListener(type, handler));\n };\n const moved = () => {\n this.rect = undefined;\n };\n listen('pointerenter', moved);\n // Scrolls of the page or of any element holding the map\n if (typeof addEventListener === 'function') {\n addEventListener('scroll', moved, { capture: true, passive: true });\n this.cleanup.push(() => removeEventListener('scroll', moved, { capture: true }));\n }\n this.cleanup.push(map.on('resize', moved));\n listen('pointerdown', (e) => {\n this.rect = undefined;\n this.down(e);\n });\n listen('pointermove', (e) => this.move(e));\n listen('pointerup', (e) => this.up(e));\n listen('pointercancel', (e) => this.up(e));\n listen('pointerleave', (e) => {\n if (e.pointerType !== 'mouse') return;\n map.hover(undefined);\n map.emit('leave', {});\n });\n // On the container, the wheel zooms over markers and popups too\n const container = map.getContainer();\n const wheel = (e: WheelEvent) => this.onWheel(e);\n container.addEventListener('wheel', wheel, { passive: false });\n this.cleanup.push(() => container.removeEventListener('wheel', wheel));\n listen('dblclick', (e) => this.zoomBy(e.shiftKey ? -1 : 1, this.local(e)));\n listen('contextmenu', (e) => e.preventDefault());\n if (options.keyboard ?? true) {\n // On the container: the keys work with the focus on a marker or a control too\n const key = (e: KeyboardEvent) => this.onKey(e);\n container.addEventListener('keydown', key);\n this.cleanup.push(() => container.removeEventListener('keydown', key));\n }\n }\n\n destroy(): void {\n for (const off of this.cleanup) off();\n }\n\n /** A gesture holds the map (pointers down): the camera has not stopped moving */\n get active(): boolean {\n return this.pointers.size > 0;\n }\n\n private local(e: MouseEvent): Point {\n this.rect ??= this.map.canvas.getBoundingClientRect();\n return [e.clientX - this.rect.left, e.clientY - this.rect.top];\n }\n\n private down(e: PointerEvent): void {\n this.map.canvas.setPointerCapture(e.pointerId);\n const point = this.local(e);\n const rotate = e.button === 2 || e.ctrlKey || e.shiftKey;\n this.pointers.set(e.pointerId, { point, start: point, button: e.button, rotate });\n this.trail = [];\n this.moved = false;\n // Grabbing the map stops any running animation (inertia, wheel zoom, easeTo)\n this.wheel.pending = 0;\n this.map.animate(undefined);\n }\n\n private move(e: PointerEvent): void {\n const point = this.local(e);\n const p = this.pointers.get(e.pointerId);\n if (!p) {\n if (e.pointerType === 'mouse') this.map.hover(point);\n return;\n }\n const [dx, dy] = [point[0] - p.point[0], point[1] - p.point[1]];\n if (Math.hypot(point[0] - p.start[0], point[1] - p.start[1]) > CLICK_TOLERANCE) this.moved = true;\n const engine = this.map.engine;\n const other = [...this.pointers.values()].find((q) => q !== p);\n if (this.pointers.size === 2 && other) {\n // Pinch: zoom by the change of spread, turn by the change of angle, pan by the midpoint\n const before = Math.hypot(p.point[0] - other.point[0], p.point[1] - other.point[1]);\n const after = Math.hypot(point[0] - other.point[0], point[1] - other.point[1]);\n const angle = (q: Point) => Math.atan2(q[1] - other.point[1], q[0] - other.point[0]);\n const mid = (q: Point): Point => [(q[0] + other.point[0]) / 2, (q[1] + other.point[1]) / 2];\n engine.pan(...mid(p.point), ...mid(point));\n if (before > 0 && after > 0) engine.zoomAt(Math.log2(after / before), ...mid(point));\n engine.rotate((-(angle(point) - angle(p.point)) * 180) / Math.PI, 0);\n } else if (p.rotate) {\n engine.rotate(-dx * ROTATE_RATE, -dy * ROTATE_RATE);\n } else {\n engine.pan(p.point[0], p.point[1], point[0], point[1]);\n this.trail.push([e.timeStamp, dx, dy]);\n }\n p.point = point;\n this.map.requestRender();\n }\n\n private up(e: PointerEvent): void {\n const p = this.pointers.get(e.pointerId);\n if (!p) return;\n this.pointers.delete(e.pointerId);\n // The next frame sends 'moveend' if the camera stays\n this.map.requestRender();\n if (!this.moved && e.type === 'pointerup' && p.button === 0 && this.pointers.size === 0) {\n this.map.emit('click', { point: p.point, lonLat: this.map.unproject(p.point) });\n return;\n }\n if (!p.rotate && this.pointers.size === 0) this.inertia(e.timeStamp, p.point);\n }\n\n /** Keeps panning at the release speed (last 50 ms), decaying exponentially */\n private inertia(now: number, from: Point): void {\n const recent = this.trail.filter(([t]) => now - t < 50);\n const first = recent[0];\n if (!first || recent.length < 2) return;\n const span = Math.max(16, now - first[0]);\n let vx = recent.reduce((s, [, dx]) => s + dx, 0) / span;\n let vy = recent.reduce((s, [, , dy]) => s + dy, 0) / span;\n if (Math.hypot(vx, vy) < 0.1) return;\n let last = performance.now();\n let point = from;\n this.map.animate((t) => {\n const dt = Math.min(64, t - last);\n last = t;\n const decay = Math.exp(-dt / INERTIA_DECAY);\n const next: Point = [point[0] + vx * dt, point[1] + vy * dt];\n this.map.engine.pan(point[0], point[1], next[0], next[1]);\n point = next;\n vx *= decay;\n vy *= decay;\n return Math.hypot(vx, vy) > 0.02;\n });\n }\n\n private onWheel(e: WheelEvent): void {\n e.preventDefault();\n // Lines (Firefox mouse wheels) are about 33 px\n const pixels = e.deltaMode === 1 ? e.deltaY * 33 : e.deltaY;\n this.zoomBy(\n Math.max(-1, Math.min(1, -pixels * WHEEL_RATE)),\n this.local(e),\n e.deltaMode === 0 && Math.abs(pixels) < 40,\n );\n }\n\n private onKey(e: KeyboardEvent): void {\n if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey || editable(e.target)) return;\n const action = keyAction(e.key, e.shiftKey);\n if (!action) return;\n e.preventDefault();\n this.wheel.pending = 0;\n const reduced = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n this.map.easeTo(keyCamera(action, this.map.getCamera()), reduced ? 0 : KEY_DURATION);\n }\n\n /** Smooth zoom around a screen point; touchpads (`direct`) follow the fingers without easing */\n private zoomBy(delta: number, at: Point, direct = false): void {\n if (direct) {\n this.map.engine.zoomAt(delta, at[0], at[1]);\n this.map.requestRender();\n return;\n }\n // Accumulate: a second notch before the end of the first one adds to it\n this.wheel.pending += delta;\n this.wheel.at = at;\n this.map.animate(() => {\n const step = Math.abs(this.wheel.pending) < 0.002 ? this.wheel.pending : this.wheel.pending * WHEEL_EASE;\n this.wheel.pending -= step;\n this.map.engine.zoomAt(step, this.wheel.at[0], this.wheel.at[1]);\n return this.wheel.pending !== 0;\n });\n }\n}\n"]}
1
+ {"version":3,"file":"interaction.js","sourceRoot":"","sources":["../src/interaction.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mouse, touch and keyboard controls. Every gesture only updates the camera and asks for a frame: the engine draws at most\n * once per display refresh, whatever the event rate of the device.\n */\nimport { latitude, mercatorX, mercatorY } from './geo.ts';\nimport type { GeoMap } from './map.ts';\nimport type { Point } from './types.ts';\nimport type { Camera } from './wasm/isard.js';\n\n/** Zoom levels per wheel pixel (a mouse notch is about 100 px: 1/3 of a level) */\nconst WHEEL_RATE = 1 / 300;\n/** Share of the remaining wheel zoom applied per frame (smooth, about 150 ms to settle) */\nconst WHEEL_EASE = 0.3;\n/** Degrees per pixel when rotating or tilting with the mouse */\nconst ROTATE_RATE = 0.4;\n/** A press that moves less than this (CSS pixels) is a click */\nconst CLICK_TOLERANCE = 4;\n/** Pan speed kept on release, decaying with this time constant (ms) */\nconst INERTIA_DECAY = 280;\n\n/** CSS pixels per arrow key press */\nconst KEY_PAN = 100;\n/** Degrees per Shift + left or right arrow */\nconst KEY_BEARING = 15;\n/** Degrees per Shift + up or down arrow */\nconst KEY_PITCH = 10;\n/** Duration of the moves made by keys, milliseconds */\nconst KEY_DURATION = 300;\n\n/** What a key does to the camera: a pan in CSS pixels, a zoom, rotation or tilt step, or facing north */\nexport type KeyAction = { pan: Point } | { zoom: number } | { bearing: number } | { pitch: number } | { reset: true };\n\n/** The action of a key (`KeyboardEvent.key`), as MapLibre's: arrows pan (with Shift: rotate and tilt), + and - zoom\n * (with Shift: two levels), 0 faces north and levels the view */\nexport function keyAction(key: string, shift: boolean): KeyAction | undefined {\n switch (key) {\n case 'ArrowLeft':\n return shift ? { bearing: -KEY_BEARING } : { pan: [-KEY_PAN, 0] };\n case 'ArrowRight':\n return shift ? { bearing: KEY_BEARING } : { pan: [KEY_PAN, 0] };\n case 'ArrowUp':\n return shift ? { pitch: KEY_PITCH } : { pan: [0, -KEY_PAN] };\n case 'ArrowDown':\n return shift ? { pitch: -KEY_PITCH } : { pan: [0, KEY_PAN] };\n case '+':\n case '=':\n return { zoom: shift ? 2 : 1 };\n case '-':\n case '_':\n return { zoom: shift ? -2 : -1 };\n case '0':\n return { reset: true };\n default:\n return undefined;\n }\n}\n\n/** The camera after a key's action: a pan moves the center by that many CSS pixels on screen (the ground in view,\n * turned with the bearing, stretched by the tilt) */\nexport function keyCamera(action: KeyAction, camera: Camera): Partial<Camera> {\n if ('zoom' in action) return { zoom: camera.zoom + action.zoom };\n if ('bearing' in action) return { bearing: camera.bearing + action.bearing };\n if ('pitch' in action) return { pitch: Math.max(0, camera.pitch + action.pitch) };\n if ('reset' in action) return { bearing: 0, pitch: 0 };\n const b = (camera.bearing * Math.PI) / 180;\n const [sx, sy] = [action.pan[0], action.pan[1] / Math.max(0.25, Math.cos((camera.pitch * Math.PI) / 180))];\n // Web Mercator units (0 to 1 across the world, y down); the world is 512 CSS pixels at zoom 0\n const world = 512 * 2 ** camera.zoom;\n const dx = (sx * Math.cos(b) - sy * Math.sin(b)) / world;\n const dy = (sx * Math.sin(b) + sy * Math.cos(b)) / world;\n const [lon, lat] = camera.center;\n const x = mercatorX(lon) + dx;\n const y = Math.max(0, Math.min(1, mercatorY(lat) + dy));\n const wrapped = ((((x * 360) % 360) + 360) % 360) - 180;\n return { center: [wrapped, latitude(y)] };\n}\n\n/** An element that takes the keys typed in it */\nfunction editable(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return target.isContentEditable || ['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName);\n}\n\ninterface Pointer {\n point: Point;\n start: Point;\n button: number;\n rotate: boolean;\n}\n\nexport class Interaction {\n private readonly pointers = new Map<number, Pointer>();\n private readonly cleanup: (() => void)[] = [];\n private wheel = { pending: 0, at: [0, 0] as Point };\n /** Recent pan moves, for the release speed: [time, dx, dy] */\n private trail: [number, number, number][] = [];\n private moved = false;\n /** The canvas's place on the page, read once: reading it on every pointer move would force a layout each time.\n * Read again after a resize, a scroll, and when a pointer comes in or goes down */\n private rect: DOMRect | undefined;\n\n constructor(\n private readonly map: GeoMap,\n options: { keyboard?: boolean } = {},\n ) {\n const canvas = map.canvas;\n const listen = <K extends keyof HTMLElementEventMap>(\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n ) => {\n canvas.addEventListener(type, handler, options);\n this.cleanup.push(() => canvas.removeEventListener(type, handler));\n };\n const moved = () => {\n this.rect = undefined;\n };\n listen('pointerenter', moved);\n // Scrolls of the page or of any element holding the map\n if (typeof addEventListener === 'function') {\n addEventListener('scroll', moved, { capture: true, passive: true });\n this.cleanup.push(() => removeEventListener('scroll', moved, { capture: true }));\n }\n this.cleanup.push(map.on('resize', moved));\n listen('pointerdown', (e) => {\n this.rect = undefined;\n this.down(e);\n });\n listen('pointermove', (e) => this.move(e));\n listen('pointerup', (e) => this.up(e));\n listen('pointercancel', (e) => this.up(e));\n listen('pointerleave', (e) => {\n if (e.pointerType !== 'mouse') return;\n map.hover(undefined);\n map.emit('leave', {});\n });\n // On the container, the wheel zooms over markers and popups too\n const container = map.getContainer();\n const wheel = (e: WheelEvent) => this.onWheel(e);\n container.addEventListener('wheel', wheel, { passive: false });\n this.cleanup.push(() => container.removeEventListener('wheel', wheel));\n listen('dblclick', (e) => this.zoomBy(e.shiftKey ? -1 : 1, this.local(e)));\n listen('contextmenu', (e) => e.preventDefault());\n if (options.keyboard ?? true) {\n // On the container: the keys work with the focus on a marker or a control too\n const key = (e: KeyboardEvent) => this.onKey(e);\n container.addEventListener('keydown', key);\n this.cleanup.push(() => container.removeEventListener('keydown', key));\n }\n }\n\n destroy(): void {\n for (const off of this.cleanup) off();\n }\n\n /** A gesture holds the map (pointers down): the camera has not stopped moving */\n get active(): boolean {\n return this.pointers.size > 0;\n }\n\n private local(e: MouseEvent): Point {\n this.rect ??= this.map.canvas.getBoundingClientRect();\n return [e.clientX - this.rect.left, e.clientY - this.rect.top];\n }\n\n private down(e: PointerEvent): void {\n this.map.canvas.setPointerCapture(e.pointerId);\n const point = this.local(e);\n const rotate = e.button === 2 || e.ctrlKey || e.shiftKey;\n this.pointers.set(e.pointerId, { point, start: point, button: e.button, rotate });\n this.trail = [];\n this.moved = false;\n // Grabbing the map stops any running animation (inertia, wheel zoom, easeTo)\n this.wheel.pending = 0;\n this.map.animate(undefined);\n }\n\n private move(e: PointerEvent): void {\n const point = this.local(e);\n const p = this.pointers.get(e.pointerId);\n if (!p) {\n if (e.pointerType === 'mouse') this.map.hover(point);\n return;\n }\n const [dx, dy] = [point[0] - p.point[0], point[1] - p.point[1]];\n if (Math.hypot(point[0] - p.start[0], point[1] - p.start[1]) > CLICK_TOLERANCE) this.moved = true;\n const engine = this.map.engine;\n const other = [...this.pointers.values()].find((q) => q !== p);\n if (this.pointers.size === 2 && other) {\n // Pinch: zoom by the change of spread, turn by the change of angle, pan by the midpoint\n const before = Math.hypot(p.point[0] - other.point[0], p.point[1] - other.point[1]);\n const after = Math.hypot(point[0] - other.point[0], point[1] - other.point[1]);\n const angle = (q: Point) => Math.atan2(q[1] - other.point[1], q[0] - other.point[0]);\n const mid = (q: Point): Point => [(q[0] + other.point[0]) / 2, (q[1] + other.point[1]) / 2];\n engine.pan(...mid(p.point), ...mid(point));\n if (before > 0 && after > 0) engine.zoomAt(Math.log2(after / before), ...mid(point));\n engine.rotate((-(angle(point) - angle(p.point)) * 180) / Math.PI, 0);\n } else if (p.rotate) {\n engine.rotate(-dx * ROTATE_RATE, -dy * ROTATE_RATE);\n } else {\n engine.pan(p.point[0], p.point[1], point[0], point[1]);\n this.trail.push([e.timeStamp, dx, dy]);\n }\n p.point = point;\n this.map.requestRender();\n }\n\n private up(e: PointerEvent): void {\n const p = this.pointers.get(e.pointerId);\n if (!p) return;\n this.pointers.delete(e.pointerId);\n // The next frame sends 'moveend' if the camera stays\n this.map.requestRender();\n if (!this.moved && e.type === 'pointerup' && p.button === 0 && this.pointers.size === 0) {\n this.map.emit('click', { point: p.point, lonLat: this.map.unproject(p.point) });\n return;\n }\n if (!p.rotate && this.pointers.size === 0) this.inertia(e.timeStamp, p.point);\n }\n\n /** Keeps panning at the release speed (last 50 ms), decaying exponentially */\n private inertia(now: number, from: Point): void {\n const recent = this.trail.filter(([t]) => now - t < 50);\n const first = recent[0];\n if (!first || recent.length < 2) return;\n const span = Math.max(16, now - first[0]);\n let vx = recent.reduce((s, [, dx]) => s + dx, 0) / span;\n let vy = recent.reduce((s, [, , dy]) => s + dy, 0) / span;\n if (Math.hypot(vx, vy) < 0.1) return;\n let last = performance.now();\n let point = from;\n this.map.animate((t) => {\n const dt = Math.min(64, t - last);\n last = t;\n const decay = Math.exp(-dt / INERTIA_DECAY);\n const next: Point = [point[0] + vx * dt, point[1] + vy * dt];\n this.map.engine.pan(point[0], point[1], next[0], next[1]);\n point = next;\n vx *= decay;\n vy *= decay;\n return Math.hypot(vx, vy) > 0.02;\n });\n }\n\n private onWheel(e: WheelEvent): void {\n e.preventDefault();\n // Lines (Firefox mouse wheels) are about 33 px\n const pixels = e.deltaMode === 1 ? e.deltaY * 33 : e.deltaY;\n this.zoomBy(\n Math.max(-1, Math.min(1, -pixels * WHEEL_RATE)),\n this.local(e),\n e.deltaMode === 0 && Math.abs(pixels) < 40,\n );\n }\n\n private onKey(e: KeyboardEvent): void {\n if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey || editable(e.target)) return;\n const action = keyAction(e.key, e.shiftKey);\n if (!action) return;\n e.preventDefault();\n this.wheel.pending = 0;\n const reduced = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n this.map.easeTo(keyCamera(action, this.map.getCamera()), reduced ? 0 : KEY_DURATION);\n }\n\n /** Smooth zoom around a screen point; touchpads (`direct`) follow the fingers without easing */\n private zoomBy(delta: number, at: Point, direct = false): void {\n if (direct) {\n this.map.engine.zoomAt(delta, at[0], at[1]);\n this.map.requestRender();\n return;\n }\n // Accumulate: a second notch before the end of the first one adds to it\n this.wheel.pending += delta;\n this.wheel.at = at;\n this.map.animate(() => {\n const step = Math.abs(this.wheel.pending) < 0.002 ? this.wheel.pending : this.wheel.pending * WHEEL_EASE;\n this.wheel.pending -= step;\n this.map.engine.zoomAt(step, this.wheel.at[0], this.wheel.at[1]);\n return this.wheel.pending !== 0;\n });\n }\n}\n"]}
Binary file
Binary file
package/dist/kml.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * KML to GeoJSON, for the feature layers: `map.addLines({ data: parseKml(await (await fetch(url)).text()) })`.
3
+ */
4
+ import type { FeatureCollection, Properties } from './features.ts';
5
+ /**
6
+ * The placemarks of a KML document as GeoJSON features: their points, lines (and gx:Track), polygons (with their
7
+ * holes) and MultiGeometry (a Multi… of one type, else a GeometryCollection); their `name`, `description`, extended
8
+ * data (`Data`, `SimpleData`) as properties, and the colors of their style (inline, or shared through `styleUrl` and
9
+ * `StyleMap`) as `stroke`, `stroke-opacity`, `stroke-width`, `fill`, `fill-opacity`, `marker-color`. A placemark
10
+ * without geometry has a null one
11
+ */
12
+ export declare function parseKml<P = Properties>(text: string): FeatureCollection<P>;
package/dist/kml.js ADDED
@@ -0,0 +1,159 @@
1
+ import { child, children, childText, descendants, parseXml } from "./xml.js";
2
+ /** Positions of a `coordinates` element: `lon,lat[,alt]` tuples separated by spaces */
3
+ function positions(element) {
4
+ const out = [];
5
+ for (const tuple of (element?.text ?? '').trim().split(/\s+/)) {
6
+ const values = tuple.split(',').map(Number);
7
+ if (values.length >= 2 && values.every(Number.isFinite))
8
+ out.push(values);
9
+ }
10
+ return out;
11
+ }
12
+ /** The geometries of an element (a Placemark, a MultiGeometry), in order */
13
+ function geometries(parent) {
14
+ const out = [];
15
+ for (const g of parent.children) {
16
+ if (g.name === 'Point') {
17
+ const [p] = positions(child(g, 'coordinates'));
18
+ if (p)
19
+ out.push({ type: 'Point', coordinates: p });
20
+ }
21
+ else if (g.name === 'LineString' || g.name === 'LinearRing') {
22
+ const line = positions(child(g, 'coordinates'));
23
+ if (line.length >= 2)
24
+ out.push({ type: 'LineString', coordinates: line });
25
+ }
26
+ else if (g.name === 'Polygon') {
27
+ const ring = (b) => positions(child(child(b, 'LinearRing'), 'coordinates'));
28
+ const outer = child(g, 'outerBoundaryIs');
29
+ const rings = [...(outer ? [ring(outer)] : []), ...children(g, 'innerBoundaryIs').map(ring)];
30
+ if ((rings[0]?.length ?? 0) >= 4)
31
+ out.push({ type: 'Polygon', coordinates: rings.filter((r) => r.length >= 4) });
32
+ }
33
+ else if (g.name === 'Track') {
34
+ // gx:Track: its gx:coord, `lon lat alt`
35
+ const line = children(g, 'coord')
36
+ .map((c) => c.text.trim().split(/\s+/).map(Number))
37
+ .filter((p) => p.length >= 2 && p.every(Number.isFinite));
38
+ if (line.length >= 2)
39
+ out.push({ type: 'LineString', coordinates: line });
40
+ }
41
+ else if (g.name === 'MultiGeometry' || g.name === 'MultiTrack') {
42
+ out.push(...geometries(g));
43
+ }
44
+ }
45
+ return out;
46
+ }
47
+ /** One geometry of several: a Multi… of one type, else a collection */
48
+ function merge(list) {
49
+ const [first] = list;
50
+ if (!first)
51
+ return null;
52
+ if (list.length === 1)
53
+ return first;
54
+ const same = list.every((g) => g.type === first.type);
55
+ if (same && first.type === 'Point') {
56
+ return { type: 'MultiPoint', coordinates: list.map((g) => g.coordinates) };
57
+ }
58
+ if (same && first.type === 'LineString') {
59
+ return { type: 'MultiLineString', coordinates: list.map((g) => g.coordinates) };
60
+ }
61
+ if (same && first.type === 'Polygon') {
62
+ return { type: 'MultiPolygon', coordinates: list.map((g) => g.coordinates) };
63
+ }
64
+ return { type: 'GeometryCollection', geometries: list };
65
+ }
66
+ /** A KML color (`aabbggrr`, hexadecimal) as a CSS color and an opacity */
67
+ function color(element) {
68
+ const value = childText(element, 'color')?.replace(/^#/, '');
69
+ if (!value || !/^[\da-f]{8}$/i.test(value))
70
+ return undefined;
71
+ const [a, b, g, r] = [0, 2, 4, 6].map((i) => value.slice(i, i + 2));
72
+ return [`#${r}${g}${b}`.toLowerCase(), Math.round((Number.parseInt(a, 16) / 255) * 1000) / 1000];
73
+ }
74
+ /** The properties of a style (simplestyle's names, as togeojson): stroke, stroke-opacity, stroke-width, fill,
75
+ * fill-opacity, marker-color */
76
+ function styleProperties(style) {
77
+ const out = {};
78
+ if (!style)
79
+ return out;
80
+ const line = child(style, 'LineStyle');
81
+ const stroke = color(line);
82
+ if (stroke)
83
+ [out.stroke, out['stroke-opacity']] = stroke;
84
+ const width = Number(childText(line, 'width'));
85
+ if (childText(line, 'width') !== undefined && Number.isFinite(width))
86
+ out['stroke-width'] = width;
87
+ const poly = child(style, 'PolyStyle');
88
+ const fill = color(poly);
89
+ if (fill)
90
+ [out.fill, out['fill-opacity']] = fill;
91
+ if (childText(poly, 'fill') === '0')
92
+ out['fill-opacity'] = 0;
93
+ if (childText(poly, 'outline') === '0')
94
+ out['stroke-opacity'] = 0;
95
+ const icon = color(child(style, 'IconStyle'));
96
+ if (icon)
97
+ out['marker-color'] = icon[0];
98
+ return out;
99
+ }
100
+ /**
101
+ * The placemarks of a KML document as GeoJSON features: their points, lines (and gx:Track), polygons (with their
102
+ * holes) and MultiGeometry (a Multi… of one type, else a GeometryCollection); their `name`, `description`, extended
103
+ * data (`Data`, `SimpleData`) as properties, and the colors of their style (inline, or shared through `styleUrl` and
104
+ * `StyleMap`) as `stroke`, `stroke-opacity`, `stroke-width`, `fill`, `fill-opacity`, `marker-color`. A placemark
105
+ * without geometry has a null one
106
+ */
107
+ export function parseKml(text) {
108
+ const root = parseXml(text);
109
+ const styles = new Map();
110
+ for (const s of descendants(root, 'Style'))
111
+ if (s.attributes.id)
112
+ styles.set(s.attributes.id, s);
113
+ const maps = new Map();
114
+ for (const m of descendants(root, 'StyleMap')) {
115
+ const normal = children(m, 'Pair').find((p) => childText(p, 'key') === 'normal');
116
+ const url = childText(normal, 'styleUrl');
117
+ if (m.attributes.id && url)
118
+ maps.set(m.attributes.id, url);
119
+ }
120
+ /** The style of a `styleUrl` in this document (`#id`, through a StyleMap) */
121
+ const shared = (url, depth = 0) => {
122
+ const id = url?.slice(url.indexOf('#') + 1);
123
+ if (id === undefined || depth > 4)
124
+ return undefined;
125
+ return styles.get(id) ?? shared(maps.get(id), depth + 1);
126
+ };
127
+ const features = descendants(root, 'Placemark').map((placemark) => {
128
+ const properties = { ...styleProperties(shared(childText(placemark, 'styleUrl'))) };
129
+ Object.assign(properties, styleProperties(child(placemark, 'Style')));
130
+ for (const key of ['name', 'description', 'address', 'styleUrl']) {
131
+ const value = childText(placemark, key);
132
+ if (value !== undefined)
133
+ properties[key] = value;
134
+ }
135
+ const time = childText(child(placemark, 'TimeStamp'), 'when');
136
+ if (time !== undefined)
137
+ properties.time = time;
138
+ const extended = child(placemark, 'ExtendedData');
139
+ for (const data of children(extended, 'Data')) {
140
+ if (data.attributes.name)
141
+ properties[data.attributes.name] = childText(data, 'value') ?? '';
142
+ }
143
+ for (const schema of children(extended, 'SchemaData')) {
144
+ for (const data of children(schema, 'SimpleData')) {
145
+ if (data.attributes.name)
146
+ properties[data.attributes.name] = data.text.trim();
147
+ }
148
+ }
149
+ const id = placemark.attributes.id;
150
+ return {
151
+ type: 'Feature',
152
+ geometry: merge(geometries(placemark)),
153
+ properties: properties,
154
+ ...(id === undefined ? {} : { id }),
155
+ };
156
+ });
157
+ return { type: 'FeatureCollection', features };
158
+ }
159
+ //# sourceMappingURL=kml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kml.js","sourceRoot":"","sources":["../src/kml.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * KML to GeoJSON, for the feature layers: `map.addLines({ data: parseKml(await (await fetch(url)).text()) })`.\n */\nimport type { Feature, FeatureCollection, Geometry, Position, Properties } from './features.ts';\nimport { child, children, childText, descendants, parseXml, type XmlElement } from './xml.ts';\n\n/** Positions of a `coordinates` element: `lon,lat[,alt]` tuples separated by spaces */\nfunction positions(element: XmlElement | undefined): Position[] {\n const out: Position[] = [];\n for (const tuple of (element?.text ?? '').trim().split(/\\s+/)) {\n const values = tuple.split(',').map(Number);\n if (values.length >= 2 && values.every(Number.isFinite)) out.push(values as Position);\n }\n return out;\n}\n\n/** The geometries of an element (a Placemark, a MultiGeometry), in order */\nfunction geometries(parent: XmlElement): Geometry[] {\n const out: Geometry[] = [];\n for (const g of parent.children) {\n if (g.name === 'Point') {\n const [p] = positions(child(g, 'coordinates'));\n if (p) out.push({ type: 'Point', coordinates: p });\n } else if (g.name === 'LineString' || g.name === 'LinearRing') {\n const line = positions(child(g, 'coordinates'));\n if (line.length >= 2) out.push({ type: 'LineString', coordinates: line });\n } else if (g.name === 'Polygon') {\n const ring = (b: XmlElement) => positions(child(child(b, 'LinearRing'), 'coordinates'));\n const outer = child(g, 'outerBoundaryIs');\n const rings = [...(outer ? [ring(outer)] : []), ...children(g, 'innerBoundaryIs').map(ring)];\n if ((rings[0]?.length ?? 0) >= 4) out.push({ type: 'Polygon', coordinates: rings.filter((r) => r.length >= 4) });\n } else if (g.name === 'Track') {\n // gx:Track: its gx:coord, `lon lat alt`\n const line = children(g, 'coord')\n .map((c) => c.text.trim().split(/\\s+/).map(Number))\n .filter((p) => p.length >= 2 && p.every(Number.isFinite)) as Position[];\n if (line.length >= 2) out.push({ type: 'LineString', coordinates: line });\n } else if (g.name === 'MultiGeometry' || g.name === 'MultiTrack') {\n out.push(...geometries(g));\n }\n }\n return out;\n}\n\n/** One geometry of several: a Multi… of one type, else a collection */\nfunction merge(list: Geometry[]): Geometry | null {\n const [first] = list;\n if (!first) return null;\n if (list.length === 1) return first;\n const same = list.every((g) => g.type === first.type);\n if (same && first.type === 'Point') {\n return { type: 'MultiPoint', coordinates: list.map((g) => (g as { coordinates: Position }).coordinates) };\n }\n if (same && first.type === 'LineString') {\n return { type: 'MultiLineString', coordinates: list.map((g) => (g as { coordinates: Position[] }).coordinates) };\n }\n if (same && first.type === 'Polygon') {\n return { type: 'MultiPolygon', coordinates: list.map((g) => (g as { coordinates: Position[][] }).coordinates) };\n }\n return { type: 'GeometryCollection', geometries: list };\n}\n\n/** A KML color (`aabbggrr`, hexadecimal) as a CSS color and an opacity */\nfunction color(element: XmlElement | undefined): [css: string, opacity: number] | undefined {\n const value = childText(element, 'color')?.replace(/^#/, '');\n if (!value || !/^[\\da-f]{8}$/i.test(value)) return undefined;\n const [a, b, g, r] = [0, 2, 4, 6].map((i) => value.slice(i, i + 2));\n return [`#${r}${g}${b}`.toLowerCase(), Math.round((Number.parseInt(a as string, 16) / 255) * 1000) / 1000];\n}\n\n/** The properties of a style (simplestyle's names, as togeojson): stroke, stroke-opacity, stroke-width, fill,\n * fill-opacity, marker-color */\nfunction styleProperties(style: XmlElement | undefined): Properties {\n const out: Properties = {};\n if (!style) return out;\n const line = child(style, 'LineStyle');\n const stroke = color(line);\n if (stroke) [out.stroke, out['stroke-opacity']] = stroke;\n const width = Number(childText(line, 'width'));\n if (childText(line, 'width') !== undefined && Number.isFinite(width)) out['stroke-width'] = width;\n const poly = child(style, 'PolyStyle');\n const fill = color(poly);\n if (fill) [out.fill, out['fill-opacity']] = fill;\n if (childText(poly, 'fill') === '0') out['fill-opacity'] = 0;\n if (childText(poly, 'outline') === '0') out['stroke-opacity'] = 0;\n const icon = color(child(style, 'IconStyle'));\n if (icon) out['marker-color'] = icon[0];\n return out;\n}\n\n/**\n * The placemarks of a KML document as GeoJSON features: their points, lines (and gx:Track), polygons (with their\n * holes) and MultiGeometry (a Multi… of one type, else a GeometryCollection); their `name`, `description`, extended\n * data (`Data`, `SimpleData`) as properties, and the colors of their style (inline, or shared through `styleUrl` and\n * `StyleMap`) as `stroke`, `stroke-opacity`, `stroke-width`, `fill`, `fill-opacity`, `marker-color`. A placemark\n * without geometry has a null one\n */\nexport function parseKml<P = Properties>(text: string): FeatureCollection<P> {\n const root = parseXml(text);\n const styles = new Map<string, XmlElement>();\n for (const s of descendants(root, 'Style')) if (s.attributes.id) styles.set(s.attributes.id, s);\n const maps = new Map<string, string>();\n for (const m of descendants(root, 'StyleMap')) {\n const normal = children(m, 'Pair').find((p) => childText(p, 'key') === 'normal');\n const url = childText(normal, 'styleUrl');\n if (m.attributes.id && url) maps.set(m.attributes.id, url);\n }\n /** The style of a `styleUrl` in this document (`#id`, through a StyleMap) */\n const shared = (url: string | undefined, depth = 0): XmlElement | undefined => {\n const id = url?.slice(url.indexOf('#') + 1);\n if (id === undefined || depth > 4) return undefined;\n return styles.get(id) ?? shared(maps.get(id), depth + 1);\n };\n const features = descendants(root, 'Placemark').map((placemark): Feature<P> => {\n const properties: Properties = { ...styleProperties(shared(childText(placemark, 'styleUrl'))) };\n Object.assign(properties, styleProperties(child(placemark, 'Style')));\n for (const key of ['name', 'description', 'address', 'styleUrl']) {\n const value = childText(placemark, key);\n if (value !== undefined) properties[key] = value;\n }\n const time = childText(child(placemark, 'TimeStamp'), 'when');\n if (time !== undefined) properties.time = time;\n const extended = child(placemark, 'ExtendedData');\n for (const data of children(extended, 'Data')) {\n if (data.attributes.name) properties[data.attributes.name] = childText(data, 'value') ?? '';\n }\n for (const schema of children(extended, 'SchemaData')) {\n for (const data of children(schema, 'SimpleData')) {\n if (data.attributes.name) properties[data.attributes.name] = data.text.trim();\n }\n }\n const id = placemark.attributes.id;\n return {\n type: 'Feature',\n geometry: merge(geometries(placemark)),\n properties: properties as P,\n ...(id === undefined ? {} : { id }),\n };\n });\n return { type: 'FeatureCollection', features };\n}\n"]}
package/dist/layers.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import type { GeoMap } from './map.ts';
1
2
  import type { LonLat, NetworkStyle, RasterStyle, Tiles3dStyle } from './types.ts';
2
- import type { NetworkStats, Tiles3dStats } from './wasm/isard.js';
3
+ import type { Camera, NetworkStats, Tiles3dStats } from './wasm/isard.js';
3
4
  export declare abstract class Layer {
4
5
  #private;
5
6
  /** Id of the layer in the engine */
@@ -64,7 +65,7 @@ export interface GroundTexture {
64
65
  export interface GroundOptions {
65
66
  /**
66
67
  * GLSL ES 3.0 defining `vec4 ground(vec2 offset)`: the color of the ground (premultiplied alpha, 0 for nothing) at
67
- * `offset`, the Mercator offset of the pixel from `anchor` (times `ISARD_EARTH`: metres of EPSG:3857), exact to
68
+ * `offset`, the Mercator offset of the pixel from `anchor` (times `ISARD_CIRCUMFERENCE`: metres of EPSG:3857), exact to
68
69
  * the millimetre at any zoom. The code declares its own uniforms and samplers; also there: `u_zoom`,
69
70
  * `u_pixel_ratio`
70
71
  */
@@ -101,3 +102,89 @@ export declare class GroundLayer extends Layer {
101
102
  setVisible(visible: boolean): void;
102
103
  private sendTexture;
103
104
  }
105
+ /** What a custom layer gets to draw a frame (`CustomLayerInterface.render`) */
106
+ export interface CustomFrame {
107
+ /**
108
+ * The model-view-projection matrix of a local frame at a position and altitude (metres above the ellipsoid, as the
109
+ * relief is drawn: times its exaggeration), column-major for `uniformMatrix4fv` or a three.js camera: x east, y
110
+ * north, z up, in metres. Made in double precision relative to the camera, so that what is drawn stays exact at
111
+ * any zoom; draw within a few kilometres of the position (or take one matrix per object far apart). Only during
112
+ * `render`.
113
+ */
114
+ matrixAt(lonLat: LonLat, altitude?: number): Float32Array;
115
+ /** The camera of the frame */
116
+ readonly camera: Camera;
117
+ }
118
+ /**
119
+ * A layer drawn by the page with its own WebGL code, as MapLibre's `CustomLayerInterface`: `render` is called at the
120
+ * layer's place in every frame drawn. It starts with the canvas bound, its viewport set, blending on (`SRC_ALPHA`,
121
+ * `ONE_MINUS_SRC_ALPHA`), no culling, and in `'3d'` mode the depth test on (`LEQUAL`, depth written): the relief, the
122
+ * buildings and the 3D Tiles hide what it draws and what it draws hides them. Whatever WebGL state it changes is set
123
+ * back afterwards; a library that caches the WebGL state (three.js) must forget it first (`renderer.resetState()`).
124
+ *
125
+ * The map is busy drawing meanwhile: `render` reads the frame, not the map (`getCamera` excepted); it may call
126
+ * `requestRender` for an animation.
127
+ */
128
+ export interface CustomLayerInterface {
129
+ /** A name for the application (the map numbers its layers) */
130
+ id?: string;
131
+ /** `'2d'` (the default): drawn over what is under it; `'3d'`: with the depth buffer of the 3D layers */
132
+ renderingMode?: '2d' | '3d';
133
+ /** Creates the WebGL objects: once added, and again after the WebGL context was lost and restored */
134
+ onAdd?(gl: WebGL2RenderingContext, map: GeoMap): void;
135
+ render(gl: WebGL2RenderingContext, frame: CustomFrame): void;
136
+ /** Frees the WebGL objects: the layer is removed, or the map destroyed */
137
+ onRemove?(gl: WebGL2RenderingContext, map: GeoMap): void;
138
+ }
139
+ /** A layer drawn by the page's WebGL code (see `CustomLayerInterface`) */
140
+ export declare class CustomLayer extends Layer {
141
+ /** The application's object */
142
+ readonly implementation: CustomLayerInterface;
143
+ private readonly canvas;
144
+ private readonly owner;
145
+ /** The map's WebGL context, and whether `onAdd` made the layer's objects there (until `onRemove`) */
146
+ private readonly gl;
147
+ private added;
148
+ /** The context was lost since `onAdd`: its objects are gone */
149
+ private stale;
150
+ private readonly lost;
151
+ private readonly frame;
152
+ /** Called by the engine at the layer's place in the frame; the page's errors are reported, the frame goes on */
153
+ private readonly draw;
154
+ remove(): void;
155
+ }
156
+ /** Where and how a model stands */
157
+ export interface ModelInstance {
158
+ lonLat: LonLat;
159
+ /** Metres above the ground (or above the ellipsoid, `altitudeReference: 'sea'`); 0 by default */
160
+ altitude?: number;
161
+ /** Degrees clockwise from the north of the model's front (glTF +Z); 0 by default */
162
+ heading?: number;
163
+ /** Degrees, nose up */
164
+ pitch?: number;
165
+ /** Degrees, right side down */
166
+ roll?: number;
167
+ /** 1 by default: the model's metres */
168
+ scale?: number;
169
+ }
170
+ export interface ModelOptions {
171
+ /** URL of a glTF binary (`.glb`): meshes, textures, Draco, meshopt, KTX2, as in 3D Tiles; or its bytes (`data`) */
172
+ url?: string;
173
+ data?: ArrayBuffer | ArrayBufferView<ArrayBuffer>;
174
+ instances: readonly ModelInstance[];
175
+ /** What the altitudes are above: `'ground'` (the relief, the default) or `'sea'` (the ellipsoid) */
176
+ altitudeReference?: 'ground' | 'sea';
177
+ }
178
+ /** The numbers of instances for the engine: longitude, latitude, altitude, heading, pitch, roll, scale */
179
+ export declare function instanceNumbers(instances: readonly ModelInstance[]): Float64Array;
180
+ /** A glTF model drawn at positions, in one instanced draw; `pickFeature` gives the instance's index */
181
+ export declare class ModelLayer extends Layer {
182
+ private readonly url;
183
+ /** The `blob:` URL of the page's bytes, revoked once the layer is gone */
184
+ private readonly blob;
185
+ private instances;
186
+ private ground;
187
+ /** Replaces the instances (and what their altitudes are above, kept if not given) */
188
+ setInstances(instances: readonly ModelInstance[], altitudeReference?: 'ground' | 'sea'): void;
189
+ remove(): void;
190
+ }