feat: make map reactive
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 35s
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 35s
This commit is contained in:
parent
080f8f80b3
commit
b24cbc84bf
2 changed files with 47 additions and 30 deletions
|
@ -11,8 +11,10 @@
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
import { page } from "$app/stores";
|
|
||||||
import L from "leaflet";
|
import L from "leaflet";
|
||||||
|
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
|
@ -12,60 +11,76 @@
|
||||||
let { data }: Props = $props();
|
let { data }: Props = $props();
|
||||||
|
|
||||||
const lignes = data.lines;
|
const lignes = data.lines;
|
||||||
const params = $page.url.searchParams;
|
const point = L.latLng(45.75388713, 4.84715287);
|
||||||
const center = L.latLng(45.75388713, 4.84715287);
|
|
||||||
|
const bbox = lignes.bbox || [0, 0, 0, 0];
|
||||||
|
const center = L.latLng((bbox[1] + bbox[3]) / 2, (bbox[0] + bbox[2]) / 2);
|
||||||
|
|
||||||
|
const linesJson = lignes.features.map((feature) => {
|
||||||
|
let color = "rgb(" + feature.properties?.couleur?.replaceAll(" ", ",") + ")";
|
||||||
|
return L.geoJSON(feature, { style: { color } });
|
||||||
|
});
|
||||||
|
|
||||||
let latlng = $state(L.latLng(0, 0));
|
let latlng = $state(L.latLng(0, 0));
|
||||||
let distance = $derived(Math.max(0, latlng.distanceTo(center) - 20));
|
let distance = $derived(Math.max(0, latlng.distanceTo(point) - 20));
|
||||||
let points = $derived(5000 * Math.exp(-distance / 750));
|
let points = $derived(5000 * Math.exp(-distance / 750));
|
||||||
|
|
||||||
function createMap(node: HTMLElement) {
|
let lines = $state(true);
|
||||||
const bbox = lignes.bbox || [0, 0, 0, 0];
|
let labels = $state(false);
|
||||||
const centerLat = (bbox[1] + bbox[3]) / 2;
|
|
||||||
const centerLon = (bbox[0] + bbox[2]) / 2;
|
|
||||||
|
|
||||||
const map = L.map(node).setView([centerLat, centerLon], 13);
|
let map: L.Map | null = $state(null);
|
||||||
const mapSuffix = params.has("labels") ? "all" : "nolabels";
|
let tileLayer = $derived(
|
||||||
|
L.tileLayer(
|
||||||
L.tileLayer(`https://basemaps.cartocdn.com/light_${mapSuffix}/{z}/{x}/{y}{r}.png`, {
|
`https://basemaps.cartocdn.com/light_${labels ? "all" : "nolabels"}/{z}/{x}/{y}{r}.png`,
|
||||||
|
{
|
||||||
attribution:
|
attribution:
|
||||||
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||||
maxZoom: 20,
|
maxZoom: 20,
|
||||||
}).addTo(map);
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (params.has("lines")) {
|
$effect(() => {
|
||||||
lignes.features.forEach((feature) => {
|
if (!map) return;
|
||||||
let color = "black";
|
tileLayer.addTo(map);
|
||||||
|
|
||||||
if (feature.properties && feature.properties.couleur) {
|
if (lines) {
|
||||||
color = "rgb(" + feature.properties.couleur.replaceAll(" ", ",") + ")";
|
linesJson.forEach((line) => map && line.addTo(map));
|
||||||
|
} else {
|
||||||
|
linesJson.forEach((line) => map && line.removeFrom(map));
|
||||||
}
|
}
|
||||||
|
|
||||||
L.geoJSON(feature, { style: { color } }).addTo(map);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
function createMap(node: HTMLElement) {
|
||||||
|
map = L.map(node).setView(center, 13);
|
||||||
|
|
||||||
const marker = L.marker([0, 0]);
|
const marker = L.marker([0, 0]);
|
||||||
map.on("click", (e) => {
|
map.on("click", (e) => {
|
||||||
marker.setLatLng(e.latlng).addTo(map);
|
if (map) marker.setLatLng(e.latlng).addTo(map);
|
||||||
latlng = e.latlng;
|
latlng = e.latlng;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="info">
|
<div class="banner">
|
||||||
<span>distance: {distance}, points: {points}</span>
|
<span>distance: {distance}, points: {points}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="banner">
|
||||||
|
<label>lines: <input type="checkbox" bind:checked={lines} /></label>
|
||||||
|
<label>labels: <input type="checkbox" bind:checked={labels} /></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="map" use:createMap></div>
|
<div id="map" use:createMap></div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#info {
|
.banner {
|
||||||
height: 5vh;
|
padding: 4px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
height: 95vh;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue