switch to mapbox gl

This commit is contained in:
vcoppe
2024-04-10 14:54:35 +02:00
parent 588175d30c
commit 8fcdc13caf
6 changed files with 1027 additions and 380 deletions

2
todo
View File

@@ -1,2 +0,0 @@
- state management with https://immerjs.github.io/immer/
- map with MapLibre

1258
website/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -39,12 +39,12 @@
"dependencies": { "dependencies": {
"@fortawesome/free-brands-svg-icons": "^6.5.2", "@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2", "@fortawesome/free-solid-svg-icons": "^6.5.2",
"@maplibre/maplibre-gl-geocoder": "^1.5.0", "@mapbox/mapbox-gl-geocoder": "^5.0.2",
"bits-ui": "^0.21.2", "bits-ui": "^0.21.2",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"gpx": "file:../gpx", "gpx": "file:../gpx",
"lucide-svelte": "^0.365.0", "lucide-svelte": "^0.365.0",
"maplibre-gl": "^4.1.2", "mapbox-gl": "^3.2.0",
"svelte-fa": "^4.0.2", "svelte-fa": "^4.0.2",
"tailwind-merge": "^2.2.2", "tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1" "tailwind-variants": "^0.2.1"

View File

@@ -1,86 +1,103 @@
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from 'svelte'; import { onMount, onDestroy } from 'svelte';
import maplibregl from 'maplibre-gl'; import mapboxgl from 'mapbox-gl';
import 'maplibre-gl/dist/maplibre-gl.css'; import 'mapbox-gl/dist/mapbox-gl.css';
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'; import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
export let map: maplibregl.Map | null = null; mapboxgl.accessToken =
'pk.eyJ1IjoiZ3B4c3R1ZGlvIiwiYSI6ImNrdHVoM2pjNTBodmUycG1yZTNwcnJ3MzkifQ.YZnNs9s9oCQPzoXAWs_SLg';
let map: mapboxgl.Map | null = null;
export let distanceUnits: 'metric' | 'imperial' = 'metric';
onMount(() => { onMount(() => {
map = new maplibregl.Map({ map = new mapboxgl.Map({
container: 'map', container: 'map',
style: 'https://demotiles.maplibre.org/style.json' style: 'mapbox://styles/mapbox/outdoors-v12',
projection: 'mercator',
hash: true,
language: 'auto',
attributionControl: false,
logoPosition: 'bottom-right'
}); });
map.addControl( map.addControl(
new maplibregl.NavigationControl({ new mapboxgl.AttributionControl({
showCompass: false compact: true
}) })
); );
map.addControl( map.addControl(new mapboxgl.NavigationControl());
new maplibregl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
})
);
const geocoderApi = {
forwardGeocode: async (config) => {
const features = [];
try {
const request = `https://nominatim.openstreetmap.org/search?q=${config.query}&format=geojson&polygon_geojson=1&addressdetails=1`;
const response = await fetch(request);
const geojson = await response.json();
for (const feature of geojson.features) {
const center = [
feature.bbox[0] + (feature.bbox[2] - feature.bbox[0]) / 2,
feature.bbox[1] + (feature.bbox[3] - feature.bbox[1]) / 2
];
const point = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: center
},
place_name: feature.properties.display_name,
properties: feature.properties,
text: feature.properties.display_name,
place_type: ['place'],
center
};
features.push(point);
}
} catch (e) {
console.error(`Failed to forwardGeocode with error: ${e}`);
}
return {
features
};
}
};
map.addControl( map.addControl(
new MaplibreGeocoder(geocoderApi, { new MapboxGeocoder({
maplibregl, accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
collapsed: true collapsed: true
}) })
); );
});
onDestroy(() => { map.addControl(
if (map) { new mapboxgl.GeolocateControl({
map.remove(); positionOptions: {
} enableHighAccuracy: true
},
trackUserLocation: true,
showUserHeading: true
})
);
map.addControl(
new mapboxgl.ScaleControl({
unit: distanceUnits
})
);
}); });
</script> </script>
<div {...$$restProps}> <div {...$$restProps}>
<div id="map" class="h-full"></div> <div id="map" class="h-full"></div>
</div> </div>
<style lang="postcss">
div :global(.mapboxgl-ctrl) {
@apply shadow-md;
}
div :global(.mapboxgl-ctrl-geocoder) {
@apply flex;
@apply flex-row;
@apply w-fit;
@apply min-w-fit;
@apply items-center;
@apply shadow-md;
}
div :global(.suggestions) {
@apply shadow-md;
}
div :global(.mapboxgl-ctrl-geocoder--icon-search) {
@apply fill-inherit;
@apply relative;
@apply top-0;
@apply left-0;
@apply my-2;
@apply w-[29px];
}
div :global(.mapboxgl-ctrl-geocoder--input) {
@apply relative;
@apply py-0;
@apply pl-2;
@apply focus:outline-none;
}
div :global(.mapboxgl-ctrl-geocoder--collapsed .mapboxgl-ctrl-geocoder--input) {
@apply hidden;
}
</style>

View File

@@ -11,7 +11,9 @@
</script> </script>
<div class="absolute top-2 left-0 right-0 z-10 flex flex-row justify-center pointer-events-none"> <div class="absolute top-2 left-0 right-0 z-10 flex flex-row justify-center pointer-events-none">
<div class="w-fit flex flex-row items-center p-1 bg-background rounded-md pointer-events-auto"> <div
class="w-fit flex flex-row items-center p-1 bg-background rounded-md pointer-events-auto shadow-md"
>
<Logo class="h-5 mt-0.5 mx-2" /> <Logo class="h-5 mt-0.5 mx-2" />
<Menubar.Root class="border-none h-fit p-0"> <Menubar.Root class="border-none h-fit p-0">
<Menubar.Menu> <Menubar.Menu>

View File

@@ -19,7 +19,7 @@
</script> </script>
<div class="absolute top-0 bottom-0 left-0 z-10 flex flex-col justify-center pointer-events-none"> <div class="absolute top-0 bottom-0 left-0 z-10 flex flex-col justify-center pointer-events-none">
<div class="flex flex-col p-1 space-y-1 bg-background rounded-md pointer-events-auto"> <div class="flex flex-col p-1 space-y-1 bg-background rounded-md pointer-events-auto shadow-md">
<ToolbarItem> <ToolbarItem>
<Fa slot="icon" icon={faPencil} /> <Fa slot="icon" icon={faPencil} />
<span slot="tooltip">Edit the track points</span> <span slot="tooltip">Edit the track points</span>