[osm-bnsu] [Koeln] Straßenbahnlinien 16 und 18 zwischen Köln und Bonn

Michael Reichert osm-ml at michreichert.de
Fr Jun 15 14:42:43 CEST 2018


Hallo Robert,

Am 2018-06-14 um 10:57 schrieb Robert.Tillmann at STADT-KOELN.DE:
> gerne möchte ich einmal auf das bisher Gesagte eingehen. Mein Problem mit diesen Argumentationen ist, dass sie an meiner Wirklichkeit und an der von 99% der OSM-Kartennutzer vorbeigeht - "Kartennutzer" im Sinne derer, die das Ergebnis als Karte betrachten und diese nutzen, die vielleicht noch nicht einmal mapper sind, geschweige denn hier mitdiskutieren würden.

Bitte bedenke, dass wir nicht für eine bestimmte Karte mappen, sondern
für viele. Nicht alle Anwendungen, die OSM-Daten nutzen, sind Karten.

Tipp: Kennst du schon station=light_rail und station=subway? Das wird
zur Kennzeichnung von Stationen an railway=light_rail bzw.
railway=subway verwendet.

> Meiner Meinung nach ist die Argumentation sehr einfach: An den Straßenbahnhaltestellen der Linien 16 und 18 zwischen Köln und Bonn halten nur Straßenbahnen. Somit darf ich als Nutzer des ÖPNV von OSM erwarten nicht in die Irre geführt zu werden. Andersherum gesagt: An dem Tag, an dem dort fahrplanmäßig ein Regionalzug hält, wären das dann natürlich Bahnhöfe. 

Du wirst auch nicht in die Irre geführt. Die Verkehre, die auf einer
Infrastruktur durchgeführt werden, werden in OSM als Routenrelationen
erfasst. Diese enthalten auch die Haltestellen (genauer: Haltepositionen
und/oder Bahnsteige).

> Ob es aber möglich ist, dass dort Güterzüge fahren, fuhren oder fahren werden ist irrelevant. Der Ausbau des Gleiskörpers, der Oberleitung, der Signalisierung jetzt, in der Vergangenheit oder in der Zukunft mag für einen kleinen Kreis begeisterter Eisenbahninteressierter wichtig sein. OSM bietet ja auch die Möglichkeit alle diese Informationen in weniger zentralen tags zu hinterlegen, was ich definitiv als Bereicherung empfinde. Nichtsdestotrotz halte ich es nicht für gerechtfertigt, dass gerade Spezialisten in ihrem Sachgebiet der Mehrheit ihren Blickwinkel diktieren. 

Doch es ist relevant. OSM wird auch im Bahnbereich genutzt, bloß nicht
so offensichtlich. Ich kann das aus meiner beruflichen Erfahrung in
einer Firma bestätigen, die nicht speziell auf Bahn-Irgendwas
spezialisiert ist. OSM ist die einzige ernsthafte, freie, überregionale
und unternehmensübergreifende Datenquelle bzw. Karte, die Informationen
über die Eisenbahninfrastruktur enthält.

Wie möchtest du bitte einem Nutzer eines Eisenbahnrouters für Güterzüge
erklären, dass Brühl-Vochem in der Liste der durchfahrenen Bahnhöfe
fehlt, die der Router als Ergebnis ausgibt? (Mein Eisenbahnrouter hat
die Funktion noch nicht, aber irgendjemand wird bestimmt eines Tages
dieses Feature wünschen) Man kann für einen Eisenbahnzug von Brühl Gbf
über Brühl-Vochem und Wesseling nach Hersel bestellen, also ist es eine
Eisenbahninfrastruktur und Hersel ein Bahnhof.

> Dementsprechend halte ich es auch nicht für zielführend, dass solche Dinge, die alle betreffen, in Foren zu diskutieren, in denen sich zu 99% Spezialisten tummeln.

Es gibt auch noch das deutschsprachige OpenStreetMap-Forum, das kein
Spezialforum ist.
https://forum.openstreetmap.org/viewforum.php?id=14

> Die allgemein wichtige Attributierung railway= station oder railway= tram_stop sollte nicht auf Basis derartig spezieller Argumentationen gefällt werden. Das Ergebnis, wie bereits einleitend angeführt, entspricht einfach nicht den Endverbraucher-Erwartungen, die "man" an die Karte OSM stellt. Ich sage bewusst "Karte", weil ich das Totschlagargument: "Wir mappen nicht für die Karte!" gerade in diesem Fall für schlichtweg falsch halte: Wofür denn bitte sonst? Für eine hochspezialisierte Datensammlung verschiedenster Fachbereiche, die aber dann auch nur noch von den jeweiligen Fachleuten zu verstehen, zu bedienen und auszuwerten ist?

Wenn man eine Karte auf Basis von OSM-Daten erstellen möchte, die den
ÖPNV korrekt darstellt, genügt es nicht, einfach nur die Tags an Ways
und Nodes auszuwerten. Es ist etwas mehr Nachdenken erforderlich, aber
es gelingt sehr wohl, eine solche Karte zu rendern.

Wer aus einer PostGIS-Datenbank heraus rendert, die mit Osm2pgsql
importiert worden ist und Slim-Tables enthält, kann mit den folgenden
SQL-Abfragen einen Haltestellen- und einen Linien-Layer ähnlich wie
https://www.geofabrik.de/maps/styles-oepnv-gftopo.png (linke Seite)
rendern. Einen laufenden Tileserver mit diesem Stil gibt es leider
nicht. Weiter unten habe ich mal die zentrale SQL-Abfrage und
beispielhaft einen Auszug aus dem CartoCSS-Stylings des gezeigten
Kartenstils eingefügt.

Der Trick ist, nur die Stationen zu rendern, die Mitglied mindestens
einer Routenrelationen sind. Zwar sind die Routenrelationen in der
Datenbanktabelle planet_osm_line enthalten, aber diese Tabelle enthält
nur die Tags und die Geometrie aller Mitglieder-Ways als
MultiLineString. Die Tabelle planet_osm_rels enthält zwar keine
Geometrie, aber ihre Spalte "parts" enthält die IDs aller
Mitgliederobjekte als eine Bigint-Array-Spalte. Die Spalte "way_off"
enthält den Index des Arrays des ersten Ways in der Mitgliederliste. Das
heißt, dass die Spalte "parts" nicht nach der Mitgliederreihenfolge in
den OSM-Rohdaten sortiert ist, aber für uns ist die Reihenfolge hier
nicht von Bedeutung.

Anhand ihrer Relationsmitglieschaften ordnet man den Punkten, die man
erhält, die Verkehrsmittel zu, d.h. man erhält dann die
Verkehrsmittelkategorien, die eine bestimmte Haltestelle bedienen und
kann dementsprechend das passende Icon rendern. Das kann entweder das
höchstwertigste sein (beim Köln Hbf "R", bei Köln Steinstraße "S", bei
Köln Severinstraße "Tram") oder kombinierte Icons.

Die weiter unten stehende SQL-Abfrage gibt einem pro Zeile die Spalten
name, geom, s_bahn, subway, tram, train
zurück.

In CartoCSS könnte man dann z.B. Folgendes für einen S-Bahn-Stationen
ohne Regionalverkehr schreiben/stylen:
#stations[s_bahn='yes'][train!='yes'][zoom>=12] {
  shield-face-name: @sans;
  shield-file: "img/icon/s-bahn.svg";
  shield-name: '[name]';
  shield-wrap-width: 50;
  shield-unlock-image: true;
  shield-fill: #006f35;
  shield-halo-fill: #ffffff;
  shield-halo-radius: 2;
  shield-placement-type: 'simple';
  shield-placements: 'N,S';
  shield-size: 11;
  shield-transform: scale(0.7);
  shield-text-dy: 11;
  shield-min-distance: 1;
  shield-vertical-alignment: auto;
}

Layer, der die Haltestellen aller Schienenverkehrsmittel enthält:

(SELECT name, ST_Centroid(way) as geom, s_bahn, subway, tram, train
 FROM (
  SELECT
    point.name AS name,
    ST_Union(point.way) AS way,

      -- S-Bahn
      max(
        CASE
          WHEN (
            line.ref SIMILAR TO '(S|RT)( )?[0-9]+'
            AND line.route IN ('train', 'light_rail', 'tram')
          )
          THEN 'yes'
        END
      ) AS s_bahn,

      -- U-Bahn
      max(
        CASE
          WHEN (
            line.ref SIMILAR TO 'U( )?[0-9]+'
            AND line.route IN ('light_rail', 'subway', 'tram')
          )
          THEN 'yes'
        END
      ) AS subway,

      -- Straßenbahn
      max(
        CASE
          WHEN (
            line.ref NOT SIMILAR TO '(U|S)( )?[0-9]+'
            AND line.route IN ('light_rail', 'subway', 'tram')
          )
          THEN 'yes'
        END
      ) AS tram,

      -- Regionalverkehr
      max(
        CASE
          WHEN (
            line.ref NOT SIMILAR TO '(U|S)( )?[0-9]+'
            AND line.route = 'train'
          )
          THEN 'yes'
        END
      ) AS train

    FROM
      planet_osm_point AS point,
      planet_osm_rels AS rels,
      planet_osm_line AS line

    WHERE ST_DWithin(point.way, line.way, 10)
      -- Relationen haben in planet_osm_line negative IDs
      AND line.osm_id < 0
      AND line.route IN ('train', 'light_rail', 'subway', 'tram')
      AND line.osm_id = - rels.id
      -- prüft, ob Node-ID in der Mitgliederliste enthalten ist
      AND point.osm_id = ANY(rels.parts[0:rels.way_off])
      AND (
        point.public_transport = 'stop_position'
        OR point.railway IN ('tram_stop', 'station', 'halt')
      )
      -- Haltestellen ohne Namen sind komisch
      AND point.name IS NOT NULL
      AND point.way && !bbox!

    GROUP BY point.name

) AS data WHERE train IS NULL
) AS data

Es werden nur Nodes mit public_transport=stop_position oder
railway=tram_stop/station/halt berücksichtigt. Damit pro Haltestelle
nicht mehrere Symbole gerendert werden, da mehrerer Nodes mit
public_transport=stop_position in OSM gemappt sind, steht am Ende ein
"GROUP BY point.name" und am Anfang ein "ST_Centroid(way)". Dadurch
enthält das Ergebnis der Abfrage pro Haltestelle nur einen Punkt,
nämlich den Schwerpunkt. Die Gruppierung erfolgt anhand des Namens.
Manche Städte haben für benachbarte Haltestellen an Verkehrsknoten
merhere Namen und diese Unterschiede sind diesen Städten teils sehr
wichtig (z.B. "Hauptbahnhof Nord" vs. "Hauptbahnhof Süd" vs. "Hamburg
Hbf" in Hamburg).

Die SQL-Abfrage funktioniert sowohl mit Routenrelationen nach Public
Transport Version 2, als auch nach älteren Mappingschemata. Die
Relationen müssen nicht einmal geordnet sein, sodass kleinere Defekte
sich nicht sofort schädlich auswirken. Wenn Routenrelationen keine
Haltepositionen enthalten, ist das ein kleines Problem, das man aber
durch Verwendung der Bahnsteige (Platforms) lösen kann (im Beispiel
nicht implementiert).

S-Bahn: ref=* beginnt mit "S " oder "RT " gefolgt von einer Nummer und
die Routenrelation hat route=train/light_rail/tram. (RT = RegioTram Kassel)

U-Bahn: ref=* beginnt mit "U " gefolgt von einer Nummer und die
Routenrelation hat route=light_rail/subway/tram. Dies unterstützt auch
Städte, die eine Stadtbahn als U-Bahn vermarkten, z.B. Stuttgart,
Frankfurt und viele Städte in NRW.

Tram: ref=* beginnt NICHT mit "U " oder "S " gefolgt von einer Nummer
und die Routenrelation hat route=light_rail/subway/tram.

Regionalverkehr: ref=* beginnt NICHT mit "U " oder "S " gefolgt von
einer Nummer und die Routenrelation hat route=train. Die Liniennummern
von Regionalzügen fangen mit allerlei Buchstaben an.

Bushaltestellen sind viel einfacher zu rendern, dafür hat der Stil, aus
dem diese Abfragen stammen, einen separaten Layer, der aber ebenso
Bushaltestellen gleichen Namens gruppiert.

"ST_DWithin(point.way, line.way, 10)" und "point.way && !bbox!"
schränken den Suchbereich räumlich ein. "!bbox!" ist eine
Mapnik-Variable für die Bounding-Box des Kartenausschnitts, der
gerendert werden soll und für den Daten von der Datenbank abgefragt
werden. Durch die Beschränkung auf Routenrelationen, die maximal 10
Web-Mercator-Einheiten (ca. 6 Meter hierzulande) von der Halteposition
bzw. dem Haltestellen-Node entfernt sind, läuft die Abfrage überhaupt
schnell genug.

Gute ÖPNV-Karten kann man nicht so einfach weltweit machen, da die
Nahverkehrssysteme in anderen Ländern andere Eigenheiten haben. Deshalb
ist die Darstellung von ÖPNV in internationalen Kartenstilen wie OSM
Carto nicht so fortgeschritten wie beispielsweise in der ÖPNVKarte oder
die OpenPTMap [1].

Im Hamburger Verkehrsverbund wurden vor einigen Jahren hvv:psv_type=R
erfasst (es gibt auch hvv:psv_type=S, hvv:psv_type=U usw.). Das ist die
OSM-Übersetzung des Schilds, das am Bahnhofseingang hängt. Ich halte es
für eine suboptimale Lösung, kann damit aber leben. Im VRS-Gebiet gibt
es seit dem VRS-Haltestellenimport spezielle VRS-Tags an den Stationen.

https://wiki.openstreetmap.org/wiki/VRS/Haltestellenimport

Wenn die Karte nur das VRS-Gebiet abdecken soll, könnte man auch mit
einem SQL-Join einer VRS-Haltestellentabelle und der OSM-Daten über die
in OSM erfassten VRS-Haltestellenummern (VRS:ref=*) arbeiten.

Viele Grüße

Michael



PS Diese E-Mail wurde von mir als Privatperson verfasst.


[1] Der Quellcode eines Forks davon ist unter
https://github.com/giggls/openptmap zu finden. Für ein Rendering auf dem
deutschen Tileserver muss man den Stil nochmal neu schrieben, weil er zu
langsam ist. Wer da Zeit investieren möchte, möge sich bitte bei Sven
Geggus melden.


-- 
Per E-Mail kommuniziere ich bevorzugt GPG-verschlüsselt. (Mailinglisten
ausgenommen)
I prefer GPG encryption of emails. (does not apply on mailing lists)

-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : signature.asc
Dateityp    : application/pgp-signature
Dateigröße  : 833 bytes
Beschreibung: OpenPGP digital signature
URL         : <http://lists.openstreetmap.de/pipermail/bonn-rhein-sieg/attachments/20180615/890adc91/attachment.sig>


Mehr Informationen über die Mailingliste bonn-rhein-sieg