Skip to content

Commit a640485

Browse files
authored
fix: $state.snapshot(style) (#81)
1 parent cfe7d21 commit a640485

File tree

4 files changed

+88
-15
lines changed

4 files changed

+88
-15
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "svelte-maplibre-gl",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"license": "(MIT OR Apache-2.0)",
55
"description": "Build interactive web maps effortlessly with MapLibre GL JS and Svelte",
66
"repository": {

src/content/examples/basestyle/BaseStyle.svelte

+84-12
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,84 @@
55
LineLayer,
66
MapLibre,
77
Projection,
8+
ImageLoader,
89
RasterDEMTileSource,
910
Sky,
1011
Terrain,
12+
GeoJSONSource,
13+
SymbolLayer,
1114
VectorTileSource
1215
} from 'svelte-maplibre-gl';
1316
1417
import { Label } from '$lib/components/ui/label/index.js';
1518
import * as RadioGroup from '$lib/components/ui/radio-group/index.js';
1619
import { Switch } from '$lib/components/ui/switch/index.js';
20+
import type { FeatureCollection } from 'geojson';
1721
18-
const STYLES = [
19-
{ name: 'Voyager', url: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json' },
20-
{ name: 'Positron', url: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json' },
21-
{ name: 'Dark Matter', url: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json' },
22-
{ name: 'Demo Tiles', url: 'https://demotiles.maplibre.org/style.json' }
23-
];
24-
let styleUrl = $state(STYLES[0].url);
22+
// Base styles
23+
const STYLES = new Map<string, string | maplibregl.StyleSpecification>([
24+
['Voyager', 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'],
25+
['Positron', 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json'],
26+
['Dark Matter', 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json'],
27+
['Demo Tiles', 'https://demotiles.maplibre.org/style.json'],
28+
[
29+
'GSI Seamlessphoto',
30+
{
31+
version: 8,
32+
sources: {
33+
basemap: {
34+
type: 'raster',
35+
tiles: ['https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg'],
36+
tileSize: 256,
37+
minzoom: 2,
38+
maxzoom: 18,
39+
attribution:
40+
"<a href='https://maps.gsi.go.jp/development/ichiran.html#seamlessphoto' target='_blank'>GSI, TSIC, AIST, NASA, USGS, GEBCO</a>"
41+
}
42+
},
43+
layers: [{ id: 'basemap', type: 'raster', source: 'basemap' }]
44+
} satisfies maplibregl.StyleSpecification
45+
],
46+
[
47+
'GSI Standard',
48+
{
49+
version: 8,
50+
sources: {
51+
basemap: {
52+
type: 'raster',
53+
tiles: ['https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png'],
54+
tileSize: 256,
55+
minzoom: 5,
56+
maxzoom: 18,
57+
attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html#std' target='_blank'>GSI</a>"
58+
}
59+
},
60+
layers: [{ id: 'basemap', type: 'raster', source: 'basemap' }]
61+
}
62+
]
63+
]);
64+
let name = $state('Voyager');
65+
let style = $derived(STYLES.get(name)!);
2566
let globe = $state(true);
67+
68+
let data: FeatureCollection = {
69+
type: 'FeatureCollection',
70+
features: [
71+
{
72+
type: 'Feature',
73+
geometry: { type: 'Point', coordinates: [140, 30] },
74+
properties: { imageName: 'osgeo', year: 2024 }
75+
}
76+
]
77+
};
2678
</script>
2779

2880
<div class="mb-3 flex items-center justify-between">
29-
<RadioGroup.Root bind:value={styleUrl} class="flex flex-row gap-x-3">
30-
{#each STYLES as style}
81+
<RadioGroup.Root bind:value={name} class="flex flex-row gap-x-3">
82+
{#each STYLES as [name, _]}
3183
<div class="flex items-center space-x-1">
32-
<RadioGroup.Item value={style.url} id={style.name} />
33-
<Label class="cursor-pointer" for={style.name}>{style.name}</Label>
84+
<RadioGroup.Item value={name} id={name} />
85+
<Label class="cursor-pointer" for={name}>{name}</Label>
3486
</div>
3587
{/each}
3688
</RadioGroup.Root>
@@ -41,7 +93,8 @@
4193
</div>
4294
</div>
4395

44-
<MapLibre class="h-[55vh] min-h-[300px]" style={styleUrl} zoom={4} maxPitch={80} center={{ lng: 137, lat: 36 }}>
96+
<MapLibre class="h-[55vh] min-h-[300px]" {style} zoom={4} maxPitch={80} center={{ lng: 137, lat: 36 }}>
97+
<!-- User-defined dynamic styles -->
4598
<Projection type={globe ? 'globe' : undefined} />
4699
<Light anchor="map" />
47100
<Sky
@@ -86,4 +139,23 @@
86139
<Terrain />
87140
</RasterDEMTileSource>
88141
{/if}
142+
<ImageLoader
143+
images={{
144+
osgeo: 'https://maplibre.org/maplibre-gl-js/docs/assets/osgeo-logo.png'
145+
}}
146+
>
147+
<GeoJSONSource {data}>
148+
<!-- Children components will be added after all images have been loaded -->
149+
<SymbolLayer
150+
layout={{
151+
'text-field': ['get', 'name'],
152+
'icon-image': ['get', 'imageName'],
153+
'icon-size': ['number', ['get', 'scale'], 1],
154+
'icon-text-fit': 'both',
155+
'icon-overlap': 'always',
156+
'text-overlap': 'always'
157+
}}
158+
/>
159+
</GeoJSONSource>
160+
</ImageLoader>
89161
</MapLibre>

src/lib/maplibre/contexts.svelte.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class MapContext {
121121
return;
122122
}
123123

124-
this.map?.setStyle(style, {
124+
this.map?.setStyle($state.snapshot(style) as string | StyleSpecification, {
125125
// Preserves user styles when the base style changes
126126
transformStyle: (previous, next) => {
127127
this.baseLight = next.light;

src/lib/maplibre/map/MapLibre.svelte

+2-1
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@
489489
}
490490
});
491491
$effect(() => {
492-
if (style && !firstRun) {
492+
style;
493+
if (!firstRun) {
493494
mapCtx.setStyle(style);
494495
}
495496
});

0 commit comments

Comments
 (0)