isard 1.2.0 → 1.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.
- package/CHANGELOG.md +124 -0
- package/README.md +46 -39
- package/dist/basemap/basemaps.js +1 -0
- package/dist/basemap/basemaps.js.map +1 -1
- package/dist/basemap/pmtileslayer.d.ts +33 -0
- package/dist/basemap/pmtileslayer.js +97 -0
- package/dist/basemap/pmtileslayer.js.map +1 -0
- package/dist/basemap/trees.d.ts +26 -0
- package/dist/basemap/trees.js +141 -0
- package/dist/basemap/trees.js.map +1 -0
- package/dist/basemap/vectorstyle.d.ts +10 -0
- package/dist/basemap/vectorstyle.js +35 -0
- package/dist/basemap/vectorstyle.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +93 -44
- package/dist/basemap/vectortiles.js +511 -303
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/workerpool.d.ts +17 -0
- package/dist/basemap/workerpool.js +203 -0
- package/dist/basemap/workerpool.js.map +1 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +18 -8
- package/dist/bind/layers.js +10 -0
- package/dist/bind/layers.js.map +1 -1
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +3 -3
- package/dist/engine-loader.d.ts +8 -1
- package/dist/engine-loader.js +20 -1
- package/dist/engine-loader.js.map +1 -1
- package/dist/geoplateforme.d.ts +16 -0
- package/dist/geoplateforme.js +23 -0
- package/dist/geoplateforme.js.map +1 -1
- package/dist/grid-module.d.ts +44 -0
- package/dist/grid-module.js +63 -0
- package/dist/grid-module.js.map +1 -0
- package/dist/grids.d.ts +51 -0
- package/dist/grids.js +88 -0
- package/dist/grids.js.map +1 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.js +11 -2
- 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/flow.d.ts +111 -0
- package/dist/layers/flow.js +222 -0
- package/dist/layers/flow.js.map +1 -0
- package/dist/layers/layers.js +9 -0
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/symbols.d.ts +2 -0
- package/dist/layers/symbols.js +2 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/vectors.d.ts +60 -0
- package/dist/layers/vectors.js +130 -0
- package/dist/layers/vectors.js.map +1 -0
- package/dist/map/frame-loop.d.ts +3 -0
- package/dist/map/frame-loop.js +6 -0
- package/dist/map/frame-loop.js.map +1 -1
- package/dist/map/layer-spec.d.ts +4 -1
- package/dist/map/layer-spec.js +2 -0
- package/dist/map/layer-spec.js.map +1 -1
- package/dist/map/raster-source.js +1 -1
- package/dist/map/raster-source.js.map +1 -1
- package/dist/map/workers.d.ts +5 -1
- package/dist/map/workers.js +36 -1
- package/dist/map/workers.js.map +1 -1
- package/dist/map.d.ts +35 -6
- package/dist/map.js +83 -11
- package/dist/map.js.map +1 -1
- package/dist/react/IsardMap.js +1 -0
- package/dist/react/IsardMap.js.map +1 -1
- package/dist/react/Layer.d.ts +2 -0
- package/dist/react/Layer.js.map +1 -1
- package/dist/react/Swipe.d.ts +11 -4
- package/dist/react/Swipe.js +26 -15
- package/dist/react/Swipe.js.map +1 -1
- package/dist/react/VectorGeometry.d.ts +35 -0
- package/dist/react/VectorGeometry.js +82 -0
- package/dist/react/VectorGeometry.js.map +1 -0
- package/dist/react/context.d.ts +2 -1
- package/dist/react/context.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +2 -1
- package/dist/react/index.js.map +1 -1
- package/dist/types.d.ts +30 -3
- package/dist/types.js.map +1 -1
- package/dist/ui/minimap.d.ts +25 -0
- package/dist/ui/minimap.js +90 -0
- package/dist/ui/minimap.js.map +1 -0
- package/dist/ui/scale.d.ts +19 -0
- package/dist/ui/scale.js +44 -0
- package/dist/ui/scale.js.map +1 -0
- package/dist/ui/search.d.ts +25 -0
- package/dist/ui/search.js +119 -0
- package/dist/ui/search.js.map +1 -0
- package/dist/ui/style.js +17 -0
- package/dist/ui/style.js.map +1 -1
- package/dist/util/sun.d.ts +11 -0
- package/dist/util/sun.js +26 -0
- package/dist/util/sun.js.map +1 -0
- package/dist/wasm/isard.d.ts +124 -7
- package/dist/wasm/isard.js +319 -8
- package/dist/wasm/isard_core.d.ts +124 -7
- package/dist/wasm/isard_core.js +319 -8
- package/dist/wasm/isard_grid.d.ts +101 -0
- package/dist/wasm/isard_grid.js +375 -0
- package/dist/wasm/isard_tess.d.ts +109 -0
- package/dist/wasm/isard_tess.js +398 -0
- package/dist/workers/basemap/geometry.d.ts +72 -0
- package/dist/workers/basemap/labels.d.ts +8 -0
- package/dist/workers/basemap/raster.d.ts +10 -0
- package/dist/workers/basemap/street.d.ts +19 -0
- package/dist/workers/basemap/tiles.d.ts +65 -0
- package/dist/workers/basemap/trees.d.ts +19 -0
- package/dist/workers/basemap.worker.d.ts +147 -22
- package/dist/workers/basemap.worker.js +93 -553
- package/dist/workers/basemap.worker.js.map +1 -1
- package/package.json +6 -4
- package/vite.js +11 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IsardMap.js","sourceRoot":"","sources":["../../src/react/IsardMap.tsx"],"names":[],"mappings":"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","sourcesContent":["/** `<IsardMap>`: the map, created when it mounts, destroyed when it unmounts, its options and events as props */\n\nimport {\n type CSSProperties,\n forwardRef,\n type ReactNode,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport { LayerOrder } from '../bind/layers.ts';\nimport { GeoMap } from '../map.ts';\nimport type { GeoMapOptions, LonLat, MapEvents, ViewshedOptions } from '../types.ts';\nimport type { Camera } from '../wasm/isard.js';\nimport { type Binding, defined, MapContext } from './context.ts';\n\n/** The props of the map's events: `onClick` for 'click', `onMoveEnd` for 'moveend'… */\nexport interface MapEventProps {\n onMoveStart?: (camera: Camera) => void;\n onMove?: (camera: Camera) => void;\n onMoveEnd?: (camera: Camera) => void;\n onResize?: (event: MapEvents['resize']) => void;\n onHover?: (event: MapEvents['hover']) => void;\n onHoverFeature?: (event: MapEvents['hoverfeature']) => void;\n onClick?: (event: MapEvents['click']) => void;\n onRender?: (event: MapEvents['render']) => void;\n onIdle?: () => void;\n onLeave?: () => void;\n}\n\nconst EVENT_PROPS = {\n onMoveStart: 'movestart',\n onMove: 'move',\n onMoveEnd: 'moveend',\n onResize: 'resize',\n onHover: 'hover',\n onHoverFeature: 'hoverfeature',\n onClick: 'click',\n onRender: 'render',\n onIdle: 'idle',\n onLeave: 'leave',\n} as const satisfies Record<keyof MapEventProps, keyof MapEvents>;\n\nexport interface IsardMapProps extends Omit<GeoMapOptions, keyof Camera>, MapEventProps {\n /** The camera at creation, then left to the user's gestures */\n center?: LonLat;\n zoom?: number;\n pitch?: number;\n bearing?: number;\n /** A camera the map follows: set again whenever it changes (with `onMove` to keep it in a state) */\n camera?: Partial<Camera>;\n /** What `onHoverFeature` picks: within `radius` CSS pixels, among `layers` (default every layer) */\n hoverPicking?: GeoMap['hoverPicking'];\n /** The map, once created */\n onLoad?: (map: GeoMap) => void;\n /** The map's creation failed (no WebGL2, the engine not found) */\n onError?: (error: unknown) => void;\n id?: string;\n className?: string;\n style?: CSSProperties;\n /** Layers, markers, popups, panels, effects; drawn once the map is created */\n children?: ReactNode;\n}\n\n/** The props that are not options of the map */\nconst NOT_OPTIONS = [...Object.keys(EVENT_PROPS), 'onLoad', 'onError', 'hoverPicking', 'id', 'className', 'style'];\n\nconst isEventProp = (key: string): key is keyof typeof EVENT_PROPS => key in EVENT_PROPS;\n\n/** Options the map takes again after its creation, and how */\nconst LIVE_OPTIONS: { [K in keyof GeoMapOptions]?: (map: GeoMap, props: IsardMapProps) => void } = {\n basemap: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n hillshade: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n terrain: (map, p) => map.setTerrain(p.terrain ?? false),\n minZoom: (map, p) => map.setMinZoom(p.minZoom ?? 0),\n maxZoom: (map, p) => map.setMaxZoom(p.maxZoom ?? 22),\n maxPitch: (map, p) => map.setMaxPitch(p.maxPitch ?? 70),\n atmosphere: (map, p) => map.setAtmosphere(p.atmosphere),\n projection: (map, p) => map.setProjection(p.projection ?? 'globe'),\n loading: (map, p) => map.setLoading(p.loading ?? 'immediate'),\n sky: (map, p) => map.setSky(p.sky ?? true),\n background: (map, p) => {\n if (p.background) map.setBackground(p.background);\n },\n};\n\nconst isLiveOption = (key: string): key is keyof typeof LIVE_OPTIONS => key in LIVE_OPTIONS;\n\nconst optionsOf = (props: Partial<IsardMapProps>): GeoMapOptions =>\n Object.fromEntries(Object.entries(props).filter(([key]) => !NOT_OPTIONS.includes(key))) as GeoMapOptions;\n\nconst sameCamera = (a: Camera, b: Partial<Camera>): boolean =>\n (b.center === undefined || (a.center[0] === b.center[0] && a.center[1] === b.center[1])) &&\n (b.zoom === undefined || a.zoom === b.zoom) &&\n (b.pitch === undefined || a.pitch === b.pitch) &&\n (b.bearing === undefined || a.bearing === b.bearing);\n\n/** What the components of a new map share */\nconst bindingOf = (map: GeoMap): Binding => {\n const viewsheds = new Map<object, ViewshedOptions>();\n\n return {\n map,\n order: new LayerOrder(),\n viewsheds,\n applyViewsheds: () => map.setViewshed(viewsheds.size > 0 ? [...viewsheds.values()] : undefined),\n };\n};\n\n/**\n * A map filling its element (give it a height). Created once mounted, destroyed when unmounted; the options read at\n * creation only (`body`, `preset`, `interactive`, the URLs) need a new `key` to take another value\n */\nexport const IsardMap = forwardRef<GeoMap | undefined, IsardMapProps>(function IsardMap(props, ref) {\n const element = useRef<HTMLDivElement>(null);\n const latest = useRef(props);\n const applied = useRef<IsardMapProps>(props);\n const [binding, setBinding] = useState<Binding>();\n const map = binding?.map;\n const { camera, hoverPicking } = props;\n\n latest.current = props;\n useImperativeHandle(ref, () => map, [map]);\n\n // Created once: StrictMode's second mount and an unmount before the engine is loaded drop the map they started\n useEffect(() => {\n const container = element.current;\n\n if (!container) return;\n\n const created: { map?: GeoMap; cancelled: boolean } = { cancelled: false };\n const { camera, center, zoom, pitch, bearing, children: _, ...options } = latest.current;\n\n GeoMap.create(container, { ...optionsOf(options), ...defined({ center, zoom, pitch, bearing }), ...camera }).then(\n (map) => {\n if (created.cancelled) {\n map.destroy();\n\n return;\n }\n\n created.map = map;\n setBinding(bindingOf(map));\n latest.current.onLoad?.(map);\n },\n (error: unknown) => {\n if (created.cancelled) return;\n if (latest.current.onError) latest.current.onError(error);\n else console.error(error);\n },\n );\n\n return () => {\n created.cancelled = true;\n created.map?.destroy();\n setBinding(undefined);\n };\n }, []);\n\n // The events, each listened to once: the props may give another function at each render\n useEffect(() => {\n if (!map) return;\n\n const offs = Object.keys(EVENT_PROPS)\n .filter(isEventProp)\n .map((prop) =>\n map.on(EVENT_PROPS[prop], (event) => (latest.current[prop] as ((e: unknown) => void) | undefined)?.(event)),\n );\n\n return () => {\n offs.forEach((off) => {\n off();\n });\n };\n }, [map]);\n\n // The options taken again, compared with what the map was given last\n useEffect(() => {\n if (!map) return;\n\n const last = applied.current;\n const done = new Set<(map: GeoMap, props: IsardMapProps) => void>();\n\n applied.current = props;\n Object.keys(LIVE_OPTIONS)\n .filter(isLiveOption)\n .forEach((key) => {\n const apply = LIVE_OPTIONS[key];\n const changed = !Object.is(last[key], props[key]);\n\n if (!apply || done.has(apply) || !changed) return;\n done.add(apply);\n apply(map, props);\n });\n });\n\n // What `onHoverFeature` picks, given to the map whenever the prop changes\n useEffect(() => {\n if (map && hoverPicking) map.hoverPicking = hoverPicking;\n }, [map, hoverPicking]);\n\n // A controlled camera: set when the prop changes, unless the map is already there (a gesture reported by `onMove`)\n useEffect(() => {\n if (map && camera && !sameCamera(map.getCamera(), camera)) map.setCamera(camera);\n }, [map, camera]);\n\n return (\n <div ref={element} id={props.id} className={props.className} style={props.style}>\n {binding ? <MapContext.Provider value={binding}>{props.children}</MapContext.Provider> : null}\n </div>\n );\n});\n"]}
|
|
1
|
+
{"version":3,"file":"IsardMap.js","sourceRoot":"","sources":["../../src/react/IsardMap.tsx"],"names":[],"mappings":"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","sourcesContent":["/** `<IsardMap>`: the map, created when it mounts, destroyed when it unmounts, its options and events as props */\n\nimport {\n type CSSProperties,\n forwardRef,\n type ReactNode,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport { LayerOrder } from '../bind/layers.ts';\nimport { GeoMap } from '../map.ts';\nimport type { GeoMapOptions, LonLat, MapEvents, ViewshedOptions } from '../types.ts';\nimport type { Camera } from '../wasm/isard.js';\nimport { type Binding, defined, MapContext } from './context.ts';\n\n/** The props of the map's events: `onClick` for 'click', `onMoveEnd` for 'moveend'… */\nexport interface MapEventProps {\n onMoveStart?: (camera: Camera) => void;\n onMove?: (camera: Camera) => void;\n onMoveEnd?: (camera: Camera) => void;\n onResize?: (event: MapEvents['resize']) => void;\n onHover?: (event: MapEvents['hover']) => void;\n onHoverFeature?: (event: MapEvents['hoverfeature']) => void;\n onClick?: (event: MapEvents['click']) => void;\n onRender?: (event: MapEvents['render']) => void;\n onIdle?: () => void;\n onLeave?: () => void;\n}\n\nconst EVENT_PROPS = {\n onMoveStart: 'movestart',\n onMove: 'move',\n onMoveEnd: 'moveend',\n onResize: 'resize',\n onHover: 'hover',\n onHoverFeature: 'hoverfeature',\n onClick: 'click',\n onRender: 'render',\n onIdle: 'idle',\n onLeave: 'leave',\n} as const satisfies Record<keyof MapEventProps, keyof MapEvents>;\n\nexport interface IsardMapProps extends Omit<GeoMapOptions, keyof Camera>, MapEventProps {\n /** The camera at creation, then left to the user's gestures */\n center?: LonLat;\n zoom?: number;\n pitch?: number;\n bearing?: number;\n /** A camera the map follows: set again whenever it changes (with `onMove` to keep it in a state) */\n camera?: Partial<Camera>;\n /** What `onHoverFeature` picks: within `radius` CSS pixels, among `layers` (default every layer) */\n hoverPicking?: GeoMap['hoverPicking'];\n /** The map, once created */\n onLoad?: (map: GeoMap) => void;\n /** The map's creation failed (no WebGL2, the engine not found) */\n onError?: (error: unknown) => void;\n id?: string;\n className?: string;\n style?: CSSProperties;\n /** Layers, markers, popups, panels, effects; drawn once the map is created */\n children?: ReactNode;\n}\n\n/** The props that are not options of the map */\nconst NOT_OPTIONS = [...Object.keys(EVENT_PROPS), 'onLoad', 'onError', 'hoverPicking', 'id', 'className', 'style'];\n\nconst isEventProp = (key: string): key is keyof typeof EVENT_PROPS => key in EVENT_PROPS;\n\n/** Options the map takes again after its creation, and how */\nconst LIVE_OPTIONS: { [K in keyof GeoMapOptions]?: (map: GeoMap, props: IsardMapProps) => void } = {\n basemap: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n hillshade: (map, p) => {\n if (p.basemap) map.setBasemap(p.basemap, p.hillshade);\n },\n terrain: (map, p) => map.setTerrain(p.terrain ?? false),\n minZoom: (map, p) => map.setMinZoom(p.minZoom ?? 0),\n maxZoom: (map, p) => map.setMaxZoom(p.maxZoom ?? 22),\n maxPitch: (map, p) => map.setMaxPitch(p.maxPitch ?? 70),\n atmosphere: (map, p) => map.setAtmosphere(p.atmosphere),\n projection: (map, p) => map.setProjection(p.projection ?? 'globe'),\n loading: (map, p) => map.setLoading(p.loading ?? 'immediate'),\n sky: (map, p) => map.setSky(p.sky ?? true),\n sun: (map, p) => map.setSun(p.sun),\n background: (map, p) => {\n if (p.background) map.setBackground(p.background);\n },\n};\n\nconst isLiveOption = (key: string): key is keyof typeof LIVE_OPTIONS => key in LIVE_OPTIONS;\n\nconst optionsOf = (props: Partial<IsardMapProps>): GeoMapOptions =>\n Object.fromEntries(Object.entries(props).filter(([key]) => !NOT_OPTIONS.includes(key))) as GeoMapOptions;\n\nconst sameCamera = (a: Camera, b: Partial<Camera>): boolean =>\n (b.center === undefined || (a.center[0] === b.center[0] && a.center[1] === b.center[1])) &&\n (b.zoom === undefined || a.zoom === b.zoom) &&\n (b.pitch === undefined || a.pitch === b.pitch) &&\n (b.bearing === undefined || a.bearing === b.bearing);\n\n/** What the components of a new map share */\nconst bindingOf = (map: GeoMap): Binding => {\n const viewsheds = new Map<object, ViewshedOptions>();\n\n return {\n map,\n order: new LayerOrder(),\n viewsheds,\n applyViewsheds: () => map.setViewshed(viewsheds.size > 0 ? [...viewsheds.values()] : undefined),\n };\n};\n\n/**\n * A map filling its element (give it a height). Created once mounted, destroyed when unmounted; the options read at\n * creation only (`body`, `preset`, `interactive`, the URLs) need a new `key` to take another value\n */\nexport const IsardMap = forwardRef<GeoMap | undefined, IsardMapProps>(function IsardMap(props, ref) {\n const element = useRef<HTMLDivElement>(null);\n const latest = useRef(props);\n const applied = useRef<IsardMapProps>(props);\n const [binding, setBinding] = useState<Binding>();\n const map = binding?.map;\n const { camera, hoverPicking } = props;\n\n latest.current = props;\n useImperativeHandle(ref, () => map, [map]);\n\n // Created once: StrictMode's second mount and an unmount before the engine is loaded drop the map they started\n useEffect(() => {\n const container = element.current;\n\n if (!container) return;\n\n const created: { map?: GeoMap; cancelled: boolean } = { cancelled: false };\n const { camera, center, zoom, pitch, bearing, children: _, ...options } = latest.current;\n\n GeoMap.create(container, { ...optionsOf(options), ...defined({ center, zoom, pitch, bearing }), ...camera }).then(\n (map) => {\n if (created.cancelled) {\n map.destroy();\n\n return;\n }\n\n created.map = map;\n setBinding(bindingOf(map));\n latest.current.onLoad?.(map);\n },\n (error: unknown) => {\n if (created.cancelled) return;\n if (latest.current.onError) latest.current.onError(error);\n else console.error(error);\n },\n );\n\n return () => {\n created.cancelled = true;\n created.map?.destroy();\n setBinding(undefined);\n };\n }, []);\n\n // The events, each listened to once: the props may give another function at each render\n useEffect(() => {\n if (!map) return;\n\n const offs = Object.keys(EVENT_PROPS)\n .filter(isEventProp)\n .map((prop) =>\n map.on(EVENT_PROPS[prop], (event) => (latest.current[prop] as ((e: unknown) => void) | undefined)?.(event)),\n );\n\n return () => {\n offs.forEach((off) => {\n off();\n });\n };\n }, [map]);\n\n // The options taken again, compared with what the map was given last\n useEffect(() => {\n if (!map) return;\n\n const last = applied.current;\n const done = new Set<(map: GeoMap, props: IsardMapProps) => void>();\n\n applied.current = props;\n Object.keys(LIVE_OPTIONS)\n .filter(isLiveOption)\n .forEach((key) => {\n const apply = LIVE_OPTIONS[key];\n const changed = !Object.is(last[key], props[key]);\n\n if (!apply || done.has(apply) || !changed) return;\n done.add(apply);\n apply(map, props);\n });\n });\n\n // What `onHoverFeature` picks, given to the map whenever the prop changes\n useEffect(() => {\n if (map && hoverPicking) map.hoverPicking = hoverPicking;\n }, [map, hoverPicking]);\n\n // A controlled camera: set when the prop changes, unless the map is already there (a gesture reported by `onMove`)\n useEffect(() => {\n if (map && camera && !sameCamera(map.getCamera(), camera)) map.setCamera(camera);\n }, [map, camera]);\n\n return (\n <div ref={element} id={props.id} className={props.className} style={props.style}>\n {binding ? <MapContext.Provider value={binding}>{props.children}</MapContext.Provider> : null}\n </div>\n );\n});\n"]}
|
package/dist/react/Layer.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type ReactNode, type Ref } from 'react';
|
|
|
4
4
|
import { type BoundLayerSpec } from '../bind/layers.ts';
|
|
5
5
|
import type { ExtrusionLayer } from '../layers/extrusions.ts';
|
|
6
6
|
import type { CircleLayer, FillLayer, LineLayer } from '../layers/features.ts';
|
|
7
|
+
import type { FlowLayer } from '../layers/flow.ts';
|
|
7
8
|
import type { GroundLayer, ModelLayer, NetworkLayer, RasterLayer, Tiles3dLayer } from '../layers/layers.ts';
|
|
8
9
|
import type { PointCloudLayer } from '../layers/pointclouds.ts';
|
|
9
10
|
import type { SymbolLayer } from '../layers/symbols.ts';
|
|
@@ -21,6 +22,7 @@ export interface LayerHandles<P = Record<string, unknown>> {
|
|
|
21
22
|
tiles3d: Tiles3dLayer;
|
|
22
23
|
pointcloud: PointCloudLayer;
|
|
23
24
|
models: ModelLayer;
|
|
25
|
+
flow: FlowLayer;
|
|
24
26
|
}
|
|
25
27
|
export type LayerType = LayerSpec['type'];
|
|
26
28
|
export type LayerProps<P = Record<string, unknown>, T extends LayerType = LayerType> = Extract<BoundLayerSpec<P>, {
|
package/dist/react/Layer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layer.js","sourceRoot":"","sources":["../../src/react/Layer.tsx"],"names":[],"mappings":"AAAA;oBACoB;AAEpB,OAAO,EACL,UAAU,EAGV,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EACL,aAAa,EACb,gBAAgB,EAEhB,WAAW,EACX,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"Layer.js","sourceRoot":"","sources":["../../src/react/Layer.tsx"],"names":[],"mappings":"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","sourcesContent":["/** `<Layer>`: a layer added when it mounts, updated by the least its props need, removed when it unmounts, in its\n * declared order */\n\nimport {\n forwardRef,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport {\n addBoundLayer,\n applyLayerChange,\n type BoundLayerSpec,\n layerChange,\n rebuildBoundLayer,\n} from '../bind/layers.ts';\nimport type { ExtrusionLayer } from '../layers/extrusions.ts';\nimport type { CircleLayer, FillLayer, LineLayer } from '../layers/features.ts';\nimport type { FlowLayer } from '../layers/flow.ts';\nimport type {\n GroundLayer,\n Layer as LayerHandle,\n ModelLayer,\n NetworkLayer,\n RasterLayer,\n Tiles3dLayer,\n} from '../layers/layers.ts';\nimport type { PointCloudLayer } from '../layers/pointclouds.ts';\nimport type { SymbolLayer } from '../layers/symbols.ts';\nimport type { LayerSpec } from '../map.ts';\nimport { MapContext, SwipeContext } from './context.ts';\n\n/** The handle of a layer by its type */\nexport interface LayerHandles<P = Record<string, unknown>> {\n lines: LineLayer<P>;\n circles: CircleLayer<P>;\n fills: FillLayer<P>;\n symbols: SymbolLayer<P>;\n extrusions: ExtrusionLayer<P>;\n raster: RasterLayer;\n ground: GroundLayer;\n network: NetworkLayer;\n tiles3d: Tiles3dLayer;\n pointcloud: PointCloudLayer;\n models: ModelLayer;\n flow: FlowLayer;\n}\n\nexport type LayerType = LayerSpec['type'];\n\nexport type LayerProps<P = Record<string, unknown>, T extends LayerType = LayerType> = Extract<\n BoundLayerSpec<P>,\n { type: T }\n> & {\n /** Its place among the layers of the components: from the bottom up, the same order by mounting (default 0) */\n order?: number;\n /** The layer, once created and each time it is made anew */\n onLayer?: (layer: LayerHandles<P>[T]) => void;\n ref?: Ref<LayerHandles<P>[T] | undefined>;\n};\n\ninterface Mounted {\n layer: LayerHandle;\n spec: BoundLayerSpec;\n order: number;\n}\n\nconst LayerComponent = forwardRef<LayerHandle | undefined, Omit<LayerProps, 'ref'>>(function Layer(props, ref) {\n const binding = useContext(MapContext);\n const swipe = useContext(SwipeContext);\n const { order = 0, onLayer, ...rest } = props;\n const spec = rest as BoundLayerSpec;\n const mounted = useRef<Mounted>(undefined);\n const latest = useRef({ spec, order, onLayer });\n const [layer, setLayer] = useState<LayerHandle>();\n\n latest.current = { spec, order, onLayer };\n useImperativeHandle(ref, () => layer, [layer]);\n\n // Added once the map is there, removed when unmounted (or when the map goes)\n useEffect(() => {\n if (!binding) return;\n\n const { spec, order, onLayer } = latest.current;\n const created = addBoundLayer(binding.map, spec);\n\n binding.order.place(created, order);\n mounted.current = { layer: created, spec, order };\n swipe?.set(created);\n setLayer(created);\n onLayer?.(created as never);\n\n return () => {\n const current = mounted.current;\n\n mounted.current = undefined;\n if (!current) return;\n binding.order.remove(current.layer);\n swipe?.unset(current.layer);\n if (binding.map.hasLayer(current.layer)) current.layer.remove();\n };\n }, [binding, swipe]);\n\n // Each render: what changed sent, or the layer made anew in its place\n useEffect(() => {\n const current = mounted.current;\n\n if (!binding || !current) return;\n\n const change = layerChange(current.spec, spec);\n\n current.spec = spec;\n if (change?.rebuild) {\n const old = current.layer;\n const fresh = rebuildBoundLayer(binding.map, old, spec);\n\n binding.order.place(fresh, order, old);\n swipe?.unset(old);\n swipe?.set(fresh);\n current.layer = fresh;\n current.order = order;\n setLayer(fresh);\n latest.current.onLayer?.(fresh as never);\n\n return;\n }\n\n if (change) applyLayerChange(current.layer, spec, change);\n if (current.order !== order) {\n current.order = order;\n binding.order.place(current.layer, order, current.layer);\n }\n });\n\n return null;\n});\n\n/**\n * A layer: the options of its `add…` method with its `type` (`map.add`), and `values` for the layers colored by\n * values. A change of data, style, filter, values or instances updates it; a change of what is set at creation (its\n * URL, grid, nodes…) makes it anew, in its place. Data, functions and arrays are compared by identity: keep them in a\n * memo or a state. The ref and `onLayer` give its handle, typed by its `type`; the properties of its features are\n * inferred from its data or its style functions (`<Layer<Building> …>` to name them)\n */\nexport const Layer = LayerComponent as <P = Record<string, unknown>, T extends LayerType = LayerType>(\n props: LayerProps<P, T>,\n) => ReactNode;\n"]}
|
package/dist/react/Swipe.d.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
/** `<Swipe>`: the `<Layer>` in it on one side of a vertical line only */
|
|
1
|
+
/** `<Swipe>`: the `<Layer>` in it on one side of a vertical line only, those of its `<SwipeOther>` on the other */
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
3
|
import type { SwipeOptions } from '../types.ts';
|
|
4
|
-
export interface SwipeProps extends Omit<SwipeOptions, 'layers'> {
|
|
5
|
-
/** The `<Layer>` shown on one side of the line only */
|
|
4
|
+
export interface SwipeProps extends Omit<SwipeOptions, 'layers' | 'other'> {
|
|
5
|
+
/** The `<Layer>` shown on one side of the line only, and a `<SwipeOther>` for the other side */
|
|
6
6
|
children?: ReactNode;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* The `<Layer>` in it shown on one side of a vertical line only, at `position` CSS pixels from the left; the layers in
|
|
10
|
+
* its `<SwipeOther>` on the other side only (two meshes of a place, each on its side)
|
|
11
|
+
*/
|
|
9
12
|
export declare const Swipe: (props: SwipeProps) => ReactNode;
|
|
13
|
+
/** In a `<Swipe>`: the `<Layer>` in it shown on the other side of the line only */
|
|
14
|
+
export declare const SwipeOther: ({ children }: {
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
}) => ReactNode;
|
package/dist/react/Swipe.js
CHANGED
|
@@ -1,41 +1,52 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
/** `<Swipe>`: the `<Layer>` in it on one side of a vertical line only */
|
|
3
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
/** `<Swipe>`: the `<Layer>` in it on one side of a vertical line only, those of its `<SwipeOther>` on the other */
|
|
3
|
+
import { useContext, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { defined, SwipeContext, useMap } from "./context.js";
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* The `<Layer>` in it shown on one side of a vertical line only, at `position` CSS pixels from the left; the layers in
|
|
7
|
+
* its `<SwipeOther>` on the other side only (two meshes of a place, each on its side)
|
|
8
|
+
*/
|
|
6
9
|
export const Swipe = (props) => {
|
|
7
10
|
const map = useMap();
|
|
8
11
|
const latest = useRef(props);
|
|
9
12
|
const { position, side } = props;
|
|
10
13
|
const layers = useMemo(() => new Set(), []);
|
|
14
|
+
const others = useMemo(() => new Set(), []);
|
|
11
15
|
latest.current = props;
|
|
12
16
|
const group = useMemo(() => {
|
|
13
17
|
if (!map)
|
|
14
18
|
return undefined;
|
|
15
|
-
const apply = () =>
|
|
16
|
-
|
|
17
|
-
map.setSwipe(layers.size > 0 ? { position, layers: [...layers], ...defined({ side }) } : undefined);
|
|
18
|
-
};
|
|
19
|
-
return {
|
|
19
|
+
const apply = () => map.setSwipe(swipeOptions(latest.current, layers, others));
|
|
20
|
+
const of = (set) => ({
|
|
20
21
|
set: (layer) => {
|
|
21
|
-
|
|
22
|
+
set.add(layer);
|
|
22
23
|
apply();
|
|
23
24
|
},
|
|
24
25
|
unset: (layer) => {
|
|
25
|
-
|
|
26
|
+
set.delete(layer);
|
|
26
27
|
apply();
|
|
27
28
|
},
|
|
28
|
-
};
|
|
29
|
-
|
|
29
|
+
});
|
|
30
|
+
return { ...of(layers), other: of(others) };
|
|
31
|
+
}, [map, layers, others]);
|
|
30
32
|
// The line's position and side sent to the map when they change (the layers in it come and go through the group)
|
|
31
33
|
useEffect(() => {
|
|
32
|
-
if (map && layers.size > 0)
|
|
33
|
-
map.setSwipe({ position,
|
|
34
|
-
}, [map, layers, position, side]);
|
|
34
|
+
if (map && (layers.size > 0 || others.size > 0))
|
|
35
|
+
map.setSwipe(swipeOptions({ position, side }, layers, others));
|
|
36
|
+
}, [map, layers, others, position, side]);
|
|
35
37
|
// The swipe taken off the map when unmounted
|
|
36
38
|
useEffect(() => () => {
|
|
37
39
|
map?.setSwipe(undefined);
|
|
38
40
|
}, [map]);
|
|
39
41
|
return _jsx(SwipeContext.Provider, { value: group, children: props.children });
|
|
40
42
|
};
|
|
43
|
+
/** The swipe of the line's props and the layers of both sides; undefined when no layer is in it */
|
|
44
|
+
const swipeOptions = ({ position, side }, layers, others) => layers.size > 0 || others.size > 0
|
|
45
|
+
? { position, layers: [...layers], other: [...others], ...defined({ side }) }
|
|
46
|
+
: undefined;
|
|
47
|
+
/** In a `<Swipe>`: the `<Layer>` in it shown on the other side of the line only */
|
|
48
|
+
export const SwipeOther = ({ children }) => {
|
|
49
|
+
const group = useContext(SwipeContext);
|
|
50
|
+
return _jsx(SwipeContext.Provider, { value: group?.other, children: children });
|
|
51
|
+
};
|
|
41
52
|
//# sourceMappingURL=Swipe.js.map
|
package/dist/react/Swipe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Swipe.js","sourceRoot":"","sources":["../../src/react/Swipe.tsx"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"Swipe.js","sourceRoot":"","sources":["../../src/react/Swipe.tsx"],"names":[],"mappings":"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","sourcesContent":["/** `<Swipe>`: the `<Layer>` in it on one side of a vertical line only, those of its `<SwipeOther>` on the other */\n\nimport { type ReactNode, useContext, useEffect, useMemo, useRef } from 'react';\nimport type { Layer as LayerHandle } from '../layers/layers.ts';\nimport type { SwipeOptions } from '../types.ts';\nimport { defined, SwipeContext, type SwipeGroup, useMap } from './context.ts';\n\nexport interface SwipeProps extends Omit<SwipeOptions, 'layers' | 'other'> {\n /** The `<Layer>` shown on one side of the line only, and a `<SwipeOther>` for the other side */\n children?: ReactNode;\n}\n\n/**\n * The `<Layer>` in it shown on one side of a vertical line only, at `position` CSS pixels from the left; the layers in\n * its `<SwipeOther>` on the other side only (two meshes of a place, each on its side)\n */\nexport const Swipe = (props: SwipeProps): ReactNode => {\n const map = useMap();\n const latest = useRef(props);\n const { position, side } = props;\n const layers = useMemo(() => new Set<LayerHandle>(), []);\n const others = useMemo(() => new Set<LayerHandle>(), []);\n\n latest.current = props;\n\n const group = useMemo<SwipeGroup | undefined>(() => {\n if (!map) return undefined;\n\n const apply = () => map.setSwipe(swipeOptions(latest.current, layers, others));\n const of = (set: Set<LayerHandle>): SwipeGroup => ({\n set: (layer) => {\n set.add(layer);\n apply();\n },\n unset: (layer) => {\n set.delete(layer);\n apply();\n },\n });\n\n return { ...of(layers), other: of(others) };\n }, [map, layers, others]);\n\n // The line's position and side sent to the map when they change (the layers in it come and go through the group)\n useEffect(() => {\n if (map && (layers.size > 0 || others.size > 0)) map.setSwipe(swipeOptions({ position, side }, layers, others));\n }, [map, layers, others, position, side]);\n // The swipe taken off the map when unmounted\n useEffect(\n () => () => {\n map?.setSwipe(undefined);\n },\n [map],\n );\n\n return <SwipeContext.Provider value={group}>{props.children}</SwipeContext.Provider>;\n};\n\n/** The swipe of the line's props and the layers of both sides; undefined when no layer is in it */\nconst swipeOptions = (\n { position, side }: { position: number; side?: SwipeProps['side'] | undefined },\n layers: Set<LayerHandle>,\n others: Set<LayerHandle>,\n): SwipeOptions | undefined =>\n layers.size > 0 || others.size > 0\n ? { position, layers: [...layers], other: [...others], ...defined({ side }) }\n : undefined;\n\n/** In a `<Swipe>`: the `<Layer>` in it shown on the other side of the line only */\nexport const SwipeOther = ({ children }: { children?: ReactNode }): ReactNode => {\n const group = useContext(SwipeContext);\n\n return <SwipeContext.Provider value={group?.other}>{children}</SwipeContext.Provider>;\n};\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** `<VectorGeometry>`: the fills and lines of a MapLibre style drawn as geometry (`vectorTiles().vectors()`), among the
|
|
2
|
+
* layers of the components */
|
|
3
|
+
import { type ReactNode, type Ref } from 'react';
|
|
4
|
+
import type { Style, StyleLayer } from '../basemap/vectorstyle.ts';
|
|
5
|
+
import type { VectorLayer, VectorSublayer } from '../layers/vectors.ts';
|
|
6
|
+
export interface VectorGeometryProps {
|
|
7
|
+
/** A style URL or object (default OpenFreeMap's Positron); another one makes the layer anew */
|
|
8
|
+
style?: string | Style;
|
|
9
|
+
/** The style layers drawn (default all its fills and lines); another function makes the layer anew, so keep it in a
|
|
10
|
+
* memo or at the module's level */
|
|
11
|
+
layers?: (layer: StyleLayer) => boolean;
|
|
12
|
+
/** The line layers that glow at night (default those whose id names a road); another function makes the layer anew,
|
|
13
|
+
* as `layers` */
|
|
14
|
+
streets?: (layer: StyleLayer) => boolean;
|
|
15
|
+
/** Paint properties over the style's (`setPaintProperty`), by style layer id, or by style layer drawn once the style
|
|
16
|
+
* is loaded (a function of its id, kind, source layer): compared by value, only those changed sent; one taken out
|
|
17
|
+
* keeps its last value */
|
|
18
|
+
paint?: Paint | ((layer: VectorSublayer) => Record<string, unknown> | undefined);
|
|
19
|
+
/** Shown (default true) */
|
|
20
|
+
visible?: boolean;
|
|
21
|
+
/** Its place among the layers of the components (as `<Layer order>`) */
|
|
22
|
+
order?: number;
|
|
23
|
+
/** The layer, once created and each time it is made anew */
|
|
24
|
+
onLayer?: (layer: VectorLayer) => void;
|
|
25
|
+
ref?: Ref<VectorLayer | undefined>;
|
|
26
|
+
}
|
|
27
|
+
/** Paint properties by style layer id */
|
|
28
|
+
type Paint = Record<string, Record<string, unknown>>;
|
|
29
|
+
/**
|
|
30
|
+
* The fills and lines of a MapLibre style drawn as geometry on the globe and the relief (`vectorTiles().vectors()`):
|
|
31
|
+
* sharp at any zoom and pitch, restyled by `paint` without cutting the tiles again, picked by feature
|
|
32
|
+
* (`map.pickFeature`). The ref and `onLayer` give its handle (`VectorLayer`: `layers`, `featureAt`, `ready`)
|
|
33
|
+
*/
|
|
34
|
+
export declare const VectorGeometry: (props: VectorGeometryProps) => ReactNode;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** `<VectorGeometry>`: the fills and lines of a MapLibre style drawn as geometry (`vectorTiles().vectors()`), among the
|
|
2
|
+
* layers of the components */
|
|
3
|
+
import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState, } from 'react';
|
|
4
|
+
import { MapContext, SwipeContext } from "./context.js";
|
|
5
|
+
/** The paint properties of `next` that differ from those of `sent`, as `[layer, name, value]` */
|
|
6
|
+
const changed = (sent, next) => Object.entries(next ?? {}).flatMap(([layer, properties]) => Object.entries(properties)
|
|
7
|
+
.filter(([name, value]) => JSON.stringify(sent?.[layer]?.[name]) !== JSON.stringify(value))
|
|
8
|
+
.map(([name, value]) => [layer, name, value]));
|
|
9
|
+
const VectorGeometryComponent = forwardRef(function VectorGeometry({ style, layers, streets, paint, visible = true, order = 0, onLayer }, ref) {
|
|
10
|
+
const binding = useContext(MapContext);
|
|
11
|
+
const swipe = useContext(SwipeContext);
|
|
12
|
+
const latest = useRef({ order, onLayer });
|
|
13
|
+
/** The paint properties sent to the current layer */
|
|
14
|
+
const sent = useRef(undefined);
|
|
15
|
+
const [layer, setLayer] = useState();
|
|
16
|
+
latest.current = { order, onLayer };
|
|
17
|
+
useImperativeHandle(ref, () => layer, [layer]);
|
|
18
|
+
// The tiles and their geometry layer created once the map is there, in the declared order; made anew when the
|
|
19
|
+
// style, the layers kept or the streets change; the tiles (and their layer) destroyed when unmounted
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!binding)
|
|
22
|
+
return;
|
|
23
|
+
const tiles = binding.map.vectorTiles(style === undefined ? {} : { style });
|
|
24
|
+
const created = tiles.vectors({ ...(layers && { layers }), ...(streets && { streets }) });
|
|
25
|
+
binding.order.place(created, latest.current.order);
|
|
26
|
+
swipe?.set(created);
|
|
27
|
+
sent.current = undefined;
|
|
28
|
+
setLayer(created);
|
|
29
|
+
latest.current.onLayer?.(created);
|
|
30
|
+
return () => {
|
|
31
|
+
binding.order.remove(created);
|
|
32
|
+
swipe?.unset(created);
|
|
33
|
+
tiles.destroy();
|
|
34
|
+
setLayer(undefined);
|
|
35
|
+
};
|
|
36
|
+
}, [binding, swipe, style, layers, streets]);
|
|
37
|
+
// The paint properties changed since the last ones sent (all of them to a layer made anew), those of a function
|
|
38
|
+
// once the style is loaded; a later render or layer drops the wait
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!layer)
|
|
41
|
+
return;
|
|
42
|
+
const apply = (next) => {
|
|
43
|
+
changed(sent.current, next).forEach(([id, name, value]) => {
|
|
44
|
+
layer.setPaintProperty(id, name, value);
|
|
45
|
+
});
|
|
46
|
+
sent.current = next;
|
|
47
|
+
};
|
|
48
|
+
if (typeof paint !== 'function') {
|
|
49
|
+
apply(paint);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const wait = { live: true };
|
|
53
|
+
layer.ready.then(() => {
|
|
54
|
+
if (!wait.live)
|
|
55
|
+
return;
|
|
56
|
+
apply(Object.fromEntries(layer.layers.flatMap((l) => {
|
|
57
|
+
const properties = paint(l);
|
|
58
|
+
return properties ? [[l.id, properties]] : [];
|
|
59
|
+
})));
|
|
60
|
+
}, () => undefined);
|
|
61
|
+
return () => {
|
|
62
|
+
wait.live = false;
|
|
63
|
+
};
|
|
64
|
+
}, [layer, paint]);
|
|
65
|
+
// Shown or hidden
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
layer?.setVisible(visible);
|
|
68
|
+
}, [layer, visible]);
|
|
69
|
+
// A new `order`: moved to its new place among the layers of the components
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (binding && layer)
|
|
72
|
+
binding.order.place(layer, order, layer);
|
|
73
|
+
}, [binding, layer, order]);
|
|
74
|
+
return null;
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* The fills and lines of a MapLibre style drawn as geometry on the globe and the relief (`vectorTiles().vectors()`):
|
|
78
|
+
* sharp at any zoom and pitch, restyled by `paint` without cutting the tiles again, picked by feature
|
|
79
|
+
* (`map.pickFeature`). The ref and `onLayer` give its handle (`VectorLayer`: `layers`, `featureAt`, `ready`)
|
|
80
|
+
*/
|
|
81
|
+
export const VectorGeometry = VectorGeometryComponent;
|
|
82
|
+
//# sourceMappingURL=VectorGeometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VectorGeometry.js","sourceRoot":"","sources":["../../src/react/VectorGeometry.tsx"],"names":[],"mappings":"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","sourcesContent":["/** `<VectorGeometry>`: the fills and lines of a MapLibre style drawn as geometry (`vectorTiles().vectors()`), among the\n * layers of the components */\n\nimport {\n forwardRef,\n type ReactNode,\n type Ref,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react';\nimport type { Style, StyleLayer } from '../basemap/vectorstyle.ts';\nimport type { VectorLayer, VectorSublayer } from '../layers/vectors.ts';\nimport { MapContext, SwipeContext } from './context.ts';\n\nexport interface VectorGeometryProps {\n /** A style URL or object (default OpenFreeMap's Positron); another one makes the layer anew */\n style?: string | Style;\n /** The style layers drawn (default all its fills and lines); another function makes the layer anew, so keep it in a\n * memo or at the module's level */\n layers?: (layer: StyleLayer) => boolean;\n /** The line layers that glow at night (default those whose id names a road); another function makes the layer anew,\n * as `layers` */\n streets?: (layer: StyleLayer) => boolean;\n /** Paint properties over the style's (`setPaintProperty`), by style layer id, or by style layer drawn once the style\n * is loaded (a function of its id, kind, source layer): compared by value, only those changed sent; one taken out\n * keeps its last value */\n paint?: Paint | ((layer: VectorSublayer) => Record<string, unknown> | undefined);\n /** Shown (default true) */\n visible?: boolean;\n /** Its place among the layers of the components (as `<Layer order>`) */\n order?: number;\n /** The layer, once created and each time it is made anew */\n onLayer?: (layer: VectorLayer) => void;\n ref?: Ref<VectorLayer | undefined>;\n}\n\n/** Paint properties by style layer id */\ntype Paint = Record<string, Record<string, unknown>>;\n\n/** The paint properties of `next` that differ from those of `sent`, as `[layer, name, value]` */\nconst changed = (sent: Paint | undefined, next: Paint | undefined): [layer: string, name: string, value: unknown][] =>\n Object.entries(next ?? {}).flatMap(([layer, properties]) =>\n Object.entries(properties)\n .filter(([name, value]) => JSON.stringify(sent?.[layer]?.[name]) !== JSON.stringify(value))\n .map(([name, value]): [string, string, unknown] => [layer, name, value]),\n );\n\nconst VectorGeometryComponent = forwardRef<VectorLayer | undefined, Omit<VectorGeometryProps, 'ref'>>(\n function VectorGeometry({ style, layers, streets, paint, visible = true, order = 0, onLayer }, ref) {\n const binding = useContext(MapContext);\n const swipe = useContext(SwipeContext);\n const latest = useRef({ order, onLayer });\n /** The paint properties sent to the current layer */\n const sent = useRef<Paint>(undefined);\n const [layer, setLayer] = useState<VectorLayer>();\n\n latest.current = { order, onLayer };\n useImperativeHandle(ref, () => layer, [layer]);\n\n // The tiles and their geometry layer created once the map is there, in the declared order; made anew when the\n // style, the layers kept or the streets change; the tiles (and their layer) destroyed when unmounted\n useEffect(() => {\n if (!binding) return;\n\n const tiles = binding.map.vectorTiles(style === undefined ? {} : { style });\n const created = tiles.vectors({ ...(layers && { layers }), ...(streets && { streets }) });\n\n binding.order.place(created, latest.current.order);\n swipe?.set(created);\n sent.current = undefined;\n setLayer(created);\n latest.current.onLayer?.(created);\n\n return () => {\n binding.order.remove(created);\n swipe?.unset(created);\n tiles.destroy();\n setLayer(undefined);\n };\n }, [binding, swipe, style, layers, streets]);\n\n // The paint properties changed since the last ones sent (all of them to a layer made anew), those of a function\n // once the style is loaded; a later render or layer drops the wait\n useEffect(() => {\n if (!layer) return;\n\n const apply = (next: Paint | undefined) => {\n changed(sent.current, next).forEach(([id, name, value]) => {\n layer.setPaintProperty(id, name, value);\n });\n sent.current = next;\n };\n\n if (typeof paint !== 'function') {\n apply(paint);\n\n return;\n }\n\n const wait = { live: true };\n\n layer.ready.then(\n () => {\n if (!wait.live) return;\n apply(\n Object.fromEntries(\n layer.layers.flatMap((l) => {\n const properties = paint(l);\n\n return properties ? [[l.id, properties]] : [];\n }),\n ),\n );\n },\n () => undefined,\n );\n\n return () => {\n wait.live = false;\n };\n }, [layer, paint]);\n\n // Shown or hidden\n useEffect(() => {\n layer?.setVisible(visible);\n }, [layer, visible]);\n\n // A new `order`: moved to its new place among the layers of the components\n useEffect(() => {\n if (binding && layer) binding.order.place(layer, order, layer);\n }, [binding, layer, order]);\n\n return null;\n },\n);\n\n/**\n * The fills and lines of a MapLibre style drawn as geometry on the globe and the relief (`vectorTiles().vectors()`):\n * sharp at any zoom and pitch, restyled by `paint` without cutting the tiles again, picked by feature\n * (`map.pickFeature`). The ref and `onLayer` give its handle (`VectorLayer`: `layers`, `featureAt`, `ready`)\n */\nexport const VectorGeometry = VectorGeometryComponent as (props: VectorGeometryProps) => ReactNode;\n"]}
|
package/dist/react/context.d.ts
CHANGED
|
@@ -13,10 +13,11 @@ export interface Binding {
|
|
|
13
13
|
applyViewsheds(): void;
|
|
14
14
|
}
|
|
15
15
|
export declare const MapContext: import("react").Context<Binding | undefined>;
|
|
16
|
-
/** The layers of a `<Swipe>` around, its `<Layer>` children joining it */
|
|
16
|
+
/** The layers of a `<Swipe>` around, its `<Layer>` children joining it; `other`: the group of its `<SwipeOther>` */
|
|
17
17
|
export interface SwipeGroup {
|
|
18
18
|
set(layer: LayerHandle): void;
|
|
19
19
|
unset(layer: LayerHandle): void;
|
|
20
|
+
other?: SwipeGroup;
|
|
20
21
|
}
|
|
21
22
|
export declare const SwipeContext: import("react").Context<SwipeGroup | undefined>;
|
|
22
23
|
/** The marker of a `<Marker>` around and its position (a `<Popup>` in it opens on its click, at that position) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/react/context.ts"],"names":[],"mappings":"AAAA;uBACuB;AAEvB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAerE,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAsB,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/react/context.ts"],"names":[],"mappings":"AAAA;uBACuB;AAEvB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAerE,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAsB,SAAS,CAAC,CAAC;AASxE,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAyB,SAAS,CAAC,CAAC;AAE7E,kHAAkH;AAClH,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAuD,SAAS,CAAC,CAAC;AAE5G,0EAA0E;AAC1E,MAAM,CAAC,MAAM,MAAM,GAAG,GAAuB,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC;AAE5E,mHAAmH;AACnH,MAAM,CAAC,MAAM,WAAW,GAAG,CAA4B,IAAO,EAAE,QAAuC,EAAQ,EAAE;IAC/G,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEhC,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC1B,uGAAuG;IACvG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAmB,MAAS,EAAiD,EAAE,CACpG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAEnF,CAAC","sourcesContent":["/** What the components of a map share: the map, the order of their layers, the viewsheds, the swipe and the marker\n * around; the hooks */\n\nimport { createContext, useContext, useEffect, useRef } from 'react';\nimport type { LayerOrder } from '../bind/layers.ts';\nimport type { Layer as LayerHandle } from '../layers/layers.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { LonLat, MapEvents, ViewshedOptions } from '../types.ts';\nimport type { Marker as MarkerHandle } from '../ui/overlay.ts';\n\nexport interface Binding {\n map: GeoMap;\n order: LayerOrder;\n /** The observers of the `<Viewshed>` components, set on the map together */\n viewsheds: Map<object, ViewshedOptions>;\n applyViewsheds(): void;\n}\n\nexport const MapContext = createContext<Binding | undefined>(undefined);\n\n/** The layers of a `<Swipe>` around, its `<Layer>` children joining it; `other`: the group of its `<SwipeOther>` */\nexport interface SwipeGroup {\n set(layer: LayerHandle): void;\n unset(layer: LayerHandle): void;\n other?: SwipeGroup;\n}\n\nexport const SwipeContext = createContext<SwipeGroup | undefined>(undefined);\n\n/** The marker of a `<Marker>` around and its position (a `<Popup>` in it opens on its click, at that position) */\nexport const MarkerContext = createContext<{ marker: MarkerHandle; lonLat: LonLat } | undefined>(undefined);\n\n/** The map of the `<IsardMap>` around, once created (undefined before) */\nexport const useMap = (): GeoMap | undefined => useContext(MapContext)?.map;\n\n/** Listens to an event of the map around while the component is mounted; the listener may change at each render */\nexport const useMapEvent = <K extends keyof MapEvents>(type: K, listener: (event: MapEvents[K]) => void): void => {\n const map = useMap();\n const latest = useRef(listener);\n\n latest.current = listener;\n // Listening while mounted, to the listener of the last render; stops when unmounted or the map changes\n useEffect(() => map?.on(type, (event) => latest.current(event)), [map, type]);\n};\n\n/** The entries of an object whose value is defined (`exactOptionalPropertyTypes`) */\nexport const defined = <T extends object>(object: T): { [K in keyof T]?: Exclude<T[K], undefined> } =>\n Object.fromEntries(Object.entries(object).filter(([, value]) => value !== undefined)) as {\n [K in keyof T]?: Exclude<T[K], undefined>;\n };\n"]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -22,5 +22,6 @@ export { Layer, type LayerHandles, type LayerProps, type LayerType } from './Lay
|
|
|
22
22
|
export { Marker, type MarkerProps } from './Marker.tsx';
|
|
23
23
|
export { Panel, type PanelProps } from './Panel.tsx';
|
|
24
24
|
export { Popup, type PopupProps } from './Popup.tsx';
|
|
25
|
-
export { Swipe, type SwipeProps } from './Swipe.tsx';
|
|
25
|
+
export { Swipe, SwipeOther, type SwipeProps } from './Swipe.tsx';
|
|
26
|
+
export { VectorGeometry, type VectorGeometryProps } from './VectorGeometry.tsx';
|
|
26
27
|
export { Viewshed } from './Viewshed.tsx';
|
package/dist/react/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export { Layer } from "./Layer.js";
|
|
|
17
17
|
export { Marker } from "./Marker.js";
|
|
18
18
|
export { Panel } from "./Panel.js";
|
|
19
19
|
export { Popup } from "./Popup.js";
|
|
20
|
-
export { Swipe } from "./Swipe.js";
|
|
20
|
+
export { Swipe, SwipeOther } from "./Swipe.js";
|
|
21
|
+
export { VectorGeometry } from "./VectorGeometry.js";
|
|
21
22
|
export { Viewshed } from "./Viewshed.js";
|
|
22
23
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,OAAO,EAAqB,MAAM,cAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAmB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAA0C,MAAM,eAAgB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAsD,MAAM,YAAa,CAAC;AACxF,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAc,CAAC;AACxD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,OAAO,EAAqB,MAAM,cAAe,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAyB,MAAM,kBAAmB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAA0C,MAAM,eAAgB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAsD,MAAM,YAAa,CAAC;AACxF,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAc,CAAC;AACxD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAa,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAmB,MAAM,YAAa,CAAC;AACjE,OAAO,EAAE,cAAc,EAA4B,MAAM,qBAAsB,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC","sourcesContent":["/**\n * Isard in React: the map, its layers, markers, popups, panels and effects as components, created when they mount,\n * updated by the least their props need and removed when they unmount.\n *\n * ```tsx\n * <IsardMap preset=\"ign-3d\" center={[2.35, 48.85]} zoom={15} style={{ height: 400 }}>\n * <Layer type=\"lines\" data={routes} color=\"#0057b8\" width={3} />\n * <Marker lonLat={[2.35, 48.85]}><Popup>Here</Popup></Marker>\n * </IsardMap>\n * ```\n */\n\nexport type { Layer as LayerHandle } from '../layers/layers.ts';\nexport type { GeoMap, LayerSpec } from '../map.ts';\nexport type { LonLat } from '../types.ts';\nexport type { Marker as MarkerHandle, Panel as PanelHandle, Popup as PopupHandle } from '../ui/overlay.ts';\nexport type { Camera } from '../wasm/isard.js';\nexport { Control, type ControlProps } from './Control.tsx';\nexport { CustomLayer, type CustomLayerProps } from './CustomLayer.tsx';\nexport { useMap, useMapEvent } from './context.ts';\nexport { IsardMap, type IsardMapProps, type MapEventProps } from './IsardMap.tsx';\nexport { Layer, type LayerHandles, type LayerProps, type LayerType } from './Layer.tsx';\nexport { Marker, type MarkerProps } from './Marker.tsx';\nexport { Panel, type PanelProps } from './Panel.tsx';\nexport { Popup, type PopupProps } from './Popup.tsx';\nexport { Swipe, SwipeOther, type SwipeProps } from './Swipe.tsx';\nexport { VectorGeometry, type VectorGeometryProps } from './VectorGeometry.tsx';\nexport { Viewshed } from './Viewshed.tsx';\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -9,11 +9,12 @@ export type LonLat = [lon: number, lat: number];
|
|
|
9
9
|
export type Point = [x: number, y: number];
|
|
10
10
|
/**
|
|
11
11
|
* The named basemaps. OpenFreeMap's vector styles, OpenStreetMap data worldwide, their labels above the other layers:
|
|
12
|
-
* `osm-positron` (light grey, quiet: data over it reads first), `osm-liberty` and `osm-bright` (in colour)
|
|
12
|
+
* `osm-positron` (light grey, quiet: data over it reads first), `osm-liberty` and `osm-bright` (in colour), `osm-dark`
|
|
13
|
+
* (near black: bright data over it, a wind's particles, lights). The
|
|
13
14
|
* Géoplateforme's (IGN, France): rasters (`ign-plan`, `ign-plan-grey`, `ign-ortho`, the aerial photographs) or vector
|
|
14
15
|
* tiles with their labels (`ign-plan-vector`, `ign-plan-grey-vector`, the PLAN.IGN styles).
|
|
15
16
|
*/
|
|
16
|
-
export type BasemapName = 'osm-positron' | 'osm-liberty' | 'osm-bright' | 'ign-plan' | 'ign-plan-grey' | 'ign-ortho' | 'ign-plan-vector' | 'ign-plan-grey-vector' | 'none';
|
|
17
|
+
export type BasemapName = 'osm-positron' | 'osm-liberty' | 'osm-bright' | 'osm-dark' | 'ign-plan' | 'ign-plan-grey' | 'ign-ortho' | 'ign-plan-vector' | 'ign-plan-grey-vector' | 'none';
|
|
17
18
|
/** A basemap by name (see `BasemapName`) */
|
|
18
19
|
export type Basemap = BasemapName;
|
|
19
20
|
/**
|
|
@@ -74,6 +75,8 @@ export interface GeoMapOptions extends Partial<Camera> {
|
|
|
74
75
|
background?: string;
|
|
75
76
|
/** Space behind the globe: stars and atmosphere halo, fading out as the globe turns flat (default true) */
|
|
76
77
|
sky?: boolean;
|
|
78
|
+
/** The sun casting the shadows of buildings, trees, models and the relief (`setSun`); none by default */
|
|
79
|
+
sun?: SunOptions;
|
|
77
80
|
/** Relief under the basemap: true for the body's terrain model (on the Earth the worldwide Terrain Tiles; NASA's on
|
|
78
81
|
* the Moon and Mars: LOLA, MOLA), one of the Earth's models by name (`'ign'`: France, RGE ALTI), or its options
|
|
79
82
|
* (default false; on another body, its `url` is required). Network layers are draped on it */
|
|
@@ -96,7 +99,7 @@ export interface GeoMapOptions extends Partial<Camera> {
|
|
|
96
99
|
/** A preset of map options (`IGN_PRESETS`: `'ign'`, `'ign-3d'`, `'ign-ortho-3d'`), the other options over it */
|
|
97
100
|
preset?: 'ign' | 'ign-3d' | 'ign-ortho-3d';
|
|
98
101
|
/** The folder isard's files are served from (its engines, `isard_bg.wasm`, `isard_core_bg.wasm`,
|
|
99
|
-
* `isard_points_bg.wasm`, and its workers, `decoder.worker.js`, `basemap.worker.js`): one option for a bundler that
|
|
102
|
+
* `isard_points_bg.wasm`, `isard_tess_bg.wasm`, `isard_grid_bg.wasm`, and its workers, `decoder.worker.js`, `basemap.worker.js`): one option for a bundler that
|
|
100
103
|
* moves them, the `…Url` options below for each one. `isard/vite` sets it for the whole page; default next to the
|
|
101
104
|
* module */
|
|
102
105
|
assetsUrl?: string | URL;
|
|
@@ -110,6 +113,13 @@ export interface GeoMapOptions extends Partial<Camera> {
|
|
|
110
113
|
/** Where the decoding workers load the point cloud module from (`isard_points_bg.wasm`, the LAZ decoder of COPC),
|
|
111
114
|
* when a bundler does not resolve the default URL. Loaded with the first point cloud only */
|
|
112
115
|
pointsWasmUrl?: string | URL;
|
|
116
|
+
/** Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`: the vector tiles drawn as
|
|
117
|
+
* geometry, `vectorTiles().vectors()`, made ready for the GPU off the main thread), when a bundler does not resolve
|
|
118
|
+
* the default URL. Loaded with the first tile of geometry; without it, the main thread does that work */
|
|
119
|
+
tessWasmUrl?: string | URL;
|
|
120
|
+
/** Where the workers load the grid module from (`isard_grid_bg.wasm`: GRIB2 and NetCDF files read by
|
|
121
|
+
* `map.readGrids`), when a bundler does not resolve the default URL. Loaded with the first file */
|
|
122
|
+
gridWasmUrl?: string | URL;
|
|
113
123
|
/** Load the engine with 3D Tiles from the start (default false: it is loaded when the first 3D Tiles layer or glTF
|
|
114
124
|
* model is added, the map then moving its camera and layers onto it, a stall of about a frame or two). For a map that shows 3D Tiles
|
|
115
125
|
* at once: one engine downloaded instead of two. `'preload'`: the map starts on the engine without 3D Tiles and
|
|
@@ -175,6 +185,21 @@ export interface AtmosphereOptions {
|
|
|
175
185
|
/** Share of the distance to the far plane over which the ground fades into the fog, 0-1 (default 0.4) */
|
|
176
186
|
fogGroundBlend?: number;
|
|
177
187
|
}
|
|
188
|
+
/** The sun casting shadows (`GeoMap.setSun`): where it stands, by date or by hand, and how dark its shadows are */
|
|
189
|
+
export interface SunOptions {
|
|
190
|
+
/** The time: the sun where it stands then over the map's center (default now, unless `azimuth` and `altitude`) */
|
|
191
|
+
date?: Date;
|
|
192
|
+
/** Degrees clockwise from north, with `altitude`: the sun placed by hand */
|
|
193
|
+
azimuth?: number;
|
|
194
|
+
/** Degrees above the horizon; at or under it, no shadows */
|
|
195
|
+
altitude?: number;
|
|
196
|
+
/** How dark the shadows are, 0 to 1 (default 0.35) */
|
|
197
|
+
opacity?: number;
|
|
198
|
+
/** How dark the night is, 0 to 1: the scene tinted in its blue, the windows of the buildings and the streets of
|
|
199
|
+
* `vectors()` lit, the labels light on dark. By default from the sun's altitude: falling from 6° above the horizon
|
|
200
|
+
* to 6° under it */
|
|
201
|
+
night?: number;
|
|
202
|
+
}
|
|
178
203
|
/** What can be seen from a point (`GeoMap.setViewshed`); with several observers, the colors, the opacity and the
|
|
179
204
|
* cone's color are the first one's */
|
|
180
205
|
export interface ViewshedOptions {
|
|
@@ -223,6 +248,8 @@ export interface SwipeOptions {
|
|
|
223
248
|
layers: readonly Layer[];
|
|
224
249
|
/** The side they show on (default 'left') */
|
|
225
250
|
side?: 'left' | 'right';
|
|
251
|
+
/** Layers shown on the other side only: two meshes of the same place, each on its side, never drawn over each other */
|
|
252
|
+
other?: readonly Layer[];
|
|
226
253
|
}
|
|
227
254
|
/** Animation of a camera move */
|
|
228
255
|
export interface AnimationOptions {
|