2026.camp.carte/js/map.js

178 lines
No EOL
5.8 KiB
JavaScript

import * as L from "./lib/leaflet/leaflet-src.esm.js"
import { 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
})
map.addEventListener("zoom", () => {
map.getContainer()
.style.setProperty("--zoom-level", map.getZoom())
})
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 = map.project(L.latLng([...coordinate_list[0]].reverse()))
let bounds = L.bounds(first_point, first_point)
for(let i = 1; i<coordinate_list.length; i++){
let point = map.project([...coordinate_list[i]].reverse())
bounds.extend(point)
}
map_bounds = bounds
console.log("Bounds:", map_bounds)
}),
])
// La couche Openstreetmap standard
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map)
// La couche custom de l'antenne
L.tileLayer('./tuiles/{z}/{x}/{y}.png', {
minZoom: 14,
maxZoom: 23
}).addTo(map)
// Parametrage de la carte initiale
map.setMaxBounds(map_bounds)
map.setView(map_center, 19, {
animate: false,
})
}
const HIGHLIGHT_LAYER = Symbol("Hilight map 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, {
style: function(feature){
return {
className: "map-hilight-area",
fill: false,
stroke: false
}
},
onEachFeature: function(feature, layer){
feature[HIGHLIGHT_LAYER] = layer
}
}).addTo(map)
// La couche des zones disponibles
const bathrooms = L.geoJSON(null, {
pointToLayer: function(feature, latlng) {
let iconEl = document.createElement("div")
iconEl.classList.add("map-amenity-icon-container")
if(feature.properties["toilettes"]){
let bathrooms_icon = document.createElement("img")
bathrooms_icon.src = new URL("../icons/toilettes.svg", import.meta.url).toString()
bathrooms_icon.alt = "Icone de toilettes"
bathrooms_icon.title = "Toilettes"
bathrooms_icon.classList.add("bathroom")
iconEl.append(bathrooms_icon)
}
if(feature.properties["douches"]){
let shower_icon = document.createElement("img")
shower_icon.src = new URL("../icons/douches.svg", import.meta.url).toString()
shower_icon.alt = "Icone de douche"
shower_icon.title = "Douches"
shower_icon.classList.add("shower")
iconEl.append(shower_icon)
}
if(feature.properties["eau potable"]){
let drinking_water_icon = document.createElement("img")
drinking_water_icon.src = new URL("../icons/eau-potable.svg", import.meta.url).toString()
drinking_water_icon.alt = "Icone d'une goute"
drinking_water_icon.title = "Eau potable"
drinking_water_icon.classList.add("drinking-water")
iconEl.append(drinking_water_icon)
}
let icon = L.divIcon({
className: "map-amenity-icon",
html: iconEl
})
return L.marker(latlng, {
icon: icon
})
}
}).addTo(map)
// On ajoute toutes les zones à la carte
for(let [_feature_id, feature] of Object.entries(places.featuresById)){
area_highlight.addData(feature)
if(feature.properties["toilettes"] || feature.properties["douches"] || feature.properties["eau potable"]) {
let amenity_feature
if(feature.geometry.type != "Point"){
amenity_feature = turf.centroid(feature)
amenity_feature[PARENT_FEATURE] = feature
amenity_feature.properties = feature.properties
} else {
amenity_feature = feature
}
bathrooms.addData(amenity_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]
))
}