Selezionare Comuni su una Mappa con OpenStreetMap e API Open Source
Vincenzo Di Franco
文 (cultura), 森 (natura), 佐 (aiuto), 迪 (guida), 弗 (unicità), 朗 (luminosità), 科 (competenza)
Quando si lavora con dati geografici, una delle sfide più comuni per gli sviluppatori è identificare e selezionare aree specifiche su una mappa. Ad esempio, come possiamo ottenere un elenco di comuni italiani all'interno di un'area selezionata su una mappa? Google Maps offre API potenti, ma con costi non sempre accessibili. Per fortuna, il mondo open-source ci offre alternative gratuite e flessibili come OpenStreetMap, Overpass API e Wikidata.
In questo articolo vedremo come costruire una web app interattiva che:
Tecnologie Utilizzate
Fase 1: Creazione della Mappa con Leaflet.js
Il primo passo è visualizzare la mappa e consentire agli utenti di disegnare un'area.
var map = L.map('map').setView([41.9028, 12.4964], 6);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
Poi aggiungiamo il controllo per disegnare poligoni:
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
edit: { featureGroup: drawnItems },
draw: { polygon: true }
});
map.addControl(drawControl);
Fase 2: Ottenere i Comuni da OpenStreetMap
Dopo aver disegnato un'area, possiamo interrogare Overpass API:
function getComuniInsideArea(polygon) {
var coords = polygon.getLatLngs()[0].map(coord => coord.lat + " " + coord.lng).join(" ");
var overpassQuery = `
[out:json];
(
relation["boundary"="administrative"]["admin_level"="8"](poly:"${coords}");
);
out center tags;`;
fetch("https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(overpassQuery))
.then(response => response.json())
.then(data => {
data.elements.forEach(element => {
console.log("Comune trovato:", element.tags.name);
});
});
}
Fase 3: Enriching con Wikidata (Popolazione e Superficie)
Molti comuni su OpenStreetMap hanno un ID Wikidata. Usiamo questa informazione per ottenere dati aggiuntivi:
function fetchWikidata(comune) {
let wikidataID = comune.wikidata;
let url = `https://www.wikidata.org/w/api.php?action=wbgetentities&ids=${wikidataID}&format=json&origin=*`;
return fetch(url)
.then(response => response.json())
.then(data => {
let entity = data.entities[wikidataID];
comune.popolazione = entity.claims.P1082 ? entity.claims.P1082[0].mainsnak.datavalue.value : "N/A";
comune.area = entity.claims.P2046 ? entity.claims.P2046[0].mainsnak.datavalue.value : "N/A";
});
}
Fase 4: Esportare i dati in JSON, CSV e XML
Infine, permettiamo di scaricare i dati in vari formati:
function downloadData(format) {
let dataStr, fileName;
if (format === 'json') {
dataStr = JSON.stringify(comuniData, null, 2);
fileName = "comuni.json";
} else if (format === 'csv') {
let csv = "Nome,Latitudine,Longitudine,Popolazione,Superficie\n";
comuniData.forEach(c => {
csv += `${c.nome},${c.latitudine},${c.longitudine},${c.popolazione},${c.area}\n`;
});
dataStr = csv;
fileName = "comuni.csv";
} else if (format === 'xml') {
let xml = "<?xml version='1.0' encoding='UTF-8'?><comuni>";
comuniData.forEach(c => {
xml += `<comune><nome>${c.nome}</nome><latitudine>${c.latitudine}</latitudine><longitudine>${c.longitudine}</longitudine><popolazione>${c.popolazione}</popolazione><superficie>${c.area}</superficie></comune>`;
});
xml += "</comuni>";
dataStr = xml;
fileName = "comuni.xml";
}
let blob = new Blob([dataStr], { type: format === 'json' ? "application/json" : format === 'csv' ? "text/csv" : "application/xml" });
let a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
Conclusione
Abbiamo creato un'applicazione web che: ? Usa Leaflet.js per disegnare un'area su una mappa interattiva. ? Usa Overpass API per ottenere i comuni all'interno di un'area. ? Integra Wikidata per arricchire le informazioni con popolazione e superficie. ? Consente il download dei dati in JSON, CSV e XML.
Grazie a queste tecnologie open-source, possiamo ottenere dati geografici avanzati senza costi elevati. ??
?? Hai mai usato Overpass API o Wikidata nei tuoi progetti? Quali altre applicazioni ti vengono in mente per questa tecnica?
Esempio codepen
Test su youtube