Hallo!
An der Grenze zwischen Deutschland und Österreich ist aufgefallen, dass
diese Grenze anders gerendert wird, als andere Grenzen. Am Dreiländereck
im Bodensee kann man das ganz gut sehen:
<http://www.openstreetmap.org/browse/node/45072653>
Über die Ursache dafür wurde hier bisher kaum ein Wort verloren (man
macht lieber seine Späßchen). Am nächsten dran war bisher Andreas Labres:
<http://lists.openstreetmap.org/pipermail/talk-de/2010-October/078441.html>
<http://lists.openstreetmap.org/pipermail/talk-de/2010-November/078935.html>
Seine Vermutung ist, dass der Mapnik-Style die Relationen
type=multipolygon und type=boundary unterschiedlich behandelt.
Schauen wir doch einfach mal nach. Der folgende Text ist ein wenig
ausführlicher und erklärender als zur Beschreibung der Ursache
notwendig, damit auch Leute, die sich noch nicht mit dem Rendering mit
Mapnik beschäftigt haben, auch noch etwas verstehen.
Der Mapnik-Style liegt in
<http://trac.openstreetmap.org/browser/applications/rendering/mapnik>
Unter 'Revision Log' oben rechts gibt es eine Versionsgeschichte. Der
eigentliche Style ist die Datei
<http://svn.openstreetmap.org/applications/rendering/mapnik/osm.xml>
Das Rendern der Grenzen ist eine Include-Datei ausgegliedert
<http://svn.openstreetmap.org/applications/rendering/mapnik/inc/layer-admin.xml.inc>
Hier stellen wir folgendes fest:
++ Das alles ist ziemlich übersichtlich.
++ Von type=multipolygon oder type=boundary sieht man hier nichts. Hier
kann der Unterschied nicht liegen. Er muss von woanders kommen.
++ Die Geometrie stammt aus der PostGIS-Tabelle prefix_roads. Dies ist
eine Teilmenge der Tabelle prefix_line. Diese beiden Tabellen enthalten
nur Linien. Die Tabelle prefix_polygon, die alle Flächen enthält, wird
nicht erwähnt. Ebenso nicht die Tabelle prefix_point mit allen Punkten.
- Alle Grenzen werden mit sehr geringer Deckkraft (opacity) zwischen 0.1
und 0.3 gezeichnet.
- Die Grenzen werden als lila Linien unterschiedlicher Breite
gezeichnet. Sie sehen wie folgt aus:
- admin_level=2 (Staat) wird durchgezogen, sehr breit
- admin_level=4 (Land, Kanton) wird gleichmäßig gestichelt, breit
- admin_level=5 (Regierungsbezirk) wird gestrichelt (lang, kurz, kurz)
- admin_level=6 (Kreis, Bezirk) wird gestrichelt (lang, kurz)
- admin_level=8 (Gemeinde) wird gleichmäßig gestrichelt, schmal
- Die SQL-Anfragen, Layer und Rules sind so angelegt, dass jeder Weg in
prefix_roads höchstens einmal gezeichnet wird.
Eine erste Vermutung ist, dass ausschließlich Wege mit
boundary=administrative und admin_level=* gerendert werden. Relationen
spielen also keine Rolle. Dafür spricht z. B. die folgende Stelle:
<http://www.openstreetmap.org/?lat=50.74158&lon=7.24558&zoom=15&layers=M>
Besser sieht man es hier:
<http://toolserver.org/~osm/styles/?lat=50.74158&lon=7.24558&zoom=15&layers=000BF0FF0000F0FF00>
Der Bach (Pleisbach) bildet die Grenzen zwischen Hennef (im Nord-Osten,
Relation 36042) und Königswinter (im Süden, Relation 173113). In den
beiden Grenzrelationen (type=multipolygon, beide vollständig) ist nur
der waterway=river als outer eingetragen. Ein Weg mit
boundary=administrative und admin_level=8 fehlt hier. Überall sonst im
Rhein-Sieg-Kreis sind Wege mit diesen Tags an den anderen Grenzen
vorhanden. Wir sehen also: Eine Multipolygon-Relation alleine reicht
nicht aus, damit sie als Grenze gerendert wird.
Ein Blick auf die gerenderten Karten (Beispiel Bodensee) zeigt, dass die
letzten beiden Punkte obiger Liste sich irgendwie widersprechen: Im
Bodensee entspricht die Grenze Schweiz-Deutschland keinem der oben
beschriebenen Aussehen. Vielmehr scheint hier das Aussehen von
admin_level=2 und admin_level=4 übereinander gelegt worden zu sein.
Tatsächlich liegen hier zwei Relationen mit type=boundary und dem
passendem admin_level (2=Schweiß, 4=Thurgau) übereinander. An der Grenze
Österreich-Deutschland ist das genau so – nur werden hier Relationen mit
type=multipolygon benutzt.
Die Vermutung ist also, dass irgendwie übereinander liegende Linien mit
unterschiedlichem admin_level in die Tabelle prefix=roads eingetragen
werden, die aus Relationen mit type=boundary stammen.
Die genannten Tabellen werden vom Programm osm2psql erzeugt. Der
Quelltext liegt hier:
<http://trac.openstreetmap.org/browser/applications/utils/export/osm2pgsql>
Das Programm nimmt OSM-Dateien bzw. Differenzen von OSM-Dateien und
trägt diese in eine Postgres-Datenbank mit PostGIS-Erweiterung ein.
Nodes kommen in die Tabelle prefix_point; Wege, die Linien und kleine
Flächen sind, nach Tabelle prefix_line und ggf. als Kopie nach Tabelle
prefix_roads und Wege, die Flächen sind, nach Tabelle prefix_polygon.
Bei diesen Schritten werden die OSM-Daten so gut wie gar nicht
bearbeitet, sondern Geometrie und Tags unverändert übernommen.
In die Tabelle prefix_roads kommen Wege mit boundary=adminstrative,
railway=* oder highway=(motoway|trunk|primary|secondary|)(_link)?. Die
Tabelle dient dazu bei kleinen Zoomleveln die Anzahl der Linien je
Kachel zu begrenzen.
Bei der Unterscheidung zwischen Linien und Flächen hilft eine
Konfigurationsdatei,
<http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/default.style>
bei der man für verschiedene Schlüssel angeben kann, ob geschlossene
Wege als Linien (highway, barrier) oder Flächen (building, landuse)
angesehen werden sollen. Im Zweifel kann der Mapper hier mit area=yes
oder area=no nachhelfen und eine Interpretation erzwingen.
Bei Relationen ist das ganz anders. Mapnik kennt keine Relationen,
sondern nur Punkte, Linien oder Flächen. Deswegen muss hier osm2psql die
ganze Arbeit machen, und die Relationen vorverarbeiten, indem alle
Mitglieder der Relationen gesucht und geeignet interpretiert werden.
Verarbeitet werden nur Relationen mit type=route, type=multipolygon oder
type=boundary. Von den Rollen der Mitglieder wird nur 'inner' erkannt.
Andere Rollen wie 'outer', 'enclave' oder 'exclave' sind in Quelltext
nicht zu finden.
Die Routen sind hier uninteressant. Hier werden nur neue Tags aus
vorhandenen erzeugt und die Route als Linie in die Tabelle prefix_line
und ggf. prefix_roads eingetragen.
Multipolygone und Grenzen werden unterschiedlich verarbeitet:
Multipolygone werden immer als Flächen aufgefasst und, wenn sie gültig
sind (das wird ausführlich nach den Multipolygon-Regeln geprüft, mehrere
Flächen und Löcher sind erlaubt), immer in die Tabelle prefix_polygon
eingetragen. Grenzen werden sowohl als Linien als auch als Flächen
aufgefasst. Sie werden immer in die Tabelle prefix_line und prefix_roads
eingetragen und zusätzliche, wenn sie gültig sind, in die Tabelle
prefix_polygon eingetragen.
Wer sich das im Quelltext ansehen will:
<http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/output-pgsql.c>
Ich empfehle eine Suche nach 't_line', 't_roads' und 't_poly'. Die
werden sehr „symetrisch“ benutzt. Nur an einer Stelle ist eine
zusätzliche Benutzung von 't_poly' vorhanden. Diese zusätzliche
Benutzung ist des Pudels Kern und man versteht sie, wenn man nach
'make_polygon' und 'make_boundary' sucht und auf den vierten Parameter
beim Aufruf von 'build_geometry' achtet.
Damit ist das Rätsel also gelöst. Aufgrund einer Eigenschaft von
osm2psql, die außerhalb des Quelltexts offensichtlich nicht dokumentiert
ist, und von der nur sehr wenige Leute wissen dürften, werden Relationen
mit type=boundary beim Rendern mit Mapnik (oder genauer: bei Syles für
Mapnik, die einfach vom Default-Mapnik-Style abgeleitet sind),
bevorzugt, indem sie sowohl als Flächen als auch als Linie in die
Datenbank eingetragen werden, was viele Leute nicht erwarten würden.
Diese Bevorzugung führt dazu, dass Grenzen mehrfach übereinander
gerendert werden können und damit immer fetter und besser sichtbar
werden. Hier fällt bei Europa-Ansichten besonders die Grenze der
Republik Tschechien auf. Gleichzeitig kann man die Art (d. h. den
admin_level) der Grenze aber immer schlechter erkennen. Schon wenn zwei
Gemeinde-Grenzen übereinander gelegt werden kann es vorkommen, dass die
Strichelchen der einen Grenze genau auf die Lücken der anderen Grenze
treffen.
Ich habe bisher ausdrücklich vermieden, von einem Fehler (entweder im
Mapnik-Style oder in osm2psql) zu sprechen, denn vielleicht ist dieses
Verhalten ja genau so beabsichtigt. In Zeiten, in denen ein
admin_level=2 zusammen mit höchstens einer anderen Grenze gerendert
wurde, sah das sicher toll aus.
Ich persönlich würde es bevorzugen, wenn jede Grenzlinie nur noch genau
einmal gerendert wird. Nur so kann man das Rendering genau kontrollieren
und z. B. an der Art der Strichelung der Grenze genau erkennen, um
welchen admin_level es sich hier handelt.
Die Lösung des Problems ist sicherlich nicht einfach. Das Unterbreiten
von Lösungsvorschlägen möchte ich aber anderen überlassen.
Abschließend sein die Bemerkung erlaubt, dass dieses Beispiel sehr schön
zeigt, wie dumm (und das ist nicht abwertend gemeint) Mapnik als
Renderer ist. Mapnik übernimmt nur Geometrien aus der Datenbank und
stellt sie nach gewissen Regeln graphisch dar. Intelligenz (z. B. in der
Form, dass von übereinander liegenden Linien nur die mit dem kleinsten
admin_level dargestellt wird), darf man hier nicht erwartet. Diese
Intelligenz gehört in eine Vorverarbeitungsstufe (in diesem Fall
osm2psql). Wenn viele Leute fordern, dass die Renderer intelligenter
werden sollen (Brückenrelationen, Abbiegerelationen, Auswahl von
Städtenamen usw.), dann reden sie eigentlich von osm2psql (oder einem
zukünftigem Ersatz). Leider ist diese Intelligenz nur schwer veränderbar
(C-Programmierung) und nach jeder Änderung ist ein neuer Import der
Datenbank (dauert sehr lange) fällig. Bisher ist auch nur sehr wenig
Intelligenz vorhanden: Außer den genannten Relationen ist noch einwenig
Code für die OpenCycleMap und die Parkplatzkarte vorhanden.
Mit freundlichen Grüßen
Adjuva
_______________________________________________
Talk-de mailing list
[email protected]
http://lists.openstreetmap.org/listinfo/talk-de