52e4ecb2a2
Doing this provides the user a way to share the result of a eligibility test with other people by sharing the browser URL.
121 lines
4.4 KiB
JavaScript
121 lines
4.4 KiB
JavaScript
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: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> 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 `<li ${props}>${p.name} - ${p.postcode} ${p.city}, ${p.county}</li>`;
|
|
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}<br/>Etat: ${building.etatImm}<br/>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);
|