webapp: fetch eligibility data on backend
We fetch the eligibility data from the backend for the area the user is currently viewing. We don't want to trigger the search when the user is zoomed out, it could be heavy on the backend CPU. Hence, we trigger the fetch after the user searched for his real address or reached a good-enough zoom level. The backend is currently returning a dummy answer.
This commit is contained in:
parent
8fbad8b7b1
commit
6c8c3b138d
4 changed files with 60 additions and 17 deletions
|
@ -1,7 +1,19 @@
|
||||||
from flask import Flask, render_template
|
from flask import Flask, request, render_template
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@app.route("/", methods=['GET'])
|
@app.route("/", methods=['GET'])
|
||||||
def getMap():
|
def getMap():
|
||||||
return render_template("map.html")
|
return render_template("map.html")
|
||||||
|
|
||||||
|
@app.route("/eligdata", methods=['GET'])
|
||||||
|
def getEligData():
|
||||||
|
args = request.args
|
||||||
|
if 'swx' in args and 'swy' in args and \
|
||||||
|
'nex' in args and 'ney' in args:
|
||||||
|
return { "buildings": [
|
||||||
|
{"x": args['swx'], "y":args['swy'], "label": "dummy elig val" },
|
||||||
|
{"x": args['nex'], "y":args['ney'], "label": "dummy elig val 2" }
|
||||||
|
]}
|
||||||
|
else:
|
||||||
|
return "Missing coordinates", 400
|
||||||
|
|
|
@ -11,5 +11,13 @@ body {
|
||||||
#search-addr-autocomplete {
|
#search-addr-autocomplete {
|
||||||
display: float;
|
display: float;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1;
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btn-load-elig-data {
|
||||||
|
top: 4em;
|
||||||
|
right: 0;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
padding: .5em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
|
let markers = [];
|
||||||
function initMap() {
|
function initMap() {
|
||||||
let map = L.map('map').setView([46.710, 3.669], 6);
|
let map = L.map('map').setView([46.710, 3.669], 6);
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
|
L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
|
||||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
}).addTo(map);
|
}).addTo(map);
|
||||||
L.marker([51.5, -0.09]).addTo(map)
|
|
||||||
.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
|
|
||||||
.openPopup();
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initAddrSearch(map) {
|
function initAddrSearch(map) {
|
||||||
const autocompleteOptions = {
|
const autocompleteOptions = {
|
||||||
|
debounceTime: 300,
|
||||||
search: async (query) => {
|
search: async (query) => {
|
||||||
if(query.length > 2) {
|
if(query.length > 2) {
|
||||||
const mapCenter = map.getCenter();
|
const mapCenter = map.getCenter();
|
||||||
|
@ -22,27 +21,49 @@ function initAddrSearch(map) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSubmit: (res) => {
|
|
||||||
const searchInput = document.getElementById('search-addr-autocomplete-input');
|
|
||||||
const p = res.properties;
|
|
||||||
searchInput.value = `${p.name} - ${p.postcode} ${p.city}, ${p.county}`;
|
|
||||||
console.log("moving to");
|
|
||||||
console.log(res.geometry.coordinates);
|
|
||||||
// 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)
|
|
||||||
},
|
|
||||||
debounceTime: 300,
|
|
||||||
renderResult: (res, props) => {
|
renderResult: (res, props) => {
|
||||||
const p = res.properties;
|
const p = res.properties;
|
||||||
if(p.name && p.postcode && p.city && p.county && res.geometry.coordinates && res.geometry.coordinates.length === 2)
|
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>`;
|
return `<li ${props}>${p.name} - ${p.postcode} ${p.city}, ${p.county}</li>`;
|
||||||
else
|
else
|
||||||
return "";
|
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);
|
const autocompleteAddr = new Autocomplete("#search-addr-autocomplete", autocompleteOptions);
|
||||||
return autocompleteAddr;
|
return autocompleteAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let map = initMap();
|
function updateEligData(map, eligData) {
|
||||||
let addrSearch = initAddrSearch(map);
|
markers.map(marker => map.removeLayer(marker));
|
||||||
|
let buildings = eligData.buildings;
|
||||||
|
markers = buildings.map(building => {
|
||||||
|
const latlng = new L.latLng(building.y, building.x);
|
||||||
|
const marker = new L.marker(latlng).bindPopup(building.label);
|
||||||
|
map.addLayer(marker);
|
||||||
|
return marker
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchEligData(map) {
|
||||||
|
const bounds = map.getBounds();
|
||||||
|
const sw = bounds.getSouthWest();
|
||||||
|
const ne = bounds.getNorthEast();
|
||||||
|
const zoom = map.getZoom();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
const map = initMap();
|
||||||
|
const addrSearch = initAddrSearch(map);
|
||||||
|
|
||||||
|
document.getElementById("btn-load-elig-data").onclick = fetchEligData;
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
autocapitalize="off" placeholder="Votre Adresse"/>
|
autocapitalize="off" placeholder="Votre Adresse"/>
|
||||||
<ul class="autocomplete-result-list"/>
|
<ul class="autocomplete-result-list"/>
|
||||||
</div>
|
</div>
|
||||||
|
<button id="btn-load-elig-data" type="button">Récupérer les données d'éligibilité
|
||||||
|
pour cette zone</button>
|
||||||
<div id="map"/>
|
<div id="map"/>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
|
Loading…
Reference in a new issue