38c67ee588
When a acceptable zoom level is reached, the frontend is going to query the DB for the eligibility data associated to the region the user is viewing. When requesting too much data, the frontend gets pretty slow. In order to prevent that, we require a minimal zoom level before triggering the actual request.
94 lines
3.7 KiB
JavaScript
94 lines
3.7 KiB
JavaScript
const minZoomForRequest = 17;
|
|
let markers = [];
|
|
function initMap(btn) {
|
|
let map = L.map('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", () => {
|
|
|
|
console.log(map.getZoom());
|
|
/* We only want to enable the search button when we reached a sufficient zoom level */
|
|
if (btn.disabled && map.getZoom() >= minZoomForRequest) {
|
|
btn.disabled = false;
|
|
btn.title = "Rechercher les données d'éligibilité pour cette zone."
|
|
}
|
|
if (!btn.disabled && map.getZoom() < minZoomForRequest) {
|
|
btn.disabled = true;
|
|
btn.title = "Veuillez zoomer plus la carte avant de lancer une recherche d'éligibilité.";
|
|
}
|
|
});
|
|
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
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
const btn = initBtn();
|
|
const map = initMap(btn);
|
|
const addrSearch = initAddrSearch(map);
|