<script lang="ts"> export let position: undefined | { lat: number; lng: number } export let azimuth: undefined | number export let inclinaison: undefined | number import { onMount } from 'svelte' const assets = '/static' const mapsrv = 'https://wxs.ign.fr/essentiels/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/png&LAYER=GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2&' import { browser } from '$app/environment' export let zoom = 5 let dot: null | L.Marker = null let redIcon: any = null let map: any = null onMount(async () => { console.log('map onload', browser) if (!browser) { return } const L = await import('leaflet') await import('leaflet.fullscreen') const G = await import('leaflet-gesture-handling') // @ts-ignore L.Map.addInitHook('addHandler', 'gestureHandling', G.GestureHandling) map = L.map('descrmap', { // @ts-ignore fullscreenControl: true, fullscreenControlOptions: { position: 'topleft', }, // @ts-ignore gestureHandling: true, // attributionControl: false, }) ;(<any>document).coturnixMap = map if (position) { map.setView(position, zoom) } else { map.setView({ lat: 46, lng: 3 }, 5) } let layer = L.tileLayer( `${mapsrv}TILEMATRIX={z}&TILEROW={y}&TILECOL={x}`, { minZoom: 0, maxZoom: 18, attribution: 'IGN-F/Geoportail', tileSize: 256, noWrap: true, } ).addTo(map) layer.on('tileerror', (e) => { console.log(e) // e.tile.src = `${mapsrv}TILEMATRIX=${e.coords.z}&TILEROW=${e.coords.y}&TILECOL=${e.coords.x}` }) if (!redIcon) { redIcon = L.icon({ iconUrl: `${assets}/marker-icon-red.png`, iconRetinaUrl: `${assets}/marker-icon-red.png`, shadowUrl: `${assets}/marker-shadow.png`, iconAnchor: [12, 41], } as L.IconOptions) } if (position) { dot = L.marker(position, { icon: redIcon!, draggable: false, }) dot.addTo(map) } // position = { lat: 45, lng: 3 } map.on('click', function (e: any) { position = e.latlng console.log(position) if (dot) { dot.setLatLng(position!) } else { dot = L.marker(position!, { icon: redIcon!, draggable: false, }) dot.addTo(map) } }) recentrer() }) function recentrer(zoom?: number) { if (!position || !map) { return } let lng0 = 180 let lng1 = -180 let lat0 = 90 let lat1 = -90 let mar = 0.5 / 111.111 // 500m en longitude (111.111km par degré) let lat2 = position.lat - mar let lat3 = position.lat + mar let dx = mar / Math.cos((position.lat * Math.PI) / 180) let lng2 = position.lng - dx let lng3 = position.lng + dx lng0 = Math.min(lng0, lng2) lng1 = Math.max(lng1, lng3) lat0 = Math.min(lat0, lat2) lat1 = Math.max(lat1, lat3) if (lng0 < lng1 && lat0 < lat1) { console.log([ [lat0, lng0], [lat1, lng1], ]) map.fitBounds( [ [lat0, lng0], [lat1, lng1], ], { maxZoom: 14 } ) } else { map.setView(position, zoom) } } </script> <svelte:head> <link rel="stylesheet" href="{assets}/leaflet.css" /> <link rel="stylesheet" href="{assets}/leafletfs.css" /> <link rel="stylesheet" href="{assets}/leaflet-gesture-handling.min.css" /> </svelte:head> <div id="descrmap" class="w-100" style="height:500px" /> <div class="d-flex flex-column"> <button class="btn btn-sm btn-outline-secondary my-2 ms-auto" on:click={(_) => recentrer(zoom)}>Recentrer</button> <div class="my-3"> <label class="form-label" for="azimuth" >Azimuth (degrés par rapport au Nord):</label> <input type="number" class="form-control" id="azimuth" bind:value={azimuth} /> </div> <div class="my-3"> <label class="form-label" for="incl">Inclinaison:</label> <input type="number" class="form-control" id="incl" bind:value={inclinaison} /> </div> </div>