Höhenlinien für Garmin-Geräte aus den EU-DEM-Daten erstellen

Die Europäischen Umweltagentur EEA stellt auf ihrer Webseite digitale Höhendaten für ganz Europa zum Download bereit. Die Daten basieren auf den Daten von SRTM und ASTER GDEM und haben eine Auflösung von 25 Metern. Hier wird beschrieben, wie man daraus Höhenlinien für Garmin-Navigationsgeräte erstellen kann.

Dies ist eine Alternative zu den üblichen Verfahren, welche direkt auf den SRTM- und/oder ASTER-GDEM-Daten aufbauen. Während es dafür Werkzeuge gibt, die in einem Schritt die Daten herunterladen und daraus eine OSM-Datei erzeugen, z.B. phyghtmap und srtm2osm, muss dies bei den EU-DEM-Daten in getrennten Verarbeitungsschritten gemacht werden.

Hinweis: Es sind die Konditionen für die Nutzung der Daten zu beachten, u.a.:

  1. When distributing or communicating Copernicus data and information to the public, users shall inform the public of the source of that data and information.
  2. Users shall make sure not to convey the impression to the public that the user’s activities are officially endorsed by the Union.
  3. Where that data or information has been adapted or modified, the user shall clearly state this.

Herunterladen der Daten

Auf der Webseite der EEA sind die Daten in EPSG:3035-Projektion verfügbar. Die Dateinamen haben die Form

 eudem_v11_ExxNyy.TIF

Jede Datei enthält die Daten für ein Quadrat mit 1000 km Seitenlänge und dem Ursprung (linke untere Ecke) bei x=xx10.000m, y=yy10.000m .

Ausschnitt erstellen

Da die Abdeckung der EU-DEM-Dateien für die Nutzung auf dem Garmin-Gerät nicht praxisgerecht ist, ist es sinnvoll, Höhenliniendateien für ein Land oder eine Region zu erstellen. Dafür erzeugt man zunächst mit gdalwarp eine DEM-Datei für das benötigte Gebiet. Man kann das Gebiet als Bounding-Box-Rechteck oder mittels eines Polygons im Shape-Format definieren. Da das Gebiet in der Regel mehrere EU-DEM-Dateien überlappt erzeugt man zunächst eine VRT-Datei, in der alle EU-DEM_Dateien zusammengefasst sind:

  gdalbuildvrt EU-DEM.vrt eu_dem*TIF

Anschließend erstellt man mit gdalwarp die DEM-Datei für den gewünschten Ausschnitt. Für einen rechteckigen Ausschnitt:

gdalwarp -te <xmin> <ymin> <xmax> <ymax> 
      -t_srs "+proj=longlat +ellps=WGS84"\
      -dstnodata 0.0\
      EU-DEM.vrt <ausgabedatei>

Für einen Polygon-Ausschnitt kann man z.B. die Shape-Datei eines Staats oder einer anderen Verwaltungseinheit verwenden. Solche Shape-Dateien findet man auf gadm.org, im Download-Bereich der Geofabrik oder hier (nur Deutschland).

gdalwarp -co BIGTIFF=YES -co COMPRESS=LZW -wm 3000\
    -t_srs "+proj=longlat +ellps=WGS84"\
    -cutline <shape-datei>\
    -crop_to_cutline\
    -dstnodata 0.0\
    EU-DEM.vrt <ausgabedatei>

Die Shape-Datei muss ein geschlossenes Polygon ohne Kreuzungspunkte enthalten, andernfalls weist gdalwarp die Datei zurück. Eine fehlerhaftes Polygon kann in QGIS mit der Funktion Vektor/Geomotrie-Werkzeuge/Geometriegültigkeit überprüfen überprüft und korrigiert werden.

Erzeugen einer OSM-Datei

Zunächst wird aus der DEM-Datei eine Shape-Datei erstellt:

gdal_contour <geotif-datei> <ausgabe-verzeichnis> -a ele  -i <schrittweite>  -f "ESRI Shapefile"

In dem Ausgabeverzeichnis wird eine Datei contour.shp erzeugt, welche Höhenlinien im Abstand von <schrittweite> Höhenmetern enthält. Die Höhe wird im Attribut ele abgelegt.

Die so erzeugte Shape-Datei wird im nächsten Schritt mit dem Werkzeug ogr2osm in eine OSM-XML-Datei umgewandelt, welche die Höhenlinien als OSM-Wege enthält. Damit die Datei später mit mkgmap weiter verarbeitet werden kann, werden die Wege mit folgenden Attributen versehen

 ele=<höhe>
 contour='elevation'
 contour_ext=['ele10'|'ele20'|'ele50|'ele100']

Hierzu wird ogr2osm mit einer Translation-Datei trans_dem.py aufgerufen, welche die Attribute hinzufügt:

def filterTags(attrs):
if not attrs:
    return
if 'ele' in attrs:
    if float(attrs['ele'])%100 == 0:
        return { 'ele':attrs['ele'], 'contour':'elevation', 'contour_ext':'ele100' }
    elif float(attrs['ele'])%50 == 0:
        return { 'ele':attrs['ele'], 'contour':'elevation', 'contour_ext':'ele50' }
    elif float(attrs['ele'])%20 == 0:
        return { 'ele':attrs['ele'], 'contour':'elevation', 'contour_ext':'ele20' }
    else:
        return { 'ele':attrs['ele'], 'contour':'elevation', 'contour_ext':'ele10' }

Der Aufruf von ogr2osm lautet dann:

python ~/appli/ogr2osm/ogr2osm.py\
   -t trans_dem.py\
   -f contour.shp  -o contour.osm

Da ogr2osm sehr viel RAM-Speicher belegt, ist es sinnvoll diesen Schritt aufzuteilen, indem man OSM-Dateien für kleinere Ausschnitte, z.B. mit 0.5°x0-5° Kantenlänge, erzeugt:

TIF=EU-DEM.tif
x1=`gdalinfo $TIF | grep "Lower Left" | cut -c 14-25`
y1=`gdalinfo $TIF | grep "Lower Left" | cut -c 27-38`
x2=`gdalinfo $TIF | grep "Upper Right" | cut -c 14-25`
y2=`gdalinfo $TIF | grep "Upper Right" | cut -c 27-38`
BBOX="$x1 $y1 $x2 $y2"
echo $BBOX|\
awk '{\
   ymin=$2;\
   xmin=$1;\
   ymax=$4;\
   xmax=$3;\
   for(x1=xmin; x1<xmax; x1+=0.5)\
      for(y1=ymin; y1<ymax; y1+=0.5){\
         if(x1+0.5>xmax)x2=xmax;else x2=x1+0.5;\
         if(y1+0.5>ymax)y2=ymax;else y2=y1+0.5;\
         print x1" "y1" "x2" "y2" ";\
      }\
}'|\
while read BBOX;do
    FNAME=`echo $BBOX|awk '{gsub(/ /,"_");print $0}'`
    FNAME="contour_$FNAME"
    gdalwarp -overwrite -te $BBOX $TIF temp.tif
    gdal_contour temp.tif /tmp -a ele  -i 10.0  -snodata -9999 
    rm -f $TMPDIR/temp.tif
    python ~/appli/ogr2osm/ogr2osm.py -t trans_dem.py -f /ttmp/contour.shp  -o ${FNAME}.osm
    rm -f /tmp/contour*
done      

Erzeugen der Garmin-Karte mit mkgmap

Die Höhenlinien sollen je nach Zoomstufe unterschiedlich dargestellt werden:

  • In Zoomstufe 21 und 22 werden 100er-Linien mitteldick und 20er-Linien dünn dargestellt
  • Ab Zoomstufe 23 werden 100er-Linien dick, 50er-Linien mitteldick und 10er-Linien dünn dargestellt

Dies wird mit der folgenden line-Stildatei erreicht:

  contour=elevation & (contour_ext=ele10 | contour_ext=ele20)
     { name '${ele|conv:m=>ft}'; }
     [0x20 resolution 23 continue]
  contour=elevation & contour_ext=ele50
     { name '${ele|conv:m=>ft}'; }
     [0x21 resolution 23 continue]
  contour=elevation & contour_ext=ele100
     { name '${ele|conv:m=>ft}'; }
     [0x22 resolution 23 continue]
  contour=elevation & contour_ext=ele20
     { name '${ele|conv:m=>ft}'; }
     [0x20 resolution 21]
  contour=elevation & contour_ext=ele100
     { name '${ele|conv:m=>ft}'; }
     [0x21 resolution 21]

Und zuletzt wird mkgmap aufgerufen:

 mkgmap\
    --style-file=mkgmap-style-contour\
    --gmapsupp\
    --family-id=2513 --product-id=1\
    --series-name=SRTM --family-name=SRTM\
    --transparent\
    --code-page=1252\
    contour*.osm