Selezionare Comuni su una Mappa con OpenStreetMap e API Open Source

Selezionare Comuni su una Mappa con OpenStreetMap e API Open Source


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:

  1. Permette all'utente di disegnare un'area su una mappa.
  2. Recupera i comuni italiani dentro quell'area.
  3. Ottiene dati avanzati come popolazione, superficie e codice ISTAT grazie a Wikidata.
  4. Permette di scaricare i risultati in JSON, CSV e XML.

Tecnologie Utilizzate

  • Leaflet.js: libreria JavaScript per visualizzare mappe interattive.
  • Overpass API: per interrogare OpenStreetMap e ottenere comuni all'interno di un'area.
  • Wikidata API: per arricchire i dati con informazioni extra come popolazione e superficie.
  • JavaScript (Vanilla): per la logica dell'applicazione.

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

https://codepen.io/vincenzo-di-franco/pen/bNGGLpr

Test su youtube



要查看或添加评论,请登录

Vincenzo Di Franco的更多文章