const minZoomForRequest = 17; let markers = []; function initMap(btn) { // Init map position/zoom. Potentially using what's in the URL search string. const params = new URLSearchParams(window.location.search); let x = parseFloat(params.get('x')); let y = parseFloat(params.get('y')); let z = parseInt(params.get('z')); let map = L.map('map'); if(x && y && z) { map.setView([y, x], z); fetchEligData(map); displayBtn(btn); } else { map.setView([46.710, 3.669], 6); } L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); map.on("zoom", () => { /* We only want to enable the search button when we reached a sufficient zoom level */ if (btn.disabled && map.getZoom() >= minZoomForRequest) { displayBtn(btn); } if (!btn.disabled && map.getZoom() < minZoomForRequest) { hideBtn(btn); } }); return map; } function initAddrSearch(map) { const autocompleteOptions = { debounceTime: 300, search: async (query) => { if(query.length > 2) { const mapCenter = map.getCenter(); const reqUri = `https://photon.komoot.io/api/?q=${encodeURI(query)}&lat=${mapCenter.lat}&lon=${mapCenter.lng}&limit=20&lang=fr`; const source = await fetch(reqUri); const data = await source.json(); return data.features; } else { return []; } }, renderResult: (res, props) => { const p = res.properties; if(p.name && p.postcode && p.city && p.county && res.geometry.coordinates && res.geometry.coordinates.length === 2) return `
  • ${p.name} - ${p.postcode} ${p.city}, ${p.county}
  • `; else return ""; }, onSubmit: async (res) => { const searchInput = document.getElementById('search-addr-autocomplete-input'); const p = res.properties; searchInput.value = `${p.name} - ${p.postcode} ${p.city}, ${p.county}`; // We already filtered out the result not having strictly 2 coordinates at item display map.setView([res.geometry.coordinates[1],res.geometry.coordinates[0]], 19); fetchEligData(map); } }; const autocompleteAddr = new Autocomplete("#search-addr-autocomplete", autocompleteOptions); return autocompleteAddr; } function updateEligData(map, eligData) { markers.map(marker => map.removeLayer(marker)); let buildings = eligData.buildings; markers = buildings.map(building => { const latlng = new L.latLng(building.y, building.x); const addrImm = `${building.numVoieImm} ${building.typeVoieImm} ${building.nomVoieImm}` const marker = new L.marker(latlng) .bindPopup(`${addrImm}
    Etat: ${building.etatImm}
    Code Immeuble: ${building.idImm}`); map.addLayer(marker); return marker }); } function updateUrl(map) { const c = map.getCenter(); history.replaceState({}, "", encodeURI(`?x=${c.lng}&y=${c.lat}&z=${map.getZoom()}`)); } async function fetchEligData(map) { const zoom = map.getZoom(); if (zoom >= minZoomForRequest) { const bounds = map.getBounds(); const sw = bounds.getSouthWest(); const ne = bounds.getNorthEast(); const reqUri = encodeURI(`eligdata?swx=${sw.lng}&swy=${sw.lat}&nex=${ne.lng}&ney=${ne.lat}`); const source = await fetch(reqUri); const eligData = await source.json(); updateEligData(map, eligData); updateUrl(map); } } function initBtn() { const btn = document.getElementById("btn-load-elig-data"); btn.disabled = true; btn.title = "Veuillez zoomer plus la carte avant de lancer une recherche d'éligibilité."; btn.onclick = () => fetchEligData(map); return btn; } function displayBtn(btn) { btn.disabled = false; btn.title = "Rechercher les données d'éligibilité pour cette zone." } function hideBtn(btn) { btn.disabled = true; btn.title = "Veuillez zoomer plus la carte avant de lancer une recherche d'éligibilité."; } const btn = initBtn(); const map = initMap(btn); const addrSearch = initAddrSearch(map);