|
1 | 1 | <script lang="ts"> |
2 | | - import { onDestroy, type Snippet } from 'svelte'; |
| 2 | + import { onDestroy, onMount, type Snippet } from 'svelte'; |
3 | 3 | import { type Map, type SourceSpecification } from 'maplibre-gl'; |
4 | | - import { getMapContext, createSourceContext, SourceContext } from '../context.svelte.js'; |
5 | | -
|
6 | | - type Source = maplibregl.VectorTileSource | maplibregl.GeoJSONSource; |
| 4 | + import { getMapContext } from '../context.svelte.js'; |
7 | 5 |
|
8 | 6 | interface MapSourceProps { |
9 | 7 | id: string; |
| 8 | + source?: maplibregl.VectorTileSource | maplibregl.GeoJSONSource; |
10 | 9 | sourceSpec: SourceSpecification; |
11 | | - source?: Source; |
12 | 10 | onLoad?: (map: Map, url?: string, data?: string) => undefined; |
13 | 11 | children?: Snippet; |
14 | 12 | } |
15 | 13 |
|
16 | 14 | let { id, sourceSpec, source = $bindable(), children }: MapSourceProps = $props(); |
17 | 15 |
|
| 16 | + const ctx = getMapContext(); |
18 | 17 | let firstRun = $state(true); |
19 | 18 |
|
20 | | - // Get map context |
21 | | - const { map, styleLoaded } = $derived(getMapContext()); |
22 | | -
|
23 | | - // Create source context |
24 | | - const sourceContext = createSourceContext(); |
25 | | -
|
26 | | - // 1. Add the source to the map using the spec, then get the |
27 | | - // actual source object back from the map instance |
28 | 19 | $effect(() => { |
29 | | - if (map && styleLoaded && firstRun) { |
30 | | - map.addSource(id, $state.snapshot(sourceSpec)); |
31 | | - source = map.getSource(id); |
32 | | - firstRun = false; |
33 | | - } |
| 20 | + ctx.waitForStyleLoaded(() => { |
| 21 | + ctx.addSource(id, sourceSpec); |
| 22 | + }); |
| 23 | + firstRun = false; |
34 | 24 | }); |
35 | 25 |
|
36 | 26 | $effect(() => { |
37 | | - if (source && sourceSpec.type === 'geojson') { |
38 | | - if (firstRun === false) { |
39 | | - source.setData(sourceSpec.data); |
40 | | - } |
| 27 | + if (!firstRun && source && source.type === 'geojson') { |
| 28 | + source.setData(sourceSpec.data); |
41 | 29 | } |
42 | 30 | }); |
43 | 31 |
|
44 | 32 | $effect(() => { |
45 | | - if (!firstRun && source.setTiles) { |
| 33 | + if (!firstRun && source && source.type === 'vector') { |
46 | 34 | source.setTiles(sourceSpec.tiles); |
47 | 35 | } |
48 | 36 | }); |
49 | 37 |
|
50 | 38 | $effect(() => { |
51 | | - if (!firstRun && source.setUrl) { |
| 39 | + if (!firstRun && source) { |
52 | 40 | source.setUrl(sourceSpec.url); |
53 | 41 | } |
54 | 42 | }); |
55 | 43 |
|
56 | 44 | onDestroy(() => { |
57 | | - if (map && styleLoaded) { |
58 | | - const layers = map?.getStyle().layers; |
59 | | - layers |
60 | | - .filter((l) => l.type !== 'background' && l.source == id) |
61 | | - .forEach((l) => { |
62 | | - map?.removeLayer(l.id); |
63 | | - }); |
64 | | - map.removeSource(id); |
65 | | - source = undefined; |
66 | | - } |
| 45 | + ctx.removeSource(id); |
67 | 46 | }); |
68 | 47 | </script> |
69 | 48 |
|
70 | | -{@render children?.()} |
| 49 | +{#if !firstRun} |
| 50 | + {@render children?.()} |
| 51 | +{/if} |
0 commit comments