User Tools

Site Tools


doc:appunti:hardware:oms_recipes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
doc:appunti:hardware:oms_recipes [2018/04/21 07:26] – [Grafo stradale da OSM] niccolodoc:appunti:hardware:oms_recipes [2018/04/24 18:32] (current) – removed niccolo
Line 1: Line 1:
-====== 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 [[wp>Turn-by-turn_navigation|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'**[[http://www.istati.it/|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: 
- 
-<code> 
-apt-get install postgis gdal-bin gpsbabel 
-</code> 
- 
-Dalla pagina **[[https://www.istat.it/it/archivio/124086|Archivio dei confini delle unità amministrative]]** si è scaricato l'archivio più dettagliato nel formato UTM32N. 
- 
-Queste sono le trasformazioni applicate al dataset originale: 
- 
-  - Rimozione dei **"buchi"**. 
-  - **Semplificazione**, con errore massimo di 150 metri, per ridurre il numero dei vertici. 
-  - Eliminazione dei **poligoni più piccoli** di una certa area. 
-  - Riproiezione dal sistema **UTM zone 32N** (EPSG:32632) al **WGS84** (EPSG:4326). 
-  - Conversione del file GPX in **file OSM**. 
- 
-Per la creazione di un database geografico consultare la pagina **[[..:..:..:tecnica:gps_cartografia_gis:postgis]]**. La conversione dello Shapefile in SLQ è ottenuta con: 
- 
-<code> 
-shp2pgsql -s 32632 Reg_2016_WGS84.shp reg2016 > Reg_2016_WGS84.sql 
-</code> 
- 
-Il primo passaggio è la **rimozione dei "buchi"** nei multipoligoni. La funzione da usare è ''[[http://postgis.net/docs/ST_ExteriorRing.html|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**: 
- 
-<code> 
-SELECT regione, ST_MakePolygon(ST_ExteriorRing((ST_Dump(geom)).geom)) AS geom 
-    INTO TABLE reg2016_no_holes FROM reg2016; 
-</code> 
- 
-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: 
- 
-<code bash> 
-#!/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" 
-</code> 
- 
-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 **[[https://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative|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**: 
- 
-<code bash> 
-#!/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 
-</code> 
- 
-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 ===== 
- 
-{{ .:osm:josm_confine_regione.png?300|Disegno del confine con JOSM}} 
-Utilizzeremo il linguaggio **[[https://wiki.openstreetmap.org/wiki/Overpass_API|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 [[https://wiki.openstreetmap.org/wiki/JOSM|JOSM]] con questa procedura. 
- 
-  - Scaricato una porzione della mappa che includa un **piccolo tratto del confine regionale**. 
-  - 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. 
-  - Menu //File//, **//New Layer//**. 
-  - Nel nuovo layer **si disegna il poligono approssimato** che racchiuda la regione. 
-  - 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**): 
- 
-<code bash> 
-#!/bin/sh 
-cat "bounds-toscana.gpx" \ 
-    | grep '<trkpt' \ 
-    | sed 's/.*lat="\([0-9\.]\+\)" lon="\([0-9\.]\+\)".*/\1 \2/' \ 
-    | tr '\n' ' ' \ 
-    | awk '{$1=$1};1' 
-</code> 
- 
-Il risultato desiderato è semplicemente **la sequenza delle coordinate lat lon** di tutti i vertici separate da spazi: 
- 
-<code> 
-44.381756 9.629437 44.488539 9.699057 44.569342 9.951234 ... 
-</code> 
- 
-===== Grafo stradale da OSM ===== 
- 
-In un file che chiameremo **query_way.xml** si prepara la **query Overpass** per estrarre le //way// dalla zona desiderata: 
- 
-<code xml> 
-<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> 
-</code> 
- 
-**NOTA**: all'espressione regolare **regv** è opportuno aggiungere anche tutte le highway di tipo **%%*_link%%**, ad esempio **motorway_link**, ecc. Vedere la [[https://wiki.openstreetmap.org/wiki/Key:highway|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**: 
- 
-<code bash> 
-wget --post-file="query_way.xml" -O "op_way.osm" "http://overpass-api.de/api/interpreter" 
-</code> 
- 
-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//): 
- 
-<code bash> 
-osmfilter "op_way.osm" \ 
-    --drop-node-tags="*=" --keep-way-tags="all highway= name= ref=" \ 
-    --drop-author --fake-version --out-osm -o="f_way.osm" 
-</code> 
- 
-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: by niccolo