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 12:45] – [Stile della mappa] 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 NON vengono utilizzati per l'indicizzazione degli indirizzi da utilizzare durante la ricerca degli stessi. L'aggiunta dei confini regionali ha ingrossato la mappa finale di circa **170 kb**. 
- 
-===== 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 senso della ricorsione di tipo //way-node//. Il //polygon-query// è quello definito nel [[#confine_per_l_estrazione_dei_dati|paragrafo precedente]]. 
- 
-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 le **highway** da estrarre sono solo quelle di tipo **track** e **path**, mentre i tag tag preservare sono **highway**, **name**, **ref** e **tracktype**. 
-===== Waypoint da OSM ===== 
- 
-===== Centri abitati da OSM ===== 
- 
-===== Stile della mappa ===== 
- 
-^ %%--region-name%% | Viene mostrato accanto al nome del centro abitato nella visualizzazione dell'elenco (altrimenti compare la stringa **ABC**). FIXME Forse esiste la possibilità di usare i confini amministrativi e l'indicizzazione degli indirizzi per associare il centro abitato al nome del comune che lo contiene?  | 
  
doc/appunti/hardware/oms_recipes.1524307525.txt.gz · Last modified: by niccolo