(function() { const MIN_ZOOM = 6; const MAX_ZOOM = 18; const INITIAL_ZOOM = 14; const TILE_URL = 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png'; const STATE = { locations: new Map(), }; let db = new Kinto({ bucket: "magellan" }); let kintoLocations = db.collection("locations"); let syncOptions = { remote: "https://kinto.b.delire.party/v1", //headers: {Authorization: "Basic " + btoa('user:pass')} }; async function sync() { try { await kintoLocations.sync(syncOptions); } catch (err){ alert(err); } } sync(); function addLocation(loc) { if (!STATE.locations.has(loc.label)) { let marker = L.marker(loc.coordinates) .addTo(map) .bindPopup(loc.label); STATE.locations.set(loc.label, marker); return true; } return false; } async function init() { try { let locations = await kintoLocations.list(); locations = locations.data; console.log(locations) locations.forEach(addLocation); } catch (err) { alert(`on init: ${err.toString()}`) } } init(); async function addNewLocation(loc) { if (addLocation(loc)) { let marker = STATE.locations.get(loc.label); marker.openPopup(); // Add it to kinto. try { await kintoLocations.create({ label: loc.label, coordinates: loc.coordinates }); } catch (err) { alert(`Error when creating new location: ${err.toString()}`); }; sync(); } else { STATE.locations.get(loc.label).openPopup(); } } class Location { constructor({ id, label, coordinates}) { this.id = id || null; this.label = label; this.coordinates = coordinates; } } async function fetchLocation(address) { // Alternatively, search only for addresses (specialized for Lyon 7). //const GEOCODING_URL = 'https://api-adresse.data.gouv.fr/search/?q={query}&postcode=69007'; const GEOCODING_URL = 'https://demo.addok.xyz/search/?q={query}&limit=20'; let resp = await fetch(GEOCODING_URL.replace('{query}', address)); let results = await resp.json(); results = results.features.map(feature => { let { properties: {label: label}, geometry: { coordinates: coordinates }} = feature; coordinates.unshift(coordinates.pop()); return new Location({label, coordinates}); }); console.log(results); return results; } let map = L.map('the-map').setView([45.751591, 4.845695], INITIAL_ZOOM); L.tileLayer(TILE_URL, {minZoom: MIN_ZOOM, maxZoom: MAX_ZOOM, attribution: 'Carte donnĂ©es © OpenStreetMap (ODbL) / fond OSM-FR (CC-by-SA), POI: OpenStreetMap (ODbL), adresses BANO (ODbL), geocodeur addok'}).addTo(map); let $ = document.querySelector.bind(document); let $address = $('#address'); let $submit = $('#submit'); let $results = window.results = $('#results'); $('#form').onsubmit = function(event) { event.preventDefault(); return false; } $submit.onclick = async function() { let address = $address.value.trim(); $results.innerHTML = `searching for ${address}...`; let firstResult = true; let locations = await fetchLocation(address); locations = locations.map(loc => { let li = document.createElement('li'); let a = document.createElement('a'); a.href = '#'; a.onclick = function() { L.popup() .setLatLng(loc.coordinates) .setContent(loc.label) .openOn(map); } a.appendChild(document.createTextNode(loc.label)) li.appendChild(a); li.appendChild(document.createTextNode(' ')); let button = document.createElement('button'); button.appendChild(document.createTextNode('Save')); button.onclick = () => { addNewLocation(loc) }; li.appendChild(button); if (firstResult) { firstResult = false; $results.innerHTML = ''; } $results.appendChild(li); return li; }); } })();