User:Rrr
Aktiv in Nord-Oldenburg und umzu.
OSM-Karten auf den Garmin bringen
Eine Routingfähige Karte von Niedersachsen mit teilweise selbstdefinierten Kartensymbolen
- aktuellen Niedersachsen-Extrakt herunterladen
- Dekomprimieren mit bunzip2
- Mit dem [Splitter] in kleinere Stücke zerteilen:
java -jar ../../tools/splitter/splitter.jar --split-file=areas.list niedersachsen.osm
Inhalt von areas.list:
# List of areas # Generated Sat Mar 07 01:44:59 CET 2009 # 26000001: 2390016,307200 to 2523136,440320 # : 51.284180,6.591797 to 54.140625,9.448242 26000002: 2390016,440320 to 2523136,542720 # : 51.284180,9.448242 to 54.140625,11.645508
Alternativ funktioniert auch (erzeugt areas.list):
java -jar ../../tools/splitter/splitter.jar --mapid=26000001 niedersachsen.osm
- Einen eigenen "style" für mkgmap aus dem Default-Style ableiten. Dazu im Verzeichnis
mkgmap-r929/resources/styles das Unterverzeichnis "default" kopieren in ein Unterverzeichnis "mapping" (der Name des neuen styles):
cp -r default mapping
- In der Datei "info" kann der neue style beschrieben werden. In der Datei "points" nehme ich Ergämnzungen vor:
barrier=bollard [0x7000 resolution 19] barrier=bollards [0x7000 resolution 19] barrier=chicane [0x7001 resolution 19] barrier=cycle_barrier [0x7001 resolution 19] barrier=kissing_gate [0x7001 resolution 19] barrier=gate [0x7002 resolution 19] barrier=yes [0x7003 resolution 19] barrier=lift_gate [0x7004 resolution 19] highway=traffic_signals [0x1616 resolution 19] amenity=post_box [0x640f resolution 20]
Die Hexadezimalzahl bezeichnet einen Garmin-Code. Die 0x70.. Codes sind meines Wissens nicht vorbelegt. 0x1616 bezeichnet irgendein Zeichen für Seefahrer. Auch Osm2mp benutzt diesen Code für Ampeln. 0x640f ist einer von zwei Garmin-Codes für post office. Der andere ist 0x2f05 und wird vom Mkgmap default style für post office verwendet. Warum es zwei verschiedene Codes dafür gibt, weiß ich nicht, aber ich verwende den anderen einfach für Briefkästen.
Welche Werte für resolution was genau bedeuten, habe ich noch nicht herausgefunden. Grundsätzlich scheinen größere Zahlen zu bedeuten, dass man den entsprechenden Punkt nur sieht, wenn man weiter hineinzoomt. Welcher Zoomstufe in Metern / km welcher Wert von resolution genau entspricht, und warum die Doku zu mkgmap types rät, man sollte level benutzen statt resolution, jedoch im Default-Style nur resolution verwendet wird, ist mir noch nicht klar.
highway=bus_stop hat resolution 21 und verschwindet, wenn man von 500m nach 800m herauszoomt.
shop=supermarket hat resolution 20 und verschwindet, wenn man von 800m nach 1.2km herauszoomt. place=suburb hat ebenfalls resolution 20, verschwindet aber erst, wenn man von 2km nach 3km herauszoomt.
Meine Ampeln und hindernisse haben resolution 19 und verschwinden von 800m nach 1.2km. Der Briefkasten mit resolution 20 genauso.
- Karte erstellen mit Mkgmap:
java -Xmx512M -jar ../../tools/mkgmap-r1029/mkgmap.jar \ --style-file=../../tools/mkgmap-r1029/resources/styles \ --style=mapping -n 019328076 --description="nds_routing" \ --latin1 --route 2600000*.osm.gz
Das Argument von --style-file ist das Verzeichnis, das alle styles enthält.
- Typ-file erstellen mit Online Editor
Mit einem Online-Editor für .TYP-Files lassen sich den oben im style verwendeten Garmin-Codes eigene Symbole / icons zuweisen. Es lassen sich Einstellungen vornehmen, Bilder hochladen, und schließlich die fertige .typ-Datei herunterladen.
- Die .typ-Datei muss mit der Karte kombiniert werden. Das erledigt das Programm sendmap, allerdings nur in seiner Windows-Variante sendmap20.exe, die auch unter wine läuft. Der Befehl lautet
wine sendmap20.exe -l 019328076.img M0000001.TYP
Damit wird eine Datei gmapsupp.img im aktuellen Verzeichnis erstellt. Falls jedoch der Garmin gerade als USB-Massenspeicher gemountet ist, wird die Datei direkt dort abgelegt, eine vorhandene Datei gmapsupp.img überschrieben.
- Garmin mounten und gmapsupp.imp dort ins Verzeichnis "Garmin" kopieren.
Wie kann man ausser dem Namen des Karten-POI noch weitere Informationen aus OSM dort integrieren?
POIs
POIs kann man recht einfach in die Karten mit aufnehmen, indem man einen entsprechenden style für mkgmap editiert (funktionniert nicht, wenn osm2mp benutzt wird). Wenn die POIs auch über die Menüs gefunden werde sollen, ist man auf die vordefinierten Kategorien von Garmin angewiesen.
Custom icons kann man mit aufnehmen, wenn man ein .typ-file erzeugt. Dazu ist man auf cgpsmapper angewiesen.
Für Mapping-Zwecke wäre es eine Alternative, POIs direkt im Garmin-Format .gpi zu erzeugen. Das kann gpsbabel tun, und dabei auch custom icons mit einbinden.
Unterschiede:
- map-POIs
- Zur Darstellung verwendeter Zoomlevel ist individuell einstellbar
- Unklar, wie Zusatzinfos mit aufgenommen werden können
- Kategorisiert in Garmins Kategorien und Unterkategorien (Schema festgelegt)
- Custom Icons nur über .typ Files (cGPSMapper)
- gpi-POIs
- Dieselbe Zoomlevel-Einstellung für alle POIs
- Eigene Kategorien, nur eine Ebene
- Zusatzinfo kann einfach mit gpsbabel übernommen werden. Bearbeitung der Waypoints mit geeignetem Tool wäre vorteilhaft.
Für Zusatzinfor gilt vermutlich für beide Varianten:
- Name ca. 80-88 Zeichen
- Beschreibung ca. 120-132 Zeichen
- Genaue Zahl abh. von der Darstellungsbreite auf dem GPS-Receiver (mehr "i"s als "m"s sind möglich)
Welche POIs sind wichtig?
- Urlaub
- Bahnhöfe, Bushaltestellen
- alles aus der tourism Abteilung, Denkmäler, Museen
- Campingplätze, Hostels, B&B, andere Unterkünfte
- Shops aller Art, insbesondere Bike Shops und Lebensmittel
- Restaurants
- Spielplätze
- Briefkästen, Post, Banken
- amenity=drinking water, toilets
- Shelter
- Mapping
- Briefkästen, Leerungszeiten
- Shops aller Art, Öffnungszeiten, Telefonnummer
- Restaurants, Öffnungszeiten, Telefonnummer
- Spielplätze
- Schulen
- Kindergärten
- Ampeln
- Bushaltestellen, Häuschen
- Parkplätze, Fahrradabstellanlagen
- Eigentlich alles, was mich auch als Tourist interessieren würde.
Garmin POI limitations
Leszek Pawlowicz found that the POI data displayed by garmin devices are not limited by a certain number of characters, but rather by screen space, which makes a difference because of the proportianal font used by the garmin handheld devices.
The garmin can show 2 lines of text for the name of a POI, and 4 lines of text for the description.
If the text in a line exceeds the displayable length, then the garmin will wrap that line, provided there is room for another line. Whether or not a hyphen is inserted seems to depend on the following factors:
- Hyphens are only inserted after or between letters of the roman alphabet (as catogorized by the device)
- No hyphen is inserted if more than one character would have to be moved to the next line to make room for the hyphen (a minus sign)
An explicit line break in the name or the description is honored by the device.
A test revealed that the following numbers of repeats of a single iso-8859-1 character fits into one line on the POI display page:
characters_per_line = { ?! => 48, ?" => 24, ?# => 18, ?$ => 16, ?% => 18, ?& => 18, ?' => 48, ?( => 29, ?) => 29, ?* => 18, ?+ => 20, ?, => 48, ?- => 18, ?. => 48, ?/ => 18, ?0 => 18, ?1 => 18, ?2 => 18, ?3 => 18, ?4 => 18, ?5 => 18, ?6 => 18, ?7 => 18, ?8 => 18, ?9 => 18, ?: => 48, ?; => 48, ?< => 18, ?= => 18, ?> => 18, ?? => 18, ?@ => 16, ?A => 18, ?B => 18, ?C => 18, ?D => 18, ?E => 18, ?F => 18, ?G => 18, ?H => 18, ?I => 29, ?J => 18, ?K => 18, ?L => 20, # test ?M => 18, ?N => 18, ?O => 18, ?P => 18, ?Q => 18, ?R => 18, ?S => 18, ?T => 20, ?U => 18, ?V => 18, ?W => 18, ?X => 18, ?Y => 16, ?Z => 18, ?[ => 29, ?\ => 18, ?] => 29, ?^ => 18, ?_ => 18, ?` => 29, ?a => 20, ?b => 20, ?c => 24, ?d => 20, ?e => 20, ?f => 29, ?g => 20, ?h => 20, ?i => 48, ?j => 36, ?k => 20, ?l => 48, ?m => 16, ?n => 20, ?o => 20, ?p => 20, ?q => 20, ?r => 24, ?s => 24, ?t => 29, ?u => 20, ?v => 20, ?w => 16, ?x => 20, ?y => 20, ?z => 20, ?{ => 29, ?| => 48, ?} => 29, ?~ => 20, 128 => 14, # Returntastenpfeil 129 => 20, # Karo 130 => 20, # Karo 131 => 20, # Karo 132 => 20, # Karo 133 => 16, # Ellipsis 134 => 20, # Karo 135 => 20, # Karo 136 => 20, # Karo 137 => 20, # Karo 138 => 20, # Karo 139 => 20, # Karo 140 => 12, # OE ohne hyphenation 141 => 14, # Returntastenpfeil 142 => 20, # Karo mit hyphenation 143 => 20, # Karo 144 => 20, # Karo 145 => 20, # Karo 146 => 20, # Karo 147 => 20, # Karo 148 => 20, # Karo 149 => 20, # Karo 150 => 20, # Karo 151 => 20, # Karo 152 => 20, # Karo 153 => 13, # TM 154 => 20, # Karo mit hyphenation 155 => 20, # Karo 156 => 13, # oe mit hyphenation 157 => 20, # Karo 158 => 20, # Karo mit hyphenation 159 => 16, # :Y mit 160 => 20, # Karo 161 => 48, # ! über Kopf 162 => 20, # Karo 163 => 20, # Karo 164 => 20, # Karo 165 => 20, # Karo 166 => 20, # Karo 167 => 20, # Karo 168 => 20, # Karo 169 => 14, # (c) 170 => 20, # Karo 171 => 20, # Karo 172 => 20, # Karo 173 => 20, # Karo 174 => 14, # (R) 175 => 20, # Karo 176 => 29, # ° 177 => 20, # +/- 178 => 36, # ^2 179 => 20, # Karo 180 => 20, # Karo 181 => 20, # Karo 182 => 20, # Karo 183 => 20, # Karo 184 => 20, # Karo 185 => 20, # Karo 186 => 36, # ^0 187 => 20, # Karo 188 => 20, # Karo 189 => 20, # Karo 190 => 20, # Karo 191 => 18, # ? über Kopf 192 => 18, # `A 193 => 18, # 'A 194 => 18, # ^A 195 => 18, # ~A 196 => 18, # :A 197 => 18, # °A 198 => 12, # AE 199 => 18, # ,C 200 => 18, # `E 201 => 18, # 'E 202 => 18, # ^E 203 => 18, # :E 204 => 29, # `I 205 => 29, # 'I 206 => 29, # ^I 207 => 24, # :I 208 => 16, # -D 209 => 18, # ~N 210 => 18, # `O 211 => 18, # 'O 212 => 18, # ^O 213 => 18, # ~O 214 => 18, # :O 215 => 18, # x 216 => 14, # /O 217 => 18, # `U 218 => 18, # 'U 219 => 18, # ^U 220 => 18, # :U 221 => 16, # 'Y 222 => 20, # |o 223 => 18, # ß 224 => 20, # `a 225 => 20, # 'a 226 => 20, # ^a 227 => 20, # ~a 228 => 20, # :a 229 => 20, # °a 230 => 13, # ae 231 => 24, # ,c 232 => 20, # `e 233 => 20, # 'e 234 => 20, # ^e 235 => 20, # :e 236 => 36, # `i 237 => 36, # 'i 238 => 29, # ^i 239 => 24, # :i 240 => 20, # del 241 => 20, # ~n 242 => 20, # `o 243 => 20, # 'o 244 => 20, # ^o 245 => 20, # ~o 246 => 20, # :o 247 => 18, # frac 248 => 13, # /o 249 => 20, # `u 250 => 20, # 'u 251 => 20, # ^u 252 => 20, # ü 253 => 20, # 'y 254 => 20, # |o 255 => 20 # :y }
This data suggests that the usable display width is 145 pixels wide and that the following widths of characters exists: 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
A blank (code point 32) on the garmin display is as wide as 2 i characters, thats 6 pixels.
OpenStreetBugs Liste für den Garmin erstellen
OpenStreetBugs ist eine Web-basierte Datenbank von Fehlern in den Openstreetmap Daten.
Dieser Abschnitt enthält ein Skript, das die Openstreetbugs für Oldenburg halbwegs zuverlässig herunterlädt. Sie stehen hinterher als Waypoints in der Datei openstreetbugsgarmin.xml. Die Beschreibung wird so in <name> und <desc> aufgeteilt, dass die maximal mögliche Information auf Garmin Handhelds angezeigt wird
# File "save_openstreetbugs.rb" # Copyright (C) 2009 Rrr # You may use, modify, distribute this code and modifications of it in any # way you like. Share and enjoy! require "net/http" require "rexml/document" require "iconv" # Boundaries have to be Floats # boundaries of Oldenburg on the map N = 53.23 S = 53.081 W = 8.125 O = 8.3 # area should be divided in n columns and m rows. # GPX files requested for too large areas do not contain all bugs in this area. n = 13 m = 18 # GPX files will also contain bugs outside the requested area. # duplicates have to be eliminated. host = "openstreetbugs.appspot.com" failed = succeeded = total = 0 target_document = REXML::Document.new(<<EOD) <?xml version="1.0" standalone="no" ?> <gpx xmlns="http://www.topografix.com/GPX/1/1" creator="bugsorter" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" /> EOD fingerprints = {} m.times {|i| bottom = (N-S) / m * i + S top = (N-S) / m * (i+1) + S n.times {|j| left = (O-W) / n * j + W right = (O-W) / n * (j+1) + W location = "/getGPX?b=#{bottom}&t=#{top}&l=#{left}&r=#{right}" puts "Getting #{location}" total += 1 response = Net::HTTP.get_response(host, location) if response.kind_of? Net::HTTPSuccess gpx = response.body succeeded += 1 puts "succeeded" xml = REXML::Document.new(gpx) xml.elements.each("//wpt"){|wpt| # get fingerprint for this bug fingerprint = [wpt.attributes["lat"], wpt.attributes["lon"], wpt.elements["desc"].text] if fingerprints[fingerprint] # known bug, ignore else # new bug, add fingerprints[fingerprint] = true target_document.root.add(wpt) end } else failed += 1 puts "failed" end } } $character_width = { 32 => 6, # blank ?! => 3, ?" => 6, ?# => 8, ?$ => 9, ?% => 8, ?& => 8, ?' => 3, ?( => 5, ?) => 5, ?* => 8, ?+ => 7, ?, => 3, ?- => 8, ?. => 3, ?/ => 8, ?0 => 8, ?1 => 8, ?2 => 8, ?3 => 8, ?4 => 8, ?5 => 8, ?6 => 8, ?7 => 8, ?8 => 8, ?9 => 8, ?: => 3, ?; => 3, ?< => 8, ?= => 8, ?> => 8, ?? => 8, ?@ => 9, ?A => 8, ?B => 8, ?C => 8, ?D => 8, ?E => 8, ?F => 8, ?G => 8, ?H => 8, ?I => 5, ?J => 8, ?K => 8, ?L => 7, ?M => 8, ?N => 8, ?O => 8, ?P => 8, ?Q => 8, ?R => 8, ?S => 8, ?T => 7, ?U => 8, ?V => 8, ?W => 8, ?X => 8, ?Y => 9, ?Z => 8, ?[ => 5, ?\\ => 8, ?] => 5, ?^ => 8, ?_ => 8, ?` => 5, ?a => 7, ?b => 7, ?c => 6, ?d => 7, ?e => 7, ?f => 5, ?g => 7, ?h => 7, ?i => 3, ?j => 4, ?k => 7, ?l => 3, ?m => 9, ?n => 7, ?o => 7, ?p => 7, ?q => 7, ?r => 6, ?s => 6, ?t => 5, ?u => 7, ?v => 7, ?w => 9, ?x => 7, ?y => 7, ?z => 7, ?{ => 5, ?| => 3, ?} => 5, ?~ => 7, 128 => 10, # Returntastenpfeil 129 => 7, # Karo 130 => 7, # Karo 131 => 7, # Karo 132 => 7, # Karo 133 => 9, # Ellipsis 134 => 7, # Karo 135 => 7, # Karo 136 => 7, # Karo 137 => 7, # Karo 138 => 7, # Karo 139 => 7, # Karo 140 => 12, # OE ohne hyphenation 141 => 10, # Returntastenpfeil 142 => 7, # Karo mit hyphenation 143 => 7, # Karo 144 => 7, # Karo 145 => 7, # Karo 146 => 7, # Karo 147 => 7, # Karo 148 => 7, # Karo 149 => 7, # Karo 150 => 7, # Karo 151 => 7, # Karo 152 => 7, # Karo 153 => 11, # TM 154 => 7, # Karo mit hyphenation 155 => 7, # Karo 156 => 11, # oe mit hyphenation 157 => 7, # Karo 158 => 7, # Karo mit hyphenation 159 => 9, # :Y mit 160 => 7, # Karo 161 => 3, # ! über Kopf 162 => 7, # Karo 163 => 7, # Karo 164 => 7, # Karo 165 => 7, # Karo 166 => 7, # Karo 167 => 7, # Karo 168 => 7, # Karo 169 => 10, # (c) 170 => 7, # Karo 171 => 7, # Karo 172 => 7, # Karo 173 => 7, # Karo 174 => 10, # (R) 175 => 7, # Karo 176 => 5, # ° 177 => 7, # +/- 178 => 4, # ^2 179 => 7, # Karo 180 => 7, # Karo 181 => 7, # Karo 182 => 7, # Karo 183 => 7, # Karo 184 => 7, # Karo 185 => 7, # Karo 186 => 4, # ^0 187 => 7, # Karo 188 => 7, # Karo 189 => 7, # Karo 190 => 7, # Karo 191 => 8, # ? über Kopf 192 => 8, # `A 193 => 8, # 'A 194 => 8, # ^A 195 => 8, # ~A 196 => 8, # :A 197 => 8, # °A 198 => 12, # AE 199 => 8, # ,C 200 => 8, # `E 201 => 8, # 'E 202 => 8, # ^E 203 => 8, # :E 204 => 5, # `I 205 => 5, # 'I 206 => 5, # ^I 207 => 6, # :I 208 => 9, # -D 209 => 8, # ~N 210 => 8, # `O 211 => 8, # 'O 212 => 8, # ^O 213 => 8, # ~O 214 => 8, # :O 215 => 8, # x 216 => 10, # /O 217 => 8, # `U 218 => 8, # 'U 219 => 8, # ^U 220 => 8, # :U 221 => 9, # 'Y 222 => 7, # |o 223 => 8, # ß 224 => 7, # `a 225 => 7, # 'a 226 => 7, # ^a 227 => 7, # ~a 228 => 7, # :a 229 => 7, # °a 230 => 11, # ae 231 => 6, # ,c 232 => 7, # `e 233 => 7, # 'e 234 => 7, # ^e 235 => 7, # :e 236 => 4, # `i 237 => 4, # 'i 238 => 5, # ^i 239 => 6, # :i 240 => 7, # del 241 => 7, # ~n 242 => 7, # `o 243 => 7, # 'o 244 => 7, # ^o 245 => 7, # ~o 246 => 7, # :o 247 => 8, # frac 248 => 11, # /o 249 => 7, # `u 250 => 7, # 'u 251 => 7, # ^u 252 => 7, # ü 253 => 7, # 'y 254 => 7, # |o 255 => 20 # :y } no_hyphenation = [?I, ?c, ?f, ?i, ?j, ?l, ?r, ?s, ?t, 140, 198, 204, 205, 206, 231,236,237,238] def split_text_into_garmin_lines(text) text = text.sub(/\A */,"") first = "" length = 0 index = 0 while (index < text.length) && (length < 145) asc = text[index] chlen = $character_width[asc] unless chlen.nil? if (length + chlen) > 145 break end length += chlen first << asc end index += 1 end if index < text.length [first] + split_text_into_garmin_lines(text[index..-1]) else [first] end end # distribute data between name and desc lines target_document.elements.each("//wpt"){|wpt| desc = wpt.elements["desc"] text = desc.text text = Iconv.conv("iso-8859-1//IGNORE//TRANSLIT", "utf-8", text) lines = split_text_into_garmin_lines(text.gsub("\n","")) if lines.size > 6 lines = split_text_into_garmin_lines(text.gsub( /\^\*\] *\|* */,";")) end name = REXML::Element.new("name") wpt.insert_before(desc,name) name.text = Iconv.conv("utf-8", "iso-8859-1", lines[0..1].to_a.join("\n")) desc.text = Iconv.conv("utf-8", "iso-8859-1", lines[2..5].to_a.join("\n")) } target_document.write(File.open("openstreetbugsgarmin.xml","w"))
Danach wandelt ein Kommando wie
gpsbabel -w -i gpx -f ../openstreetbugsgarmin.xml \ -o garmin_gpi,category=bugs,bitmap=../poi/errorklein.bmp \ -F openstreetbugs.gpi
die Bugs in Garmin POIs um.