Axione-IPE-Viewer/webapp/templates/app.js
Félix Baylac-Jacqué 38c67ee588 Webapp: add real elig data query
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.
2022-02-22 14:24:41 +01:00

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: '&copy; <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);