import * as L from "./lib/leaflet/leaflet-src.esm.js" import { MapSubFeature, PlaceDatabase } from "./places.js"; import "./lib/turf/turf.js" let map = null; /** @type {PlaceDatabase| null} */ let places = null; export async function init(){ /** Le centre de la carte */ let map_center = null /** Les bords de la carte */ let map_bounds = null map = L.map(document.getElementById("map"), { attributionControl: false, zoomControl: false, zoomSnap: 1, zoomDelta: 1 }) { let zoom_interval = null function updateCssZoom(){ map.getContainer() .style.setProperty("--zoom-level", map.getZoom()) } map.addEventListener("zoom", updateCssZoom) map.addEventListener("zoomstart", () => { zoom_interval = setInterval(updateCssZoom, 50) updateCssZoom() }) map.addEventListener("zoomend", () => { zoom_interval = clearInterval(zoom_interval) updateCssZoom() }) } L.control.attribution({ position: 'topright' }).addTo(map) await Promise.all([ // Point définissant le centre de la carte fetch("./couches/centre.geojson").then(res => res.json()).then(geojson => { map_center = L.latLng([...geojson.features[0].geometry.coordinates].reverse()) console.log("Centre:", map_center) }), // Polygone définissant les limites de la carte fetch("./couches/emprise.geojson").then(res => res.json()).then(geojson => { let coordinate_list = geojson.features[0].geometry.coordinates[0] let first_point = L.latLng([...coordinate_list[0]].reverse()) let bounds = L.latLngBounds(first_point, first_point) for(let i = 1; i { if(map_bounds.contains(map.getCenter())){ map.setMaxZoom(21) } else { map.setMaxZoom(18) } }) // La couche Openstreetmap standard L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map) // La couche custom de l'antenne L.tileLayer('./tuiles/{z}/{x}/{y}.png', { minZoom: 19, maxZoom: 21 }).addTo(map) L.marker( map_center, { icon: L.divIcon({ html: `Logo du camp interhack`, className: "center-marker" }), title: "Camp Interhack 2026", } ).addTo(map) // Parametrage de la carte initiale //map.setMaxBounds(map_bounds) map.setView(map_center, 19, { animate: false, }) } const HIGHLIGHT_LAYER = Symbol("Highlight map layer") const AMENITY_MARKER_LAYER = Symbol("Amenity marker layer") const PARENT_FEATURE = Symbol("Parent feature") export async function init_places(places_db){ places = places_db // La couche des zones disponibles const area_highlight = L.geoJSON(null, { pointToLayer: function(feature, latlng) { let symbol = feature.mapSymbol; if(symbol.markerUrl) { let iconEl = document.createElement("img"); iconEl.src = symbol.markerUrl; if(iconEl){ return L.marker(latlng, { icon: L.divIcon({ className: "highlight-point-icon", html: iconEl, iconSize: [0, 0] }) }) } } }, style: function(feature){ let symbol = feature.mapSymbol; return { className: "map-hilight-area", fill: !!symbol.backgroundColor, fillColor: symbol.backgroundColor, fillOpacity: 0.5, stroke: !!symbol.borderColor, color: symbol.borderColor, } }, onEachFeature: function(feature, layer){ feature[HIGHLIGHT_LAYER] = layer } }).addTo(map) // On ajoute toutes les zones à la carte for(let [_feature_id, feature] of Object.entries(places.featuresById)){ area_highlight.addData(feature) let point_feature = feature.asPoint() if(point_feature !== feature){ area_highlight.addData(point_feature) } } } export function unhighlight_all(){ for(let el of document.querySelectorAll(".map-hilight-area.active")){ el.classList.remove("active") } } export function highlight(place_or_placeid){ unhighlight_all() let place; if(typeof place_or_placeid == "string"){ place = places.getFeatureById(place_or_placeid) } else { place = place_or_placeid } if(place[HIGHLIGHT_LAYER]){ place[HIGHLIGHT_LAYER].getElement() .classList.add("active") } let centroid = turf.centroid(place) map.panTo(L.latLng( centroid.geometry.coordinates[1], centroid.geometry.coordinates[0] )) }