User Tools

Site Tools


doc:appunti:hardware:oms_recipes

This is an old revision of the document!


Ricette Mappe OpenStreetMap

In questa pagina alcune ricette utili per cucinare mappe OpenStreetMap da caricare su navigatore GPS. In particolare l'obiettivo è creare delle versioni ridotte compatibili con il Garmin eTrex 10, che ha capacità di memoria davvero ridotte (circa 7 Mb).

Spazio limitato: è necessario un compromesso

Per motivi di capienza sarà quindi necessario restringere l'estensione della mappa ad una sola regione (in questo esempio la Toscana), inoltre si dovrà optare per una mappa di tipo on-road (ad esempio per uso cicloturistico) oppure una off-road (per uso trekking o MTB). Nel primo caso si includerà solo la rete stradale ordinaria (da motorway a unclassified nella classificazione OSM), nel secondo caso quella off-road (track e path nella classificazione OSM).

Cosa includere

  • Grafo stradale. Poiché l'eTrex-10 non è in grado di effettuare il routing, si è preservato solo il grafo stradale senza includere le informazioni relative ad esempio alla percorribilità, ai sensi unici, alle relazioni circa le restrizioni di svolta, ecc.
  • Waypoint. Si è inclusa una selezione di waypoint. Dalla categoria amenity di OSM: distributori di benzina, punti di ristoro (ristoranti, caffè), farmacie, ospedali. Dalla categoria tourism: strutture di ospitalità come alberghi, campeggi e rifugi montani. Alcune feature sono rappresentate nella mappa OSM come way invece che come node, cioè è stato mappato il contorno invece del singolo punto. La procedura individuata trasforma tale contorno in un singolo punto.
  • Centri abitati. Avere i centri abitati come waypoint è utile per effettuare ricerche e spostarsi velocemente sulla mappa del GPS.
  • Confini amministrativi. Si sono inclusi i confini delle regioni italiane soprattutto per fini “estetici”, poiché sono utili ad interpretare la mappa a livelli di zoom inferiori. I confini vengono usati anche per l'indicizzazione degli waypoint, cioè durante la ricerca degli stessi viene mostrata la regione in cui si trovano. L'aggiunta dei confini regionali ha ingrossato la mappa finale di circa 170 kb. FIXME Forse ha senso aggiungere i confini dei comuni della regione interessata?

Confini regioni italiane da Istat

L'Istituto nazionale di statistica fornisce gratuitamente il file dei confini comunali e regionali, in formato Shapefile. Per effettuare le opportune manipolazioni abbiamo caricato il file in un database geografico PostgreSQL/PostGIS. Inoltre abbiamo utilizzato i tool GDAL/OGR e gpsbabel.

I pacchetti Debian da installare sono:

apt-get install postgis gdal-bin gpsbabel

Dalla pagina Archivio dei confini delle unità amministrative si è scaricato l'archivio più dettagliato nel formato UTM32N.

Queste sono le trasformazioni applicate al dataset originale:

  1. Rimozione dei “buchi”.
  2. Semplificazione, con errore massimo di 150 metri, per ridurre il numero dei vertici.
  3. Eliminazione dei poligoni più piccoli di una certa area.
  4. Riproiezione dal sistema UTM zone 32N (EPSG:32632) al WGS84 (EPSG:4326).
  5. Conversione del file GPX in file OSM.

Per la creazione di un database geografico consultare la pagina PostGIS su Debian. La conversione dello Shapefile in SLQ è ottenuta con:

shp2pgsql -s 32632 Reg_2016_WGS84.shp reg2016 > Reg_2016_WGS84.sql

Il primo passaggio è la rimozione dei “buchi” nei multipoligoni. La funzione da usare è ST_ExteriorRing(), che però deve essere applicata dopo aver scomposto i MULTIPOLYGON componenti con la funzione ST_Dump(). La geometria risultante è una LINESTRING che deve essere ricomposta in poligoni con ST_MakePolygon(). Il risultato viene salvato in una tabella temporanea reg2016_no_holes:

SELECT regione, ST_MakePolygon(ST_ExteriorRing((ST_Dump(geom)).geom)) AS geom
    INTO TABLE reg2016_no_holes FROM reg2016;

I passaggi successivi sono realizzati da una sola istruzione SQL, che viene eseguita dal tool ogr2ogr, in modo da salvare il risultato direttamente in un file GPX:

#!/bin/sh
SQL="SELECT regione AS name, ST_Transform(ST_Simplify(geom, 150), 4326) AS geom
     FROM reg2016_no_holes WHERE ST_Area(geom) > 11000000"
export GPX_USE_EXTENSIONS
ogr2ogr \
    -f "GPX" regioni.gpx \
    PG:"host=localhost user=username dbname=dbname password=MySecret" \
    -sql "$SQL" \
    -lco "FORCE_GPX_TRACK=YES" -nlt "MULTILINESTRING" -mapFieldType "Integer64=String"

Nell'istruzione SQL si utilizza ST_Simplfy() indicando un errore massimo di 150 metri (la proiezione dei dati Istat è in metri), la ST_Transform() per riproiettare le geometrie nel sistema WGS84, infine si impone una clausola con ST_Area() per togliere i poligoni (isole) che hanno una superficie inferiore agli 11 km quadrati.

Il passaggio finale viene fatto con il tool gpsbabel, consiste nel convertire il file GPX estratto dal database in un file OSM, utilizzabile in seguito da mkgmap. Durante la conversione vengono aggiunti ad ogni way i tag che indicano un confine regionale. Il file prodotto da gpsbabel ha purtroppo ha gli ID negativi ordinati in modo decrescente, questo impedisce a osmconvert (che verrà usato successivamente) di funzionare correttamente. Si usa un comando brutale sed per togliere il segno meno a tutti gli id e ref:

#!/bin/sh
gpsbabel -i gpx -f regioni.gpx \
    -o osm,created_by=,tag="boundary:administrative;admin_level:4" \
    -F regioni_bad_id.osm
cat regioni_bad_id.osm  | sed "s/id='-/id='/" | sed "s/ref='-/ref='/" > regioni.osm
rm regioni_bad_id.osm

FIXME Questa ricetta ha un problema teorico: gli ID trasformati in numeri positivi potrebbero andare in conflitto con gli ID degli oggetti scaricati dal database OpenStreetMap e quindi creare problemi al programma osmconvert. Esiste anche la funzione renumber del programma osmium (dal pacchetto osmium-tool), ma occorre la versione 1.8.0 da Debian stretch-backports.

Confine per l'estrazione dei dati

Disegno del confine con JOSM Utilizzeremo il linguaggio Overpass API per estrarre i dati da OpenStreetMap. Per ogni richiesta forniremo il confine per l'estrazione sotto forma di vertici di un poligono grossolano (una trentina di vertici) che racchiude la regione desiderata.

Per disegnare i confini abbiamo utilizzato JOSM con questa procedura.

  1. Scaricato una porzione della mappa che includa un piccolo tratto del confine regionale.
  2. Dopo aver selezionato tale tratto di confine, dal tab Tags / Memberships si evidenzia la relazione boundary[4] Toscana, click destro, Download members. Vengono scaricate tutte le way che formano il confine reginale.
  3. Menu File, New Layer.
  4. Nel nuovo layer si disegna il poligono approssimato che racchiuda la regione.
  5. Click destro sul layer disegnato, Export to GPX.

Dal file GPX creato è possibile estrarre le coordinate con un semplice script di shell (lo abbiamo chiamato bounds-gpx2txt):

#!/bin/sh
cat "bounds-toscana.gpx" \
    | grep '<trkpt' \
    | sed 's/.*lat="\([0-9\.]\+\)" lon="\([0-9\.]\+\)".*/\1 \2/' \
    | tr '\n' ' ' \
    | awk '{$1=$1};1'

Il risultato desiderato è semplicemente la sequenza delle coordinate lat lon di tutti i vertici separate da spazi:

44.381756 9.629437 44.488539 9.699057 44.569342 9.951234 ...

Grafo stradale da OSM

In un file che chiameremo query_way.xml si prepara la query Overpass per estrarre le way dalla zona desiderata:

<osm-script>
  <query type="way">
    <has-kv k="highway" regv="^motorway$|^trunk$|^primary$|^secondary$|^tertiary$|^unclassified$"/>
    <polygon-query bounds="44.381756 9.629437 44.488539 9.699057 44.569342 ..."/>
  </query>
  <union>
    <item />
    <recurse type="way-node"/>
  </union>
  <print mode="body"/>
</osm-script>

NOTA: all'espressione regolare regv è opportuno aggiungere anche tutte le highway di tipo *_link, ad esempio motorway_link, ecc. Vedere la classificazione delle highway.

Nell'opportuno linguaggio è scritto che devono essere estratte non solo le way con i relativi attributi, ma anche i node che costituiscono effettivamente la forma della strada, questo è il sendo della ricorsione di tipo way-node.

Per prelevare i grafo stradale è quindi sufficiente l'uso di wget:

wget --post-file="query_way.xml" -O "op_way.osm" "http://overpass-api.de/api/interpreter"

Infine usiamo osmfilter per ripulire il file, togliendo eventuali tag associati ai singoli nodi e mantenendo solo alcuni tag delle strade (i tag highway, name e ref):

osmfilter "op_way.osm" \
    --drop-node-tags="*=" --keep-way-tags="all highway= name= ref=" \
    --drop-author --fake-version --out-osm -o="f_way.osm"

Per ottenere il grafo delle strade off-road si utilizza una ricetta del tutto analoga, salvo che i valori per per il tag highway sono solo track e path e i tag tag preservare sono highway, name, ref e tracktype.

Waypoint da OSM

Centri abitati da OSM

Stile della mappa

doc/appunti/hardware/oms_recipes.1524288391.txt.gz · Last modified: 2018/04/21 07:26 by niccolo