generalisierung und anreicherung von geodaten für den ... · die charakteristik der straßenzüge...
TRANSCRIPT
Gottfried Wilhelm Leibniz Universität HannoverFachgebiet Distributed ComputingDistributed Computing & Security Group
Bachelorarbeitim Studiengang Informatik (B. Sc.)
Generalisierung und Anreicherung von Geodatenfür den Mobile Security & Privacy Simulator
Verfasser: Carsten ProtschErstprüfer: Prof. Dr. rer. nat. M. SmithZweitprüferin: Prof. Dr.-Ing. G. von VoigtBetreuer: M. Sc. B. HenneDatum: 30. September 2011
Hannover, den 30.09.2011Hiermit versichere ich, dass ich diese Arbeit selbstständig verfasst habe undkeine anderen als die angegebenen Quellen und Hilfsmittel verwandt habe.
Carsten Protsch
Abstract
Der Mobile Security & Privacy Simulator simuliert Bedrohungen der IT-Sicherheit
und der Nutzerprivatsphäre moderner mobiler Endgeräte. Mögliche Maßnahmen zum
Schutz gegen diese Bedrohungen werden geprüft und bewertet. Die Simulationen
erfolgen auf Basis von Karten des OpenStreetMap-Projekts. In dieser Arbeit wer-
den Methoden entwickelt, um das Kartenmaterial für den Simulator aufzubereiten.
Es werden die Karten durch Datenreduktion vereinfacht. Partitionen werden erkannt
und zu einem gesamten Straßennetz zusammengeführt. Points of Interest werden au-
gewählt und mit dem Straßennetz verbunden.
i
Inhaltsverzeichnis
Abbildungsverzeichnis iv
Abkürzungsverzeichnis vi
1 Einleitung 1
1.1 Motivation dieser Arbeit . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Mobile Security & Privacy Simulator . . . . . . . . . . . . . . . . . 2
1.3 Inhalt und Aufbau dieser Arbeit . . . . . . . . . . . . . . . . . . . 3
2 Kartographische Grundlagen 4
2.1 Kartenprojektionen . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Die Bibliothek pyproj . . . . . . . . . . . . . . . . . . . . . . . . 6
3 OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 9
3.1 Das OSM-Datenmodell . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 Die Import-Bibliothek imposm.parser . . . . . . . . . . . . . . . . 11
3.3 Datenstrukturen des MoSP-GeoTools . . . . . . . . . . . . . . . . 13
3.3.1 Die Klasse OSM_objects . . . . . . . . . . . . . . . . . . . 13
3.3.2 Die Klasse Node . . . . . . . . . . . . . . . . . . . . . . . 16
3.3.3 Die Klasse Way . . . . . . . . . . . . . . . . . . . . . . . . 17
4 Die gra�sche Benutzerober�äche des MoSP-GeoTools 19
5 Allgemeine geometrische Methoden und Kartendarstellung 22
5.1 Das Modul geo.geo_utils . . . . . . . . . . . . . . . . . . . . . . 22
5.2 Kartendarstellung und Zoom . . . . . . . . . . . . . . . . . . . . . 28
6 Generalisierung 33
6.1 Der Douglas-Peucker-Algorithmus . . . . . . . . . . . . . . . . . . 33
6.2 Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
ii
Inhaltsverzeichnis iii
7 Partitionen 40
7.1 Identifikation von Partitionen . . . . . . . . . . . . . . . . . . . . . 40
7.2 Zusammenführen von Partitionen . . . . . . . . . . . . . . . . . . . 42
8 Points of Interest 47
8.1 POI-Auswahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
8.2 Algorithmen zur Verbindung von POI mit dem Straßennetz . . . . . 48
9 Fazit 55
Literaturverzeichnis 60
Abbildungsverzeichnis
2.1 Zylinderlage bei der Mercator-Projektion . . . . . . . . . . . . . . 5
2.2 Schematische Darstellung der transversalen UTM-Schnittzylinder-
projektion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Darstellung des UTM-Zonensystems . . . . . . . . . . . . . . . . . 7
3.1 Darstellung der OSM-Daten in JOSM . . . . . . . . . . . . . . . . 12
4.1 Geöffnete Karte im Anwendungsfenter des MoSP-GeoTools . . . . 19
4.2 Auswahl der Generalisierung . . . . . . . . . . . . . . . . . . . . . 20
4.3 Markierung und Zusammenführung von Partitionen . . . . . . . . . 20
4.4 Auswahl von POI und Verbindung mit dem Straßennetz . . . . . . . 21
5.1 Generierung einer Node-Box . . . . . . . . . . . . . . . . . . . . . 23
5.2 Rückgabewerte der Methode distance_point_to_line . . . . . . . 24
5.3 Abstandsberechnung zwischen Node und Straße . . . . . . . . . . . 25
5.4 Funktionsweise connect_by_projection . . . . . . . . . . . . . . 27
5.5 Punkt-in-Polygon-Test . . . . . . . . . . . . . . . . . . . . . . . . 28
5.6 Bestimmung der Pixel-Koordinaten innerhalb einer OSM-Kachel . . 30
5.7 Bestimmung der Pixel-Größe einer Bounding Box . . . . . . . . . . 31
5.8 Bestimmung einer vollständig mit OSM-Kacheln gefüllten Darstellung 32
6.1 Douglas-Peucker-Algorithmus (rekursiv) . . . . . . . . . . . . . . . 35
6.2 Abstandsberechnung im Douglas-Peucker-Algorithmus . . . . . . . 35
6.3 Douglas-Peucker-Algorithmus (iterativ) . . . . . . . . . . . . . . . 37
6.4 Generalisierung im MoSP-GeoTool . . . . . . . . . . . . . . . . . 38
7.1 Partitionierung durch Straßenfilterung . . . . . . . . . . . . . . . . 42
7.2 Funktionsweise der Methode get_adjacent_streets . . . . . . . . 44
7.3 Auswirkung der Minimum Node Distance . . . . . . . . . . . . . . 45
7.4 Gegenüberstellung connect_by_node und connect_by_projection 46
iv
ABKÜRZUNGSVERZEICHNIS v
8.1 Verbindung eines POI über Gebäudeeingang und Gebäudeadresse
mit dem Straßennetz . . . . . . . . . . . . . . . . . . . . . . . . . 52
9.1 Anzahl der Straßenknoten in Abhängigkeit vom Toleranzwert der Li-
niengeneralisierung . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.2 Ausschnitt des Straßennetzes von Chicago . . . . . . . . . . . . . . 58
9.3 Unveränderte und generalisierte Straßenverläufe . . . . . . . . . . . 59
Abkürzungsverzeichnis
DCSec Distributed Computing & Security Group
EPSG European Petroleum Survey Group Geodesy
JOSM Java-OpenStreetMap-Editor
MoSP Mobile Security & Privacy
OSM OpenStreetMap
POI Point of Interest
UTM Universal Transverse Mercator
WGS World Geodetic System
XML Extensible Markup Language
vi
1 Einleitung
1.1 Motivation dieser Arbeit
In der Distributed Computing & Security Group (DCSec) der Leibniz Universität
Hannover wird der Mobile Security & Privacy Simulator (MoSP-Simulator) ent-
wickelt. Mit diesem Simulator werden Bedrohungen der IT-Sicherheit und der Nut-
zerprivatsphäre moderner mobiler Endgeräte simuliert und mögliche Maßnahmen
zum Schutz gegen diese Bedrohungen geprüft und bewertet. Der MoSP-Simulator
benutzt für seine Simulationen Kartenmaterial des OpenStreetMap-Projekts (OSM)1.
Der Simulator stellt gewisse Anforderungen an die Kartendaten, um mit diesen Da-
ten arbeiten zu können. Im Rahmen dieser Arbeit wird daher ein Werkzeug – das
Mobile Security & Privacy GeoTool (MoSP-GeoTool) – entwickelt, das die OSM-
Kartendaten so aufbereitet, dass diese Daten für den MoSP-Simulator verwendbar
sind.
Ein limitierender Faktor ist die Anzahl der Knoten des Straßennetzes. Der Simula-
tor erstellt vor Beginn einer Simulation aus dem OSM-Straßennetz eine Routing-
Tabelle, damit das Routing während der Simulation in konstanter Zeitkomplexi-
tät erfolgen kann. Die Tabelle wächst quadratisch mit der Anzahl der Knoten. Da
die Routing-Tabelle während der Simulation im Speicher vorgehalten wird, ist bei
großen Karten die Speicherkapazität erschöpft. Eine Aufgabe des im Rahmen die-
ser Arbeit entwickelten MoSP-GeoTools ist, eine Datenreduktion der OSM-Daten
durchzuführen, um die Anzahl der Straßenknoten zu minimieren. Gleichzeitig muss
die Charakteristik der Straßenzüge möglichst erhalten bleiben, um eine wirklich-
keitsgetreue Simulation zu ermöglichen.
Auf Grund ungenauer und nicht immer koordinierter Datenerfassung bei der Erstel-
lung des Kartenmaterials durch die OSM-Community können Straßennetze zu Teil-
graphen zerfallen oder einzelne Straßen nicht mit dem restlichen Straßennetz verbun-
den sein. Da somit auch im Datenmodell des Simulators keine Verbindung zwischen1http://www.openstreetmap.org/
1
1. Einleitung 2
diesen Partitionen besteht, können Personen, die sich in der Simulation auf dem Stra-
ßennetz bewegen, Teile des Netzes nicht erreichen. Durch eine Eliminierung von
Straßen, auf denen sich Personen nicht bewegen können, z. B. Autobahnen, können
ebenfalls Partitionen entstehen. Eine Patitionserkennung in einer laufenden Simula-
tion wäre zu komplex. Für das MoSP-GeoTool werden daher Methoden entwickelt
und implementiert, um Partitionen zu erkennen und intelligent zu einem einzigen
Straßennetz zusammenzufügen. Für die Simulationen muss ein einzelner, vollständi-
ger Graph vorliegen.
In den Simulationen des MoSP-Simulators sollen Personen, die sich auf dem Stra-
ßennetz bewegen, bestimmte Points of Interest (POI) ansteuern. Diese besonderen
Punkte sind im Regelfall nicht mit dem Straßennetz verbunden, so dass auch keine
Routinginformationen zu diesen Punkten im Datenmodell des Simulators enthalten
sind und somit für die Personen nicht erreichbar sind. Ein Einfügen von Verknüpfun-
gen der POI mit dem Straßennetz während einer laufenden Simulation wäre wieder
unnötig komplex. Eine weitere Aufgabe des MoSP-GeoTools ist es, auch die Points
of Interest intelligent mit dem bestehenden Straßennetz zu verbinden.
1.2 Mobile Security & Privacy Simulator
Möchte man Bedrohungen und Schutzmaßnahmen im Kontext der IT-Sicherheit und
Nutzerprivatsphäre moderner mobiler Endgeräte untersuchen, steht man vor der Her-
ausforderung, geeignete Analysemöglichkeiten zu entwickeln. Abstrakte Modelle
können nicht alle möglichen Szenarien der Realität erfassen und erlauben somit
auch keine umfassende Analyse. Gegen Feldstudien sprechen hohe Kosten und der
notwendige Eingriff in die Privatsphäre der möglichen Studienteilnehmer. Daher
wird der Mobile Security & Privacy Simulator entwickelt, um Bedrohungen der IT-
Sicherheit und der Nutzerprivatsphäre moderner mobiler Endgeräte zu simulieren.
Des Weiteren prüft und bewertet der Simulator mögliche Maßnahmen zum Schutz
gegen diese Bedrohungen. Der MoSP-Simulator simuliert die Bewegungsmuster von
Personen in einem Straßennetz. Die Personen bewegen sich zufällig oder steuern be-
stimmte Ziele an. Personen können miteinander interagieren, sei es durch direkten
Kontakt oder Kommunikation [HSS11].
1. Einleitung 3
1.3 Inhalt und Aufbau dieser Arbeit
In Kapitel 2 erfolgt eine kurze Einführung in die kartographischen Grundlagen, die
zum Verständnis dieser Arbeit benötigt werden. Des Weiteren wird die Bibliothek er-
läutert, mit deren Hilfe im Rahmen des MoSP-GeoTools kartographische Berechnun-
gen durchgeführt werden. In Kapitel 3 wird das Datenmodell des OpenStreetMap-
Projekts vorgestellt. Anschließend wird der Import eines OSM-Datensatzes und Über-
führung der Daten in das Datenmodell des MoSP-GeoTools beschrieben. In Kapitel 4
erfolgt eine Einführung in die graphische Benutzeroberfläche des MoSP-GeoTools.
In Kapitel 5 erfolgt eine Beschreibung der grundlegenden Methoden, die im Rahmen
dieser Arbeit entwickelt wurden und auf die die Applikationen des MoSP-GeoTools
zur Durchführung ihrer Aufgaben zugreifen. Außerdem wird die Darstellung der
OSM-Kartendaten im Anwendungsfensters des MoSP-GeoTools beschrieben. In Ka-
pitel 6 wird der verwendete Algorithmus zur Datenreduktion vorgestellt und dessen
Implementierung erläutert. In Kapitel 7 werden die Methoden erklärt, die im Rahmen
dieser Arbeit entwickelt wurden, um partitionierte Straßennetze zu identifizieren und
zusammenzuführen. In Kapitel 8 werden die Methoden vorgestellt, um Points of In-
terest auszuwählen und diese mit dem Straßennetz zu verbinden. In Kapitel 9 erfolgt
eine Zusammenfassung der Ergebnisse dieser Arbeit.
2 Kartographische Grundlagen
Im Rahmen dieser Arbeit werden Methoden verwendet, um die reale Welt auf der
gekrümmten Erdoberfläche auf einem flachen Medium wie einem Computerbild-
schirm abzubilden. Zum besseren Verständnis wird an dieser Stelle zunächst ein
grober Überblick über kartographische Projektionssysteme gegeben. Im Anschluss
daran wird die Bibliothek vorgestellt, mit deren Methoden die in dieser Arbeit not-
wendigen kartographischen Berechnungen durchgeführt werden.
2.1 Kartenprojektionen
Wenn die gekrümmte Erdoberfläche in einer ebenen Karte dargestellt werden soll,
kann dies nur mit Verzerrungen geschehen. Aus den Elementen Länge, Fläche und
Winkel kann dabei ein Element getreu abgebildet werden, während die übrigen Ele-
mente verzerrt dargestellt werden [HGM02, S. 56]. Bei Flächentreue werden Flä-
cheninhalte korrekt wiedergegeben, während Abstände und Winkel verzerrt abgebil-
det werden. Ein Kreis auf der Kugeloberfläche wird als flächengleiche Ellipse in der
Kartenprojektion wiedergegeben. Bei Längentreue werden Längen unverzerrt über-
tragen, während Flächen und Winkel verzerrt dargestellt werden. Längentreue kann
dabei aber nur in eine Richtung realisiert werden. Ein Kreis auf der Kugeloberfläche
wird in der Kartenprojektion als Ellipse abgebildet, bei der eine Halbachse dem Ra-
dius des Kreises entspricht, während die andere Halbachse gestreckt oder gestaucht
wird. Bei Winkeltreue, die auch Konformität genannt wird, werden Winkel korrekt
wiedergegeben, während Längen und Flächen verzerrt dargestellt werden. Ein be-
stimmter Winkel auf der Kugeloberfläche wird in der Kartenprojektion mit demsel-
ben Wert abgebildet. Ein Kreis auf der Kugeloberfläche wird auch in der Kartenpro-
jektion als Kreis mit größerem oder kleinerem Radius wiedergegeben. Für Karten
zur Navigation werden winkeltreue Abbildungen bevorzugt [HGM02, S. 57].
Eine Projektionsart, die eine konforme Abbildung erzeugt, ist die Mercator-Projektion
[HGM02, S. 72], von der es zahlreiche Abwandlungen gibt. In der klassischen Mercator-
4
2. Kartographische Grundlagen 5
Projektion wird ein Zylinder um das Erdmodell gelegt, dessen Achse mit der Erdach-
se zusammenfällt, und der am Äquator die Erdoberfläche berührt (siehe Abbildung 2.1).
Die Karten des OpenStreetMap-Projekts basieren auf EPSG:3857, das ebenfalls ein
sphärisches Mercator-Projektionssystem ist [Opea]. Die Bezeichnung leitet sich von
der Schlüsselnummer des Codesystems der European Petroleum Survey Group Geo-
desy (EPSG) ab. Als Erdmodell wird bei diesem Projektionssystem nicht eine Ku-
gel verwendet, sondern ein Ellipsoid, das durch das World Geodetic System 1984
(WGS84) definiert wird [EPS] [HGM02, S. 41].
Abbildung 2.1: Zylinderlage bei der Mercator-Projektion (aus [HGM02, S. 56])
Da bei der Darstellung der Karten im MoSP-GeoTool die OSM-Kartendarstellung
als Hintergrundgrafik eingeblendet werden kann, verwendet das MoSP-GeoTool für
die Visualisierung der Karten ebenfalls die EPSG:3857-Projektion.
Die im Rahmen dieser Arbeit implementierte Methode __distance_point_to_line
aus dem Modul geo.geo_utils arbeitet mit Vektorrechnung in einem kartesischen
Koordinatensystem (siehe Kapitel 5.1). Die Koordinaten aus der EPSG:3857-Projektion
können nicht für die Berechnungen dieser Methode herangezogen werden, da diese
Projektion nur längs des Äquators längentreu ist und sich daher für den größten Teil
der Erdoberfläche sehr starke Verzerrungen ergäben.
Für die Berechnungen der Methode __distance_point_to_line wird daher eine an-
dere Projektionsart gewählt, die Universal Transversal Mercator Projection (UTM-
Projection). Das UTM-System ist heute das Standardsystem für Landvermessung
und Geodatenbanken. Auch diese Projektionsart benutzt das WGS84-Ellipsoid als
Erdmodell [HGM02, S. 77]. Projektionsfläche ist ein transversaler Schnittzylinder,
das heißt die Zylinderachse ist gegenüber der Erdachse um 90◦ gedreht und der Zy-
linder durchschneidet die Erdoberfläche (siehe Abbildung 2.2).
2. Kartographische Grundlagen 6
Abbildung 2.2: Schematische Darstellung der transversalen UTM-Schnittzylinderprojektion (aus [Lan09])
Der Meridian in der Mitte zwischen den beiden Schnittkreisen wird Mittelmeridi-
an genannt. Das UTM-System teilt die Erdoberfläche in 60 Zonen mit 3◦, 9◦, 15◦
usw. östlicher bzw. westlicher Länge als Mittelmeridiane. Die Zonen dehnen sich
links und rechts des Mittelmeridians um jeweils 3◦ aus. An den Schnittkreisen, die
ca. 180 km links und rechts des Mittelmeridians liegen, wird Längentreue erreicht.
Der Mittelmeridian ist um den Faktor 0,9996 gestaucht, die Verzerrung der Randbe-
reiche beträgt 1,00015 [HGM02, S. 77]. Somit wird innerhalb einer UTM-Zone ein
großer Grad an Längentreue erreicht. Diese Genauigkeit reicht aus, um die Berech-
nungen der Methode __distance_point_to_line mit UTM-Koordinaten durchfüh-
ren zu können. Die Zonen werden beim Mittelmeridian 177◦ westlicher Länge be-
ginnend von West nach Ost durchnummeriert. Deutschland liegt zum großen Teil in
UTM-Zone 32 mit 9◦ östlicher Länge als Mittelmeridian (siehe Abbildung 2.3).
2.2 Die Bibliothek pyproj
Für Berechnungen mit geographischen Koordinaten bzw. zur Umrechnung der geo-
graphischen Koordinaten in die projizierten Koordinaten der EPSG:3857-Projektion
und der UTM-Projektion wird die Python-Bibliothek pyproj verwendet 1.
Die Klasse Proj der Bibliothek dient zur Konvertierung von geographischen Ko-
ordinaten, angegeben in Längengrad lon und Breitengrad lat, in die x- und y-
Koordinaten von Kartenprojektionen. Im Falle der EPSG:3857-Projektion bzw. der
UTM-Projektion wird die Klasse mit folgenden Konstruktoren aufgerufen:
1http://code.google.com/p/pyproj/
2. Kartographische Grundlagen 7
Abbildung 2.3: Darstellung des UTM-Zonensystems (aus [HGM02, S. 78])
UTM-Projektion:
utm_projection = Proj(proj=’utm’, zone=utm_zone, ellps=’WGS84’)
EPSG:3857-Projektion:
epsg3857_projection = Proj(init=’epsg:3857’)
Der Konstruktor für die UTM-Projektion erhält als Übergabeparameter die Projek-
tionsart, den Referenzellipsoid und die UTM-Zone, die während des Einlesens der
OSM-Kartendaten ermittelt wird (siehe Kapitel 3).
Der Konstruktor für die EPSG:3857-Projektion erhält als Übergabeparameter die
Projektionsart.
Der Aufruf einer Proj-Instanz mit geographischen Koordinaten als Parameter lon
und lat konvertiert die Koordinaten in die entsprechende Projektion:
utm_x, utm_y = utm_projection(lon, lat)
epsg3857_x, epsg3857_y = epsg3857_projection(lon, lat)
Die Klasse Geod der Bibliothek pyproj dient zu Abstands- und Winkelberechnungen
mit geographischen Koordinaten. Im Konstruktor der Klasse wird dieser das Refe-
renzellipsoid übergeben:
geod = Geod(ellps=’WGS84’)
2. Kartographische Grundlagen 8
Der bei den folgenden Berechnungen verwendete Azimut ist der im Uhrzeigersinn
gemessene Winkel zwischen dem geographischen Nordpol und der Richtung einer
Strecke auf der Erdoberfläche. Ein Azimut 0◦ ist also geographisch-Nord, 90◦, 180◦
und 270◦ dementsprechend Ost, Süd und West. Der Back-Azimut ist der dem Azimut
entgegengesetzte Winkel.
Für die Algorithmen des MoSP-GeoTools sind zwei Methoden der Klasse Geod rele-
vant. Die Methode fwd(lon1, lat1, azimut, distance) berechnet zu einem Punkt
mit den Koordinaten lon1 und lat1 einen zweiten Punkt, der im Winkel azimut (in
Grad) die Strecke distance (in Meter) entfernt liegt. Der Rückgabewert ist ein Tripel
aus den Koordinaten des zweiten Punktes und aus dem Back-Azimut:
lon2, lat2, back_azimut = geod.fwd(lon1, lat1, azimut, distance)
Die Methode inv(lon1, lat1, lon2, lon2) berechnet zu zwei Punkten den Win-
kel in Grad und Abstand in Metern der beiden Punkte zueinander:
azimut, back_azimut, distance = geod.inv(lon1, lat1, lon2, lon2)
Die Methode pyproj.Geod.inv(lon1, lat1, lon2, lat2) arbeitet fehlerhaft. Wenn
zwei Punkte sehr dicht beieinander liegen, ohne dass sie dieselben Koordinaten ha-
ben, löst die Methode eine ValueError-Exception aus2. Daher wird im Rahmen dieser
Arbeit im Modul geo.geo_utils (siehe Kapitel 5) die Methode distance_points(point1,
point2) implementiert. Diese Methode übernimmt das Exception-Handling für die
fehlerhafte Methode aus der pyproj-Bibliothek. Wenn eine ValueError-Exception
ausgelöst wird, dann wird für die beiden Azimut-Winkel und die Distanz das Tripel
(0.0, 0.0, 0.0) zurückgegeben, ansonsten die durch die Methode pyproj.Geod.inv
berechneten Werte.
2http://code.google.com/p/pyproj/issues/detail?id=18
3 OpenStreetMap: Datenimport und-verwaltung im MoSP-GeoTool
Der Mobile Security & Privacy Simulator und damit auch das MoSP-GeoTool be-
nutzen als Datengrundlage Kartenmaterial des OpenStreetMap-Projekts. In diesem
Kapitel wird zunächst das Datenmodell von OpenStreetMap erläutert. Anschließend
wird auf den Import der OSM-Daten eingegangen. Schließlich wird die Datenhaltung
innerhalb des MoSP-GeoTools erklärt.
3.1 Das OSM-Datenmodell
OpenStreetMap benutzt für Kartenobjekte drei grundlegende Datentypen: Nodes,
Ways und Relations [Opec]. Für das MoSP-GeoTool liegen die OpenStreetMap-
Kartendaten in Form einer XML-Datei vor. Das folgende Listing zeigt beispielhaft
eine solche XML-Datei.
1 <xml version=’1.0’ encoding=’UTF-8’>2 <osm version=’0.6’ generator=’MoSP-GeoTool’>3 <bounds minlat="52.3811037" minlon="9.7189859" maxlat="52.3819458" maxlon="9.7216229"/>4 <node id=’100001’ lat=’52.3817433’ lon=’9.7200323’ visible=’true’ version=’1’ />5 <node id=’100002’ lat=’52.3818804’ lon=’9.7193151’ visible=’true’ version=’1’ />6 [...]7 <node id=’100011’ lat=’52.3815497’ lon=’9.7204914’ visible=’true’ version=’1’ />8 <node id=’100012’ lat=’52.3815799’ lon=’9.7200153’ visible=’true’ version=’1’>9 <tag k=’building’ v=’entrance’ />10 </node>11 <node id=’100013’ lat=’52.3815913’ lon=’9.719842’ visible=’true’ version=’1’ />12 <node id=’100014’ lat=’52.3811487’ lon=’9.719766’ visible=’true’ version=’1’ />13 <node id=’100015’ lat=’52.3811037’ lon=’9.7204693’ visible=’true’ version=’1’ />14 <node id=’100016’ lat=’52.3813523’ lon=’9.7202111’ visible=’true’ version=’1’>15 <tag k=’amenity’ v=’library’ />16 <tag k=’name’ v=’Technische Informationsbibliothek’ />17 </node>18 <way id=’100017’ visible=’true’ version=’1’>19 <nd ref=’100003’ />20 <nd ref=’100002’ />21 <nd ref=’100001’ />22 <nd ref=’100006’ />23 <tag k=’highway’ v=’footway’ />24 <tag k=’addr:street’ v=’Welfengarten’ />
9
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 10
25 </way>26 <way id=’100018’ visible=’true’ version=’1’>27 <nd ref=’100006’ />28 <nd ref=’100005’ />29 <nd ref=’100004’ />30 <tag k=’highway’ v=’service’ />31 </way>32 <way id=’100019’ visible=’true’ version=’1’>33 <nd ref=’100015’ />34 <nd ref=’100014’ />35 [...]36 <nd ref=’100007’ />37 <nd ref=’100015’ />38 <tag k=’building’ v=’yes’ />39 </way>40 </osm>
Jedes Element der drei grundlegenden Datentypen wird durch ein Attribut id eindeu-
tig identifiziert. Die vergebenen IDs sind dabei über alle Typen hinweg eindeutig.
Die im Listing angegebenen Attribute visible und version sind für die Anwen-
dungen des MoSP-GeoTools ohne Bedeutung, bleiben aber beim Export der Daten
erhalten. Diese Attribute werden z. B. vom Java-OpenStreetMap-Editor (JOSM)1 be-
nötigt. Mit JOSM können OSM-Daten bearbeitet und wieder auf den OSM-Server
geladen werden. Über version erfolgt eine Versionsnummerierung der Änderungen,
mit visible wird die Sichtbarkeit eines OSM-Objekts bestimmt. Kartendaten, die
mit JOSM exportiert werden, enthalten zudem negative IDs, die als Platzhalter die-
nen, um nicht in Konflikt mit bestehenden Objekten der OSM-Datenbank zu gera-
ten [Opeb].
Nodes sind als Punkte die kleinsten Einheiten einer OSM-Karte. Über die Attribute
lat und lon werden die geographischen Koordinaten eines Nodes spezifiziert (z. B.
Zeile 4).
Durch die Verbindung einzelner Nodes erhält man den Datentyp Way. Ein Way re-
ferenziert über die eindeutigen IDs die Nodes, aus denen er aufgebaut ist (z. B. Zei-
le 18 bis 25). Flächen werden nicht durch einen eigenen Datentyp beschrieben, son-
dern durch einen Way, dessen Anfangs- und Endpunkt identisch sind (z. B. Zeile 32
bis 39). Alle Kartenobjekte, die sich durch Linienzüge oder Polygone darstellen las-
sen, werden durch diesen Datentyp beschrieben. Dazu gehören zum Beispiel Straßen,
Flüsse, Hochspannungsleitungen, Gebäude und auch Parks.
OSM-Objekte können durch Relations in Beziehung zueinander gesetzt werden. So
lassen sich zum Beispiel Innenhöfe von Gebäuden darstellen oder Straßenbahnstrecken
1http://josm.openstreetmap.de
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 11
zu einem Liniennetz verknüpfen. Relationen spielen in den Anwendungen des MoSP-
GeoTools keine Rolle und werden daher hier nicht weiter betrachtet.
Alle Objekte können durch Tags näher charakterisiert werden. So wird der Node mit
der ID 100012 im obigen Listing als Eingang eines Gebäudes deklariert (Zeile 9).
Des Weiteren können zum Beispiel Straßen kategorisiert werden. Im Beispiel wird
der Way mit der ID 100017 als Straße vom Typ Fußweg definiert (Zeile 23). Au-
ßerdem erhält der Way einen Straßennamen (Zeile 24). Der geschlossene Way mit
der ID 100019 wird durch ein Tag als Gebäude charakterisiert (Zeile 38). Die mög-
lichen Key-Value-Paare sind nicht standardisiert. Die Interpretation der Tags bleibt
dem verarbeitenden Werkzeug überlassen. Allerdings haben sich viele Tags über das
OSM-Wiki zu Quasistandards entwickelt.
Am Beginn der XML-Datei kann optional eine Bounding Box angegeben werden
(Zeile 3). Je nach Datenquelle oder OSM-Editor werden unterschiedliche Formate
verwendet:
<bounds minlat=’52.3811037’ minlon=’9.7189859’ maxlat=’52.3819458’ maxlon=’9.7216229’/>
<bound box=’52.3811037, 9.7189859, 52.3819458, 9.7216229’/>
Die OSM-API und JOSM benutzen das bounds-Element. Osmosis2, eine Java-Kom-
mandozeilen-Applikation zur Verarbeitung von OSM-Daten, benutzt das bound-Element.
Das MoSP-GeoTool kann beide Deklarationen einer Bounding Box interpretieren.
Wenn im MoSP-GeoTool Kartendaten exportiert werden, dann soll eine vorgegebe-
ne Bounding Box erhalten bleiben oder eine Bounding Box erzeugt werden, wenn
in den Kartendaten keine enthalten war. Bei einem Datenexport durch das MoSP-
GeoTool wird die Bounding Box als bounds-Element gespeichert.
Die Darstellung des obigen Beispiels einer OSM-Datei in JOSM ist in Abbildung 3.1
gezeigt. Der Bereich außerhalb der Bounding Box wird als schraffierte Fläche dar-
gestellt.
3.2 Die Import-Bibliothek imposm.parser
Zum Import der OSM-Daten in das MoSP-GeoTool ist ein XML-Parser notwendig.
Die auf den Import von OSM-Daten optimierte Python-Bibliothek imposm.parser3
2http://wiki.openstreetmap.org/wiki/Osmosis3http://dev.omniscale.net/imposm.parser/
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 12
Abbildung 3.1: Darstellung der OSM-Daten in JOSM
zeichnet sich durch eine einfache Bedienung und Schnelligkeit durch Multiprozes-
sorbetrieb aus und wird daher im MoSP-GeoTool für den Import der OSM-Daten
verwendet.
Bei Erzeugung einer Instanz des Parsers werden diesem für jeden OSM-Objekttyp
eine Callback-Funktion als Parameter übergeben. Beim Parsen der OSM-Datei wer-
den für jeden OSM-Objekttyp Listen angelegt, die als Listenelemente die relevanten
Daten für je ein Objekt enthalten. Diese Listen werden als Parameter an die jeweilige
Callback-Funktion übergeben. Die Liste für einen Objekttyp wird nicht vollständig,
sondern abschnittsweise erzeugt. Durch den Multiprozessorbetrieb baut jeder Pro-
zessor eine Teilliste auf. Des Weiteren wird eine Teilliste an die Callback-Funktion
übergeben, sobald die Liste eine vorgegebene Größe erreicht hat. Die Liste wird da-
nach zurückgesetzt und bei Bedarf wieder gefüllt.
Die Bibliothek importiert die wichtigen zu einer Beschreibung der OSM-Objekte
notwendigen Daten wie ID, Koordinaten, Tags und Referenzen. Im Rahmen die-
ser Arbeit wird die Bibliothek so erweitert, dass auch ignorierte Attribute importiert
werden, damit die Daten vollständig erhalten bleiben. Im Folgenden ist die Struktur
der Listenelemente, wie sie von der Bibliothek, an die Callback-Funktionen überge-
ben werden, dargestellt. In der erweiterten Version der Bibliothek sind am Ende des
Listeneintrags die zusätzlichen Attribute enthalten.
• Nodes
(osm_id, tags, (lon, lat), attr)
• Ways
(osm_id, tags, refs, attr)
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 13
• Relations
(osm_id, tags, members, attr)
Dabei sind tags bzw. attr Dictionaries aus den Key/Value-Paaren der Tags bzw. der
Attribute:
tags = {tag_key1:tag_value1, tag_key2:tag_value2, ...}
attr = {attr_name1:attr_val1, attr_name2:attr_val2, ...}
refs ist eine Liste der IDs der referenzierten Nodes:
refs = [ref_id1, ref_id2, ...]
members ist eine Liste aus 3-Tupeln der Elemente ID des referenzierten Objekts, Typ
des Objekts (node, way oder relation), Rolle des Objekts:
members = [(refID1, type1, role1), (refID2, type2, role2), ...]
Des Weiteren ist in der imposm.parser-Bibliothek kein Import einer eventuell vor-
handenen Bounding Box einer OSM-Karte vorgesehen. Da diese Bounding Box er-
halten bleiben soll, wird die Bibliothek im Rahmen dieser Arbeit so erweitert, dass
ein bounds- bzw. bound-Element am Anfang der OSM-Datei erkannt und importiert
wird.
Die angepasste Bibliothek wird als imposm2.parser direkt in das MoSP-GeoTool-
Paket eingebunden.
3.3 Datenstrukturen des MoSP-GeoTools
Das Modul geo.osm_import repräsentiert die zentrale Datenverwaltung des MoSP-
GeoTools. Die Klassen dieses Moduls nehmen die geparsten OSM-Objektdaten ent-
gegen, erzeugen daraus korrespondierende Python-Objekte und stellen Methoden
zum Auslesen und Ändern der Objekteigenschaften zur Verfügung. Im Folgenden
werden die drei Klassen OSM_objects, Node und Way dieses Moduls näher erläutert.
3.3.1 Die Klasse OSM_objects
Die Klasse OSM_objects initiiert das Parsen einer OSM-Datei, nimmt das Parsing-
Ergebnis entgegen, generiert hieraus die entsprechenden Objekte und legt die er-
zeugten Objekte in Datenstrukturen ab. Der Konstruktor der Klasse hat die Signa-
tur OSM_objects(infile). Dabei steht infile für den Dateipfad der zu öffnenden
OSM-Datei.
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 14
Der Import der OSM-Daten erfolgt in zwei Phasen. In der ersten Phase werden
die vom Parser übergebenen Objekt-Listen (siehe Abschnitt 3.2) eingelesen. Die
Methoden __receive_<type>(object_list) (mit <type> = bounds, nodes, ways
oder relations) werden vom OSM-Parser als Callback-Funktionen mit den Objekt-
Listen als Parameter aufgerufen. Die Listeneinträge für Bounds, Nodes und Ways
werden unverändert den Objektvariablen __imported_bounds, __nodes bzw. __ways
hinzugefügt. OSM-Karten werden meist durch Extraktion eines durch eine Boun-
ding Box bestimmten Bereichs aus größeren Kartenobjekten gewonnen. Straßen an
den Grenzen dieses Bereichs werden dabei in der Regel nicht abgeschnitten, son-
dern werden entsprechend ihren referenzierenden Knoten über diesen Bereich hinaus
fortgeführt. Somit kann es vorkommen, dass sich die in der OSM-Datei angegebe-
ne Bounding Box und die tatsächliche Größe der Karte unterscheiden können. Da-
her wird beim Einlesen der Nodes schrittweise die maximale Ausdehnung der Karte
bestimmt. Hierzu werden in der Callback-Funktion __receive_nodes die Koordina-
ten der eingelesenen Nodes mit den bisher ermittelten Extremwerten verglichen und
diese bei Bedarf angepasst. Relationen werden in der Objektvariable __relations
als Dictionary in der Form {rel_id1:relation1,rel_id2:relation2,...} gespei-
chert (mit relationX = Listeneintrag in der übergebenen Relation-Liste).
In der zweiten Phase des Datenimports werden aus den importierten Rohdaten die
korrespondierenden Python-Objekte erzeugt. Dabei wird zunächst die Methode __create_bounds()
aufgerufen. Die während des Einlesens der Nodes ermittelte maximale Ausdehnung
der Karte wird in der Objektvariable __calculated_bounds gespeichert. Wenn die
OSM-Datei der eingelesenen Karte kein Bounds-Element aufweist, so wird die be-
rechnete Bounding Box auch für die importierte Bounding Box übernommen. Für
Operationen innerhalb des MoSP-GeoTools wird immer die berechnete Bounding
Box verwendet. Wenn eine Karte abgespeichert wird, wird die importierte Boun-
ding Box verwendet. Somit bleibt bei einem Export das Bounds-Element erhalten,
wenn eine importierte Karte dieses Element enthält. Wenn eine importierte Karte
kein Bounds-Element enthält, wird dieses beim Export hinzugefügt. Anhand der lin-
ken Seite der berechneten Bounding Box wird die UTM-Zone der Karte ermittelt
und das korrespondierende pyproj.Proj-Objekt erzeugt, das in der Objektvariable
__utm_projection gespeichert wird (siehe Kapitel 2).
Anschließend wird mit der Methode __create_nodes() für jeden Listeneintrag in
__nodes ein Node-Objekt erzeugt. Die weiteren Methoden des MoSP-GeoTools sind
so angelegt, dass entweder über die OSM-ID gezielt auf ein Node-Objekt zugegrif-
fen wird oder dass über alle Node-Objekte iteriert wird. Für eine optimale Suche
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 15
nach einer ID bietet sich ein ausbalancierter binärer Suchbaum an. Ein AVL-Baum
ist ein Vertreter dieser Baumart und wird für die Speicherung der Node-Objekte
wird verwendet. Für diese Baumstruktur existiert eine einfache, nur auf Standard-
Python-Bibliotheken zurückgreifende Implementierung4. Die OSM-ID eines Nodes
wird als Key, das Node-Objekt als Item eines Baumeintrags gespeichert. Das AVL-
Baum-Objekt wird in der Objektvariable __node_avl gespeichert. Über die Metho-
de AVLTree.get(id) lässt sich auf das Objekt mit der gewünschten ID zugreifen,
die Methode AVLTree.value() liefert einen Iterator über die gespeicherten Node-
Objekte.
Als letzter Teil der zweiten Import-Phase wird mit der Methode __create_ways()
für jeden Listeneintrag in __ways ein Way-Objekt erzeugt. Auch hier werden die
Way-Objekte für einen schnellen Zugriff über die OSM-ID in einem AVL-Baum ge-
speichert (Objektvariable __way_avl). In den weiteren Methoden des MoSP-GeoTools
ist es wichtig, effizient auf Way-Objekte einer lokalen Umgebung zugreifen zu kön-
nen. Es wird also eine räumliche Datenstruktur benötigt. Eine gängige Datenstruktur,
um zweidimensionale Objekte zu speichern, ist ein R-Baum [Gut84]. Die verwendete
Python-Implementierung5 speichert Kopien der eingefügten Objekte und keine Re-
ferenzen auf die Objekte. Da dieses Verhalten für die Implementierung innerhalb des
MoSP-GeoTools ungeeignet ist, wird der R-Baum nur verwendet, um einer OSM-ID
eine räumliche Lage und Ausdehnung zuzuordnen. Der Zugriff auf das Way-Objekt
selbst erfolgt über den AVL-Baum.
Da Ways viele unterschiedliche Objekte der realen Welt repräsentieren können, wer-
den Way-Objekte bei der Generierung vorsortiert und in getrennten Datenstrukturen
abgespeichert. Straßen, gekennzeichnet durch ein Tag mit dem Key highway, werden
in einem R-Baum gespeichert (Objektvariable __street_tree). Gebäude, gekenn-
zeichnet durch Tags mit Key = ’building’ und Value = ’yes’, werden in einem
weiteren R-Baum gespeichert (__building_tree). Die übrigen Way-Objekte spielen
im MoSP-GeoTool keine Rolle. Um beim Export wieder auf diese Objekte zugrei-
fen zu können, werden die OSM-IDs in einer Liste gespeichert (__other_ways). Mit
Beendigung der Methode __cretate_ways() ist der Import der OSM-Daten abge-
schlossen.
Weitere wichtige Objektvariablen, die nicht während des Imports, sondern durch spä-
tere Manipulationen mit Daten gefüllt werden, sind __poi und __generalized. In
__poi wird eine Menge der Nodes gespeichert, die als Point of Interest markiert wer-
4http://pypi.python.org/pypi/bintrees/5http://pypi.python.org/pypi/Rtree/
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 16
den (siehe Kapitel 8). In __generalized werden die Toleranzen der durchgeführten
Generalisierungen gespeichert werden (siehe Kapitel 6).
Die Klasse OSM_objects stellt Methoden zur Bearbeitung der gespeicherten Da-
ten zur Verfügung. Die Methoden insert_new_node(lat, lon, tags, attr) und
append_new_street(tags, nodes, attr) erzeugen mit vorgegebenen Parametern
neue Node- und Way-Objekte und fügen diese in die entsprechenden Datenstruktu-
ren ein. Über die Methode find_new_key() wird für diese Objekte eine neue OSM-
ID generiert. Dem Vorgehen des Java-OpenStreetMap-Editors folgend erhalten neue
Objekte eine negative ID, entweder -1, wenn noch kein Objekt mit einer negativen
ID existiert, oder eine gegenüber der kleinsten ID um 1 verminderte ID, wenn bereits
negative IDs existieren. Dadurch ist gewährleistet, dass die neuen IDs nicht in Kon-
flikt mit den IDs bestehender Objekte aus der OSM-Datenbank stehen. Die Methode
get_adjacent_streets(node, threshold) gibt zu einem vorgegebenen Node eine
Liste von Straßen zurück, die sich in der Umgebung des Nodes befinden, die durch
den Parameter threshold (Angabe in Meter) spezifiziert wird.
3.3.2 Die Klasse Node
In der Klasse Node werden alle notwendigen Eigenschaften eines OSM-Node-Objekts
gespeichert. Der Konstruktor der Klasse hat die Signatur Node(id, lon, lat, tags,
attr, osm_object). Dabei sind id die OSM-ID des Node-Objekts, lon und lat die
geographischen Koordinaten des Nodes, tags und attr die als Dictionary gespei-
cherten Key/Value-Paare der Tags bzw. Attribute und osm_object eine Referenz auf
die zugrunde liegende Objekt-Instanz der OSM_objects-Klasse.
Neben den Objektvariablen, die bei der Initialisierung eines Node-Objekts mit den
übergebenen Parametern belegt werden, enthält die Klasse weitere Objektvariablen.
In der Objektvariablen __neighbours wird bei der Initialisierung von Straßen eine
Liste mit Referenzen auf die Node-Objekte gespeichert, mit denen eine direkte Stra-
ßenverbindung besteht. In __partition_id wird die ID der Partition gespeichert, zu
der der Node gehört (siehe Kapitel 7). In __poi wird gespeichert, ob das Node-Objekt
als Point of Interest markiert ist (siehe Kapitel 8).
Als Methoden stellt die Klasse Getter und Setter für die Objektvariablen zur Verfü-
gung. Die Methode get_xy() gibt den x- und y-Wert der Koordinaten in EPSG:3857-
Projektion als Tupel zurück, die Methode get_xy_utm() die entsprechenden Koor-
dinaten in UTM-Projektion.
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 17
3.3.3 Die Klasse Way
In der Klasse Way werden alle notwendigen Eigenschaften eines OSM-Way-Objekts
gespeichert. Der Konstruktor der Klasse hat die Schnittstelle Way(id, nodes, tags,
attr, node_avl). Dabei sind id die OSM-ID des Way-Objekts, nodes eine Liste
der Node-IDs, aus deren dazugehörigen Node-Objekten das Way-Objekt aufgebaut
ist, tags und attr die als Dictionary gespeicherten Key/Value-Paare der Tags bzw.
Attribute und node_avl eine Referenz auf die Instanz des AVL-Baums, in dem zu
den Node-IDs die dazugehörigen Node-Objekte gespeichert sind.
Während der Initialisierung eines Way-Objekts wird anhand der geographischen Ko-
ordinaten der referenzierten Node-Objekte eine Bounding Box für das Way-Objekt
generiert. Diese Bounding Box wird als Parameter beim Einfügen des Way-Objekts
in einen R-Baum benötigt. Bei Suchanfragen an den R-Baum erfolgt über diese
Bounding Box die geographische Lokalisierung des Way-Objekts. Wenn es sich bei
dem Way-Objekt um eine Straße handelt, werden bei der Initialisierung die Nachbar-
schaftslisten der beteiligten Node-Objekte aufgebaut. Zwei direkt aufeinander fol-
gende Nodes werden sich gegenseitig als Nachbarn zugewiesen. Da bei den weiteren
Methoden des MoSP-GeoTools häufig über alle Node-Objekte einer Straße iteriert
werden muss, wird bei der Initialisierung auch eine Liste mit Referenzen auf die
Node-Objekte erzeugt, damit der Zwischenschritt, das Node-Objekt anhand seiner
ID aus dem AVL-Baum zu holen, bei zukünftigen Zugriffen entfallen kann.
In der Objektvariable __partition_id wird die ID der Partition gespeichert, zu der
eine Straße gehört (siehe Kapitel 7). In der Objektvariable __generalized werden
die Ergebnisse von Generalisierungen als Dictionary mit dem Toleranzwert der Ge-
neralisierung als Key und einer Liste der Node-Objekte des generalisierten Straßen-
zugs als Value gespeichert (siehe Kapitel 6).
Neben Gettern und Settern für Objektvariablen stellt die Klasse Way zwei weite-
re wichtige Methoden zur Verfügung. Die Methode insert_node(segment_start,
segment_end, node) fügt ein Node-Objekt in ein bestehendes Liniensegment ein.
segment_start und segment_end kennzeichnet die Node-Objekte von Anfangs- und
Endpunkt des Segments, node das einzufügende Node-Objekt. Die Methode fügt
das Node-Objekt an der richtigen Stelle in die Datenstrukturen ein und aktualisiert
die Nachbarschaftslisten der beteiligten Nodes. Es obliegt der aufrufenden Metho-
de, die Node-Objekte für Start- und Endpunkt des Segments korrekt zu bestim-
men. Die Methode insert_node überprüft, ob die Nodes tatsächlich benachbart sind.
Mit der Methode apply_generalization(tolerance) wird die Generalisierung, die
3. OpenStreetMap: Datenimport und -verwaltung im MoSP-GeoTool 18
dem als Parameter übergebenen Toleranzwert entspricht, zum neuen Basis-Datensatz
gemacht. Dabei werden die Objektvariablen __nodes und __node_objects mit den
Node-Listen des entsprechenden Toleranzwertes überschrieben und die Variable __generalized
geleert. Außerdem werden die Nachbarschaftsbeziehungen der Nodes, die nach einer
Generalisierung nicht mehr Bestandteil einer Straße sind, gelöscht.
4 Die grafische Benutzeroberflächedes MoSP-GeoTools
Über das grafische User Interface (GUI) steuert der Anwender alle Funktionen des
MoSP-GeoTools, die in den folgenden Kapiteln besprochen werden.
Nach dem Öffnen einer Karte wird diese zunächst vollständig im Anwendungsfenster
angezeigt. Der Benutzer kann sich durch Zoomen und Verschieben des Ausschnitts
an die für ihn interessanten Bereiche der Karte anzeigen lassen. In Abbildung 4.1 ist
eine Karte mit dem gesamten Straßennetz der Stadt Hannover zu sehen, wie sie sich
dem Benutzer des MoSP-GeoTools nach dem Öffnen der Karte darstellt.
Abbildung 4.1: Geö�nete Karte im Anwendungsfenter des MoSP-GeoTools
Eine Funktion des MoSP-GeoTools ist die so genannte Liniengeneralisierung von
Straßen (siehe Kapitel 6). Durch Datenreduktion werden Straßenverläufe verein-
facht. Über das GUI wählt der Benutzer den Generalisierungsgrad durch Vorgabe
eines Toleranzwertes aus. Um die Realitätsnähe der vereinfachten Straßenverläufe
beurteilen zu können, lassen sich die OSM-Kacheln als Hintergrundgrafik einblen-
den. Ausgehend vom Datensatz der ursprünglichen Karte lassen sich mehrere Gene-
raliserungen mit unterschiedlichen Toleranzwerten durchführen. Der Benutzer kann
über das GUI zwischen den Generalisierungen wechseln und so sich die für seine Be-
dürfnisse optimale Karte auswählen. In der in Abbildung 4.2 dargestellten Situation
19
4. Die grafische Benutzeroberfläche des MoSP-GeoTools 20
stehen drei bereits durchgeführte Generalisierungen zur Auswahl. Die Generalisie-
rung mit dem Toleranzwert 10 Meter wird aktuell im Anwendungsfenster angezeigt.
Abbildung 4.2: Auswahl der Generalisierung
Eine weitere Aufgabe des MoSP-GeoTools ist die Anzeige und Zusammenführung
von Partitionen (siehe Kapitel 7). Nach Auswahl der Anzeige von Partitionen werden
Partitionen farbig hervorgehoben. Das zusammenhängende Hauptstraßennetz behält
seinen schwarzen Grundton. Der Benutzer gibt über die Benutzeroberfläche Para-
meter vor, die das Verhalten der Zusammenführung von Partitionen bestimmen und
startet die Methode. Bei einer erfolgreichen Verbindung sind die Partitionen nach
Ausführung der Funktion Bestandteil des Hauptstraßennetzes (siehe Abbildung 4.3).
Abbildung 4.3: Markierung und Zusammenführung von Partitionen
4. Die grafische Benutzeroberfläche des MoSP-GeoTools 21
Als weitere Funktion bietet das MoSP-GeoTool an, Points of Interest (POI) auszu-
wählen, die dann mit dem Straßennetz verbunden werden können (siehe Kapitel 8).
Durch Eingabe eines Key/Value-Paares von OSM-Tags startet der Benutzer über das
GUI die POI-Auswahl. Punkte, die dem gesuchten Kriterium entsprechen, werden
als blaue Punkte in der Karte markiert. In der Karte aus Abbildung 4.4 werden Re-
staurants ausgewählt. Durch Angabe verschiedener Parameter durch den Anwender
wird die Verbindung der ausgewählten POI mit dem Straßennetz gestartet. Bei einer
erfolgreichen Verbindung mit dem Straßennetz erscheinen die POI als grüner Punkt.
Die Mensa Contine auf dem Conti-Campus der Leibniz Universität Hannover wird
dabei über die Eingänge des Gebäudes, in dem sich die Mensa befindet mit dem
umliegenden Straßennetz verbunden. Bei ungünstig gewählten Parametern kann die
Verbindung scheitern. Betroffene POI werden rot markiert. Der Benutzer des MoSP-
GeoTools kann sich dann entscheiden, ob er die Funktion erneut mit angepassten
Parametern aufruft.
Abbildung 4.4: Auswahl von Points of Interest und deren Verbindung mit demStraÿennetz
5 Allgemeine geometrischeMethoden und Kartendarstellung
Alle Applikationen, die im Rahmen dieser Arbeit entwickelt werden, benötigen Ope-
rationen, die die OSM-Datenobjekte einer lokalen Umgebung auswählen und nach
bestimmten Kriterien filtern. Dieses Kapitel beschäftigt sich zunächst mit den Funk-
tionen des Moduls geo.geo_utils, welches Methoden für geometrische Operatio-
nen, die die Applikationen des MoSP-GeoTools benötigen, bereitstellt. Anschlie-
ßend wird erläutert, welche Methoden entwickelt wurden, um aus den geographi-
schen Koordinaten der Bounding Box einer OSM-Karte die Zuordnung zu den Pixel-
Koordinaten des Anwendungsfensters zu erhalten.
5.1 Das Modul geo.geo_utils
Geometrische Operationen, die nicht spezifisch für eine bestimmte Klasse sind, wer-
den von dem Modul geo.geo_utils bereitgestellt. Für Abstands- und Winkelberech-
nungen greifen die Methoden dieses Moduls auf die Methoden der Geod-Klasse aus
der pyproj-Bibliothek zurück (siehe Kapitel 2). Die Funktionsweisen der wichtig-
sten Methoden des geo_utils-Moduls werden im Folgenden erläutert. Die konkrete
Verwendung der Methoden wird bei den aufrufenden Methoden in den jeweiligen
Kapiteln genauer beschreiben.
Die Methode create_node_box(node, distance)
In den Anwendungen des MoSP-GeoTools zur Partitionszusammenführung und zur
Verbindung von Points of Interest wird ausgehend von einem vorgegebenen Node ein
rechteckiger Suchbereich (Box) um diesen Node benötigt. Diese Box wird als Such-
gebiet an die R-Bäume, in denen die Straßen- und Gebäudeobjekte gespeichert sind,
um so die Objekte der direkten Umgebung zu finden. Die Methode create_node_box
erzeugt eine solche Box. Ausgehend von dem Node, der als Parameter der Methode
22
5. Allgemeine geometrische Methoden und Kartendarstellung 23
übergeben wird, werden mit der Methode pyproj.Geod.fwd(lon, lat, azimuth,
distance) vier Punkte bestimmt, die jeweils den als Parameter übergebenen Ab-
stand von dem Node haben und von diesem aus gesehen in Nord-Richtung (Azimuth-
Winkel 0◦), Ost-Richtung (90◦), Süd-Richtung (180◦) und West-Richtung (270◦) lie-
gen (siehe Abbildung 5.1). Längengrad des West-Punktes und Breitengrad des Süd-
Punktes ergeben die geographischen Koordinaten der linken, unteren Ecke der Box,
Längengrad des Ost-Punktes und Breitengrad des Nord-Punktes geben die Koordi-
naten der rechten, oberen Ecke der Box.
distance
0°
90°
180°
270°
Abbildung 5.1: Generierung einer Node-Box
Die Methode __distance_point_to_line(line_start, line_end,point)
Die Methode __distance_point_to_line bestimmt den Abstand zwischen einem
Punkt und einem Liniensegment, das von einem Start- und einem Endpunkt aufge-
spannt wird. Dabei ist der Abstand entweder die Distanz zwischen dem Punkt und
dem Lotfußpunkt der Projektion des Punktes auf das Liniensegment, wenn der Lot-
fußpunkt auf dem Segment liegt, oder die Distanz zwischen dem Punkt und dem
Start- bzw. Endpunkt, wenn der Lotfußpunkt auf der Interpolation des Linienseg-
ments liegt. Auf welche Weise der Abstand bestimmt wird, wird im Abstandsmodus
mode gespeichert. Im Fall der Projektion ist der Modus eine dreielementige Liste aus
den Node-Objekten des Start- und Endpunktes, sowie des Abstands in Metern zwi-
schen Startpunkt und Lotfußpunkt (siehe Abbildung 5.2 a). Im anderen Fall ist der
Modus eine einelementige Liste aus dem Node-Objekt des Start- bzw. Endpunkts
des Segments (siehe Abbildung 5.2 b bzw. c). Der Rückgabewert der Methode ist
ein Tupel aus Abstand in Metern und Abstandsmodus. Der Abstandsmodus wird von
den Methoden benötigt, die eine Verbindung eines Knoten zum Straßennetz herstel-
len wollen. Anhand des Abstandsmodus entscheiden die aufrufenden Methoden, auf
welche Weise und an welcher Stelle ein Punkt mit einer Straße verbunden werden
kann. Hat der Abstandsmodus die Länge eins, besteht also nur aus einem Node-
5. Allgemeine geometrische Methoden und Kartendarstellung 24
Objekt, kann eine Verbindung nur zu einem der beiden Endpunkte des Linienseg-
ments erfolgen. Der im Abstandsmodus gespeicherte Node gibt an, an welchem der
beiden Endpunkte die Verbindung erfolgen kann. Hat der Abstandsmodus die Länge
drei, so kann eine Verbindung durch Projektion erfolgen. Der Wert für projection
gibt an, an welcher Stelle des Liniensegments ein neuer Knoten eingefügt werden
muss.
start
end
point
distance
projection
mode = [start, end, projection]
start
end
point
distance mode = [start]
start
end
point
distance
mode = [end]
a)
b)
c)
Abbildung 5.2: Zusammensetzung der Rückgabewerte der Methodedistance_point_to_line
Der im MoSP-GeoTool implementierte Algorithmus zur Bestimmung des Abstands
ist eine Adaption der Implementierungen gemäß [3DS] und [map]. Zur Erklärung
der einzelnen Schritte des Algorithmus sei dorthin verwiesen.
Die Methode __distance_point_to_line ist eine private Methode. Der Aufruf er-
folgt über die öffentlichen Methoden distance_mode_point_line(line_start, line_end,
point), die ein Tupel aus Abstand in Metern und Abstandsmodus als Rückgabewert
hat, oder distance_point_line(line_start, line_end, point), die den Abstand
in Metern zurückgibt. Die erste Methode wird von den Algorithmen zur Verbindung
von Points of Interest (Kapitel 8) mit dem Straßennetz oder zur Zusammenführung
von Partitionen (Kapitel 7) verwendet. Die zweite Methode wird zur Abstandbestim-
mung im Douglas-Peucker-Algorithmus verwendet (Kapitel 6).
5. Allgemeine geometrische Methoden und Kartendarstellung 25
Die Methode distance_node_street(node, street)
Eine Straße besteht aus mehreren Segmenten jeweils zweier benachbarten Nodes.
Zur Bestimmung des Abstandes zwischen einem Node und einer Straße wird mit der
Methode distance_mode_point_line der Abstand zwischen dem Node und jedem
Segment bestimmt. Der geringste dabei ermittelte Abstand ist der Abstand des Nodes
zur Straße (siehe Abbildung 5.3). Dieser Abstand sowie der Abstandsmodus werden
als Tupel zurückgegeben.
s1
s2
s3d1 = min_distance
d2 d3
Abbildung 5.3: Abstandsberechnung zwischen Node und Straÿe
Auf der Methode distance_node_street aufbauend bestimmt die Methode get_nearest_street(node,
streets) zu einem Node die nächstgelegene Straße. Als Parameter erhält die Me-
thode einen Node und eine Liste von Straßenobjekten, die durch die aufrufenden
Methoden bereits auf die Straßen der näheren Umgebung des Nodes reduziert ist.
Es wird über die Straßen-Liste iteriert und zu jeder Straße dieser Liste Abstand und
Abstandsmodus zu dem Node bestimmt. Der Rückgabewert enthält als 3-Tupel die
nächstgelegene Straße, den Abstand des Nodes zu dieser Straße und den Abstands-
modus.
Auf ähnliche Weise bestimmt die Methode get_nearest_street_node(node, streets)
aus einer Liste von Straßen den zu einem gegebenen Node nächstgelegenen Node ei-
ner Straße und den Abstand. Dazu wird zusätzlich über alle Straßenknoten der über-
gebenen Straßen iteriert.
Die Methode connect_by_node(osm_object, node, street_node)
Über die Methode connect_by_node werden zwei Nodes direkt miteinander durch
eine Straße verbunden. Die Methode bekommt als Parameter eine Instanz des OSM-
Datenmodells und die beiden zu verbindenden Nodes übergeben. Der zweite Node
der Parameterliste ist der Node, der bereits Bestandteil einer Straße ist. Die Me-
thode erzeugt ein neues Objekt der Klasse Way. Durch ein OSM-Tag wird das neu
erzeugte als Fußweg deklariert, durch Attribute wird es als „sichtbar“ gekennzeich-
net. Durch Aufruf der Methode append_new_street(tags, nodes, attr) aus der
5. Allgemeine geometrische Methoden und Kartendarstellung 26
Klasse geo.osm_import.OSM_objects wird die neue Straße erzeugt und dem Daten-
modell hinzugefügt. Um die neu erzeugte Straße und den verbundenen Node einer
Partition zuzuordnen, werden deren Partition-IDs auf die Partition-ID des Straßen-
nodes gesetzt.
Die Methode connect_by_projection(osm_object, node, street,mode)
Über die Methode connect_by_projection wird ein Node mit einer Straße verbun-
den, indem das Lot des Nodes auf die Straße gefällt wird und am Lotfußpunkt ein
neuer Node in die Straße eingefügt wird, über den die Verbindung des zu verbinden-
den Nodes mit der Straße erfolgt. Als Parameter erhält die Methode eine Instanz des
OSM-Datenmodells, den Node und die Straße, die zu verbinden sind, sowie den be-
reits vorher bestimmten Abstandsmodus. Der Abstandsmodus enthält als Liste den
Anfangs- und Endpunkt des Straßensegments, mit dem die Verbindung erfolgen soll,
sowie den Abstand zwischen Anfangspunkt des Segments und Lotfußpunkt der Pro-
jektion (Abbildung 5.4 a). Über die Methode pyproj.Geod.inv(lon1, lat1, lon2,
lat2) wird der Azimut-Winkel zwischen Start- und Endpunkt und damit der Verlauf
des Straßensegments im Koordinatensystem bestimmt (Abbildung 5.4 b). Mit der
Methode pyproj.Geod.fwd(lon, lat, azimuth, distance) werden die geogra-
phischen Koordinaten des Lotfußpunkts berechnet (Abbildung 5.4 c). Es wird durch
die Methode insert_new_node(lat, lon, tags, attr) aus der Klasse geo.osm_
import.OSM_objects ein neues Node-Objekt mit den Koordinaten des Fußpunkts er-
zeugt und in das Datenmodell eingefügt. Durch Aufruf der Methode insert_node(start_node,
end_node, new_node) aus der Klasse geo.osm_import.Way wird der neu erzeug-
te Node in die Straße eingefügt. Zuletzt werden noch der übergebene und der neu
erzeugte Node über die Methode connect_by_node miteinander verbunden (Abbil-
dung 5.4 d). Bei der gegenwärtig realisierten Implementierung überprüfen die auf-
rufenden Methoden, ob eine Verbindung über eine Projektion möglich ist. Da dies
in späteren Weiterentwicklungen nicht mehr der Fall sein muss, erfolgt zu Beginn
der Methode eine erneute Überprüfung anhand der Länge des Abstandsmodus. Wie
weiter oben bei der Erklärung der Methode __distance_point_to_line erläutert,
ist bei einer Länge von 3 eine Projektion möglich, bei einer Länge von 1 erfolgt eine
Verbindung über den Aufruf der Methode connect_by_node.
5. Allgemeine geometrische Methoden und Kartendarstellung 27
start
end
(start, end, projection_length) = mode
projection_length
azimuth, az_b, dist = inv(start.lon, start.lat, end.lat, end.lon)
start
end
node
node
new_lon, new_lat, az_b = fwd(start.lon, start.lat, azimuth, projection_length
start
end
azimuth
projection_length
node
start
end
node
new_node
a)
c)
b)
d)
Abbildung 5.4: Funktionsweise der Methode connect_by_projection
Die Methode is_inside_polygon(node, way)
Der Test, ob ein Punkt innerhalb oder außerhalb eines gegebenen Polygons liegt,
erfolgt mit der even-odd-Regel (Abbildung 5.5). Vom Punkt ausgehend wird eine
horizontale Linie nach rechts gezogen und geprüft, wie oft diese Linie die Begren-
zungslinie des Polygons schneidet. Bei einer ungeraden Anzahl an Schnitten liegt der
Punkt innerhalb des Polygons, bei einer geraden Anzahl außerhalb [Bar05, S. 104].
Der verwendete Algorithmus (nach [Bou87]) überprüft die Lagebeziehung des Punk-
tes zu den einzelnen Segmenten des Polygons. Dabei sind zwei Sonderfälle zu beach-
ten. Zum einen kann die gezogenen Linie durch einen Knoten des Polygons gehen
5. Allgemeine geometrische Methoden und Kartendarstellung 28
2. Fall
1. Fall
3. Fall
4. Fall
5. Fall
s1
s2 s4
s3
Abbildung 5.5: Punkt-in-Polygon-Test
(2. Fall in Abbildung 5.5). Hier muss gewährleistet sein, dass der Schnitt nicht dop-
pelt gezählt wird. Zum anderen kann die Linie mit einer Begrenzungslinie des Poly-
gons zusammenfallen (3. Fall in Abbildung 5.5). Hier muss gewährleistet sein, dass
der Schnitt entweder doppelt oder gar nicht gezählt wird. Die Implementierung des
Algorithmus beachtet diese Sonderfälle und zählt im Fall 2 einen einzelnen Schnitt
mit Segment s4 und in Fall 3 Schnitte mit den Segmenten s1 und s2. Die übrigen dar-
gestellten Fälle sind unproblematisch. Der Strahl in Fall 1 erzeugt einen Schnitt, der
Punkt liegt innerhalb des Polygons. In Fall 4 werden zwei Schnitte erzeugt, der Punkt
liegt außerhalb. In Fall 5 wird kein Schnitt erzeugt, der Punkt liegt ebenfalls außer-
halb des Polygons. Der Algorithmus kann nicht entscheiden, ob ein Punkt direkt auf
einer Begrenzungslinie des Polygons liegt. Da dieser Fall auch als „ist enthalten“
angesehen werden soll, erfolgt zunächst eine Bestimmung des Abstands vom Punkt
zum Polygon. Ist dieser Abstand gleich 0, so gibt die Funktion True zurück.
5.2 Kartendarstellung und Zoom
Für eine Darstellung einer OSM-Karte innerhalb der graphischen Oberfläche des
MoSP-GeoTools müssen die geographischen Koordinaten der Karte in Pixel-Koordi-
naten innerhalb des Anwendungsfensters umgerechnet werden. In diesem Abschnitt
werden die Methoden beschrieben, die im Rahmen dieser Arbeit für diese Aufgabe
entwickelt wurden.
Die Klasse ZoomObject
Für eine Überprüfung der Ergebnisse der Applikationen des MoSP-GeoTools kön-
nen in der Kartendarstellung des MoSP-GeoTools die Kartenkacheln (Tiles der Slip-
py Map von OpenStreetMap [Oped] als Hintergrundgrafik eingeblendet werden. Die
5. Allgemeine geometrische Methoden und Kartendarstellung 29
OSM-Tiles stehen entsprechend den Zoom-Levels von OpenStreetMap in 18 ver-
schiedenen Maßstäben zur Verfügung. Dementsprechend muss auch die Kartendar-
stellung des MoSP-GeoTools in einem dieser Zoom-Level erfolgen. Die Klasse ZoomObject
stellt Methoden zur Verfügung, um eine Karte im MoSP-GeoTool in OSM-Zoom-
Level darstellen zu können. Die Signatur des Konstruktors der Klasse ist ZoomObject(size),
wobei size ein Tupel aus Fensterbreite und Fensterhöhe des Anwendungsfenster in
Pixeln ist. Bei der Initialisierung der Klasse werden die Objektvariablen __window_width
und __window_height auf die entsprechenden Werte gesetzt. Die Objektvariable
__zoom_level wird auf den Wert 18 gesetzt, den größten verfügbaren OSM-Zoom-
Level. Weitere Objektvariablen werden durch die Methoden der Klasse gesetzt.
Einige Methoden der Klasse ZoomObject bedienen sich der Methoden tileXY bzw.
tileEdges aus dem Modul tilenames 1. Die Methode tileXY(lat, lon, z) lie-
fert zu gegebenen geographischen Koordinaten lat und lon sowie zu einem gege-
benen Zoom-Level z die dazugehörige OSM-Kachel. Die Kachel wird in Form des
x- und y-Werts der Kachelnummerierung gemäß dem Nummerierungsschema für
OSM-Kacheln angegeben [Oped]. Die Methode tileEdges(x, y, z) ergibt zu einer
gegebenen OSM-Kachel, definiert durch Kachelnummerierung x, y und Zoom-Level
z, die geographischen Koordinaten der Kanten der OSM-Kachel. Der Rückgabewert
ist ein 4-Tupel der Form „(Breitengrad untere Kante, Längengrad linke Kante, Brei-
tengrad obere Kante, Längengrad rechte Kante)“.
Im Folgenden werden zuerst die Methoden der Klasse ZoomObject erklärt. Danach
wird erläutert, wie mit Hilfe dieser Methoden der Zoom-Level einer Karte bestimmt
wird.
Die Methode get_tile_coordinates(lat, lon) berechnet mit Hilfe der Metho-
den tileXY und tileEdges zu gegebenen Koordinaten und zum Zoom-Level, der
in der Objektvariable __zoom_level gespeichert ist, die Kantenkoordinaten der da-
zugehörigen OSM-Kachel. Mit Hilfe der Kantenkoordinaten bestimmt die Metho-
de get_position_in_tile(lat, lon) die Pixel-Koordinaten der vorgegebenen Ko-
ordinaten innerhalb der Kachel. Dazu wird näherungsweise angenommen, dass die
geographischen Koordinaten innerhalb der Grenzen der Kachel linear verlaufen. Die
Pixel-Koordinaten lassen sich dann mit Hilfe des Strahlensatzes bestimmen (siehe
Abbildung 5.6 und Gleichung 5.1). Da das Ergebnis dieser Methode nur für eine
ungefähre Größeneinschätzung, nicht aber für genaue Koordinatenberechnungen be-
nötigt wird, kann diese Näherung ohne Probleme verwendet werden.
1http://svn.openstreetmap.org/applications/routing/pyroute/tilenames.py
5. Allgemeine geometrische Methoden und Kartendarstellung 30
x
y
west east
north
south
(lat, lon)
TILE_SIZE
TILE_SIZE
TILE_SIZE = 256(in Pixel)
south, west, north, east = get_tile_coordinates(lat, lon)
Abbildung 5.6: Bestimmung der Pixel-Koordinaten innerhalb einer OSM-Kachel
x
TILE_SIZE=
lon− west
east− west
y
TILE_SIZE=
lat− north
south− north
(5.1)
Die Methode get_box_tiles(box) liefert zu einer vorgegebenen Bounding Box die
Kachelnummerierungen der OSM-Tiles, die zur linken, oberen und rechten, unteren
Ecke der Bounding Box gehören.
Mit Hilfe der Methoden get_box_tiles und get_position_in_tile kann die Größe
einer Bounding Box in Pixeln bestimmt werden. Dies erfolgt durch die Methode
box_size_in_pixels(box). Zunächst werden mit der Methode get_box_tiles die
Kachelnummerierungen der Bounding Box bestimmt. Aus der Nummerierung lässt
sich ableiten, wie viele Kacheln in x-Richtung (d_tiles_x = 3 in Abbildung 5.7)
bzw. y-Richtung (d_tiles_y = 2 in Abbildung 5.7) von der Bounding Box berührt
werden. Durch die Methode get_position_in_tile wird der Abstand in Pixeln der
Bounding Box von den Rändern der äußeren Kacheln errechnet.x1, y1 = get_position_in_tile(north, west)x2, y2 = get_position_in_tile(south, east)
Mit den berechneten Werten lässt sich die gesamte Ausdehnung der Bounding Box
in Pixeln ermitteln.d_x = d_tiles_x * TILE_SIZE - x1 - (TILE_SIZE - x2)d_y = d_tiles_y * TILE_SIZE - y1 - (TILE_SIZE - y2)
5. Allgemeine geometrische Methoden und Kartendarstellung 31
Der Rückgabewert der Methode ist ein Tupel aus den berechneten Pixel-Werten in
x-Richtung d_x und in y-Richtung d_y.
Abbildung 5.7 zeigt die relevanten Werte für die Methode box_size_in_pixels. Die
graue Fläche stellt die Bounding Box dar, das Gitternetz die von der Bounding Box
berührten OSM-Kacheln.
x1
y1
west
east
north
south
TILE_SIZE
TILE_SIZE
x2
y2
TILE_SIZE
TILE_SIZE
d_tiles_x
d_tiles_y
d_x
d_y
Abbildung 5.7: Bestimmung der Pixel-Gröÿe einer Bounding Box
Auf diese Weise kann bei einem gegebenen Zoom-Level die Pixel-Größe einer Boun-
ding Box bestimmt werden. Wenn eine Karte im MoSP-GeoTool geöffnet wird, soll
diese zunächst so dargestellt werden, dass die gesamte Karte im Anwendungsfen-
ster abgebildet wird. Mit der Methode find_zoom_level(box) wird der Zoom-Level
ermittelt, bei dem eine vorgegebene Bounding Box vollständig in das Anwendungs-
fenster passt. Dazu wird in einer while-Schleife der Zoom-Level ausgehend von
Zoom-Level 18 schrittweise verringert, bis die Methode box_size_in_pixels so-
wohl für den x-Wert als auch für den y-Wert kleinere Werte als die Pixel-Größen
des Anwendungsfenster liefert. Wenn der passende Zoom-Level gefunden wurde,
werden mit der Methode get_box_tiles die Kachelnummerierungen der Bounding
Box ermittelt und in der Objektvariablen __tiles_zoom_level gespeichert. Wenn zu
einer Karte die OSM-Kacheln eingeblendet werden sollen, wird diese Variable aus-
gelesen und so ermittelt, welche Kacheln darzustellen sind. Außerdem wird in den
5. Allgemeine geometrische Methoden und Kartendarstellung 32
Objektvariablen __d_tiles_x bzw. __d_tiles_y die Anzahl der Kacheln in x- bzw.
y-Richtung gespeichert.
Wenn der optimale Zoom-Level ermittelt wurde, muss noch überprüft werden, ob
die in der Objektvariablen __tiles_zoom_level gespeicherten OSM-Kacheln aus-
reichen, um das gesamte Anwendungsfenster auszufüllen. In Abbildung 5.8 ist bei-
spielhaft eine Situation dargestellt, in der dies nicht der Fall ist. Die Situation in der
Abbildung geht von einer Fenstergröße von 768 Pixel Breite und 512 Pixel Höhe aus.
Bei einer Kachelgröße von 256×256 Pixeln können so 3×2 Kacheln dargestellt wer-
den. Das dunkelgraue Rechteck repräsentiert die Bounding Box einer OSM-Karte.
Die Methode find_zoom_level liefert hier aber nur eine Ausdehnung von 3 × 1
Kacheln.__d_tiles_x
__d_tiles_y
(neu
)
__d_tiles_y
(alt
)
east
north
westsouth
Abbildung 5.8: Bestimmung einer vollständig mit OSM-Kacheln gefülltenDarstellung
Die Methode tile_box() überprüft die Ausdehnung der ermittelten Kacheln und
vergrößert die in den Objektvariablen __d_tiles_x bzw. __d_tiles_y gespeicherten
Werte soweit, dass das Anwendungsfenster vollständig mit Kacheln ausgefüllt wer-
den kann. In der Objektvariable __tiles_zoom_level wird die angepasste Kachel-
nummerierung gespeichert, in der Objektvariable __box_pixel wird die Größe der
Kachelausdehnung in Pixeln als Tupel gespeichert. Der Rückgabewert der Methode
ist eine Liste mit den geographischen Koordinaten der linken, unteren Ecke und der
rechten, oberen Ecke der Kacheln in der Form [west, south, east, north].
Mit dem Rückgabewert der Methode tile_box und durch Auslesen der Objektvaria-
ble __box_pixel erhält man eine eindeutige Zuordnung der geographischen Koordi-
naten der Bounding Box einer Karte zu den Pixel-Koordinaten des Anwendungsfen-
sters. Somit kann nun eine Umrechnung der Koordinaten eines Kartenpunktes in die
Pixel-Koordinaten innerhalb des Anwendungsfensters erfolgen.
6 Generalisierung
Die verwendeten OSM-Straßendaten liegen in einem Detail-Grad vor, der vom MoSP-
Simulator nicht verarbeitet werden kann. Daher wird im MoSP-GeoTool eine Funk-
tion zur Verfügung gestellt, mit der die Anzahl der Straßenknoten auf ein opti-
males Minimum ohne großen Detailverlust reduziert werden kann. Diese Reduk-
tion der Kartendaten erfolgt durch eine so genannte Liniengeneralisierung. Einer
der bekanntesten Algorithmen zur Liniengeneralisierung ist der Douglas-Peucker-
Algorithmus [DP73].
In diesem Kapitel wird der Douglas-Peucker-Algorithmus zur Liniengeneralisierung
vorgestellt sowie die Implementierung im MoSP-GeoTool erläutert.
6.1 Der Douglas-Peucker-Algorithmus
Verfahren zur Liniengeneralisierung können wie folgt klassifiziert werden [Ins]:
• Lokal
• Sequentiell
• Interpolation
• Unbewertet
• Lageänderung der Stützpunkte
• Global
• Nicht sequentiell
• Approximation
• Bewertet
• Keine Lageänderung der Stütz-
punkte
Ein lokales Verfahren betrachtet nur die unmittelbare Umgebung eines Punktes, wäh-
rend ein globales Verfahren die gesamte Punktmenge betrachtet. Ein lokales Verfah-
ren kann meist auch sequentiell auf einem Datenstrom arbeiten. Für ein globales
Verfahren müssen von Anfang an alle Daten vorliegen, so dass hier ein sequentielles
Arbeiten nicht möglich ist. Bei interpolierenden Verfahren geht der generalisierte Li-
nienzug durch die berechnete Punktmenge. Bei approximierenden Verfahren wird die
33
6. Generalisierung 34
Punktmenge durch den Linienzug angenähert. Wenn das Ergebnis eines Verfahrens
von Eingabeparametern abhängt, so spricht man von einem bewertenden Verfahren.
Des weiteren kann sich je nach die Verfahren die Lage der neu berechneten Stütz-
punkte gegenüber den ursprünglichen Stützpunkten ändern oder erhalten bleiben.
Eine Straßenkreuzung wird im OSM-Datenmodell durch einen Node dargestellt,
der von mehreren Straßen referenziert wird. Bei einem Generalisierungsverfahren
mit verändernder Stützpunktlage kann der Kreuzungsnode nach der Generalisie-
rung der verschiedenen Straßen an unterschiedlichen Punkten zu liegen kommen.
Die Straßen wären nicht mehr verbunden. Um zu verhindern, dass im Original-
Kartenmaterial zusammenhängende Straßen nach einer Generalisierung nicht mehr
verbunden sind, muss daher ein Verfahren gewählt werden, das die Stützpunktla-
ge nicht verändert. Aus demselben Grund muss ein interpolierendes Verfahren ge-
wählt werden, da bei einem approximierenden Generalisierungsverfahrens nicht ge-
währleistet werden kann, dass die Topologie erhalten bleibt. Damit der Benutzer des
MoSP-GeoTools selbst das Ausmaß der Generalisierung bestimmen kann, bietet sich
zudem ein bewertendes Verfahren an.
Der Douglas-Peucker-Algorithmus zur Liniengeneralisierung ist ein globales, nicht
sequentielles, interpolierendes, bewertendes, die Stützpunktlage nicht veränderndes
Verfahren. Der Algorithmus erfüllt die oben genannten Kriterien und wird daher für
die Implementierung der Generalisierung im MoSP-GeoTool gewählt.
Der Douglas-Peucker-Algorithmus erhält als Eingabeparameter den zu generalisie-
renden Linienzug und einen Toleranzwert t. In Abbildung 6.1 ist der Ablauf des
Verfahrens schematisch dargestellt. Der Toleranzbereich wird dabei durch die roten
Linien markiert. Zunächst werden der Anfangs- und der Endpunkt des Linienzuges
verbunden. Anschließend wird der Punkt mit der größten Entfernung zur Verbin-
dungslinie gesucht (Abbildung 6.1 a). Liegt dieser Punkt außerhalb des gewählten
Toleranzbereichs, so wird dieser Punkt mit dem Anfangs- und Endpunkt verbun-
den und es wird der Algorithmus rekursiv auf die neu entstandenen Teilabschnitte
angewendet (Abbildung 6.1 b). Wenn es zu einer Verbindungslinie keinen Punkt au-
ßerhalb des Toleranzbereichs gibt, so werden Anfangs- und Endpunkt dieser Linie
zum neu berechneten Linienzug hinzugefügt. Dazwischenliegende Punkte werden
verworfen (Abbildung 6.1 c). Das Verfahren wird rekursiv solange wiederholt, bis
keine Punkte außerhalb des Toleranzbereichs gefunden werden (Abbildung 6.1 d).
6. Generalisierung 35
Abbildung 6.1: Der Douglas-Peucker-Algorithmus (rekursives Verfahren)
6.2 Implementierung
Douglas und Peucker betrachteten bei der Abstandsberechnung zwischen einem Punkt
und einem Liniensegment nur die Projektion des Punktes auf das Liniensegment
(Punkt p1 und Abstand s1 in Abbildung 6.2) bzw. die Projektion des Punktes auf die
Interpolation des Liniensegments (Punkt p2 und Abstand s2 in Abbildung 6.2), so
dass ein gegenüber dem Liniensegment weit verschobener Punkt genau so behandelt
wird wie ein Punkt, der direkt über dem Liniensegment liegt. Da dieses Verhalten
nicht zweckmäßig ist, wird bei Punkten, die über der Interpolation des Linienseg-
ments liegen, nicht der projizierte Abstand, sondern die Verbindung zwischen Punkt
und Ende des Liniensegments als Abstand genommen (Punkt p4 und Abstand s4 in
Abbildung 6.2) [Ebi02]. Bei Punkten, die über dem Liniensegment liegen, bleibt es
bei der ursprünglichen Abstandsbestimmung durch Projektion (Punkt p3 und Ab-
stand s3 in Abbildung 6.2).
p1 p2
s1 s2
p3 p4
s3 s4
Abbildung 6.2: Abstandsberechnung im Douglas-Peucker-Algorithmus (oben:original, unten: modi�ziert)
6. Generalisierung 36
Da rekursive Algorithmen in der Regel einen höheren Speicherbedarf haben als ver-
gleichbare iterative Algorithmen, wird im MoSP-GeoTool eine iterative Version des
Douglas-Peucker-Algorithmus implementiert [3DS] [map]. Die Methode douglas_
peucker(way_segment, tolerance) erhält als Eingabeparameter den zu generali-
sierenden Linienzug way_segment als Liste von Node-Objekten und einen Toleranz-
wert tolerance in Metern. In Abbildung 6.3 ist der Ablauf des iterativen Verfahrens
schematisch dargestellt. Start- und Endpunkt des gerade betrachteten Teilstücks wer-
den als Anchor bzw. Floater bezeichnet, der am weitesten von der Verbindungslinie
zwischen Anchor und Floater entfernte Punkt als Farthest. Abschnitte, die noch zu
betrachten sind, werden in einem Stack gespeichert. Abbildung 6.3 a zeigt die Aus-
gangslage zu Beginn des Verfahrens. Bei jedem Durchlauf des Algorithmus wird
zunächst zu einem gegebenen Anchor und Floater der Farthest gesucht. Liegt dieser
außerhalb des gewählten Toleranzbereichs, so wird der Farthest dem Stack hinzuge-
fügt und wird selbst zum neuen Anchor (Abbildung 6.3 b). Danach startet ein neuer
Durchlauf des Algorithmus. Wenn kein Farthest gefunden wird, der noch außerhalb
des Toleranzbereichs liegt, so wird die Strecke zwischen Anchor und Floater dem
generalisierten Linienzug hinzugefügt. Der aktuelle Floater ist immer auch oberstes
Element des Stacks. Der Floater wird zum neuen Anchor und wird gleichzeitig vom
Stack entfernt. Das neue oberste Element des Stacks wird zum neuen Floater (Ab-
bildung 6.3 c). Dieses Verfahren wird solange wiederholt, bis sich schließlich kein
Element mehr auf dem Stack befindet und der generalisierte Linienzug vollständig
aufgebaut ist (Abbildung 6.3 f).
Ein allgemeines Problem bei Generalisierungsoperationen ist es, Nachbarschaften
oder Verbindungen von Objekten auch nach der Generalisierung zu erhalten. Ein
Straßenzug, definiert über ein OSM-Way-Objekt, kann mit anderen Way-Objekten
Kreuzungen oder Abzweigungen bilden (siehe Abbildung 6.4 a). Wenn dieser Stra-
ßenzug als Ganzes generalisiert wird, so kann es passieren, dass die Kreuzungspunk-
te nicht mehr zum generalisierten Linienzug gehören (Abbildung 6.4 b). Um dies zu
verhindern, wird bei der Implementierung der Generalisierung im MoSP-GeoTool
der Straßenzug abschnittsweise bearbeitet. Jeder dieser Abschnitte wird einzeln ge-
neralisiert. Am Ende des Verfahrens werden alle Abschnitte zu einem neuen Straßen-
zug zusammengesetzt. Das Ende eines Abschnitts ist durch einen Kreuzungspunkt
gekennzeichnet. Kreuzungspunkte sind durch mindestens drei Nachbarn ausgezeich-
net (Abbildung 6.4 c, die Nodes sind mit ihrem Nachbarschaftsgrad gekennzeichnet).
Da bei einer Generalisierung mit dem Douglas-Peucker-Algorithmus Anfangs- und
Endpunkt eines Linienzuges erhalten bleiben, ist gewährleistet, dass die Lage von
6. Generalisierung 37
1
2
34
5 67
8
1
2
3
4
56
7
8
1
2
34
5 67
8
1
2
34
56
7
8
1
2
34
56
7
8
1
2
34
5 67
8
anchor = 1floater = 8farthest = 5stack = [8]new_way = [1]
anchor = 1floater = 5farthest = 3stack = [8,5]new_way = [1]
anchor = 5floater = 8farthest = 7stack = [8]new_way = [1,5]
anchor = 5floater = 7farthest = 6stack = [8,7]new_way = [1,5]
anchor = 7floater = 8farthest = 8stack = [8]new_way = [1,5,7]
anchor = 8floater = 8farthest = 8stack = []new_way = [1,5,7,8]
a)
b)
c)
d)
e)
f)
tolerance
Abbildung 6.3: Der Douglas-Peucker-Algorithmus (iteratives Verfahren)
Start- und Endpunkt einer Straße sowie die Lage aller Kreuzungspunkte erhalten
bleiben (Abbildung 6.4 d).
Nodes können als Point of Interest besonders markiert sein (siehe Kapitel 8). Da die-
se Nodes Bestandteil des Straßennetzes sein sollen, wäre es kontraproduktiv, diese
Nodes im Zuge einer Generalisierung aus einem Straßennetz zu entfernen. Daher
werden alle Nodes, die zwar nur einen Nachbarschaftsgrad von 2 haben, aber gleich-
zeitig als Point of Interest markiert sind, ebenfalls als Abschnittsgrenze betrachtet.
Die Zerlegung der Straßen in einzelne Abschnitte erfolgt durch die Methode generalize(osm_
object, tolerance), wobei der Übergabeparameter osm_object eine Referenz auf
das zugrunde liegende Datenobjekt ist und tolerance der Toleranzwert für die Li-
niengeneralisierung in Metern. Die Methode übergibt die einzelnen Segmente zur
Generalisierung an die Methode douglas_peucker und setzt die generalisierten Teil-
stücke zu einer gesamten Straße zusammen. Das Ergebnis wird in der Objektva-
riable __generalized des Datenobjekts als Dictionary mit dem Toleranzwert als
6. Generalisierung 38
a)
d)
c)
b)
n = 12 2
32
32
22 2
31
Abbildung 6.4: Abschnittsweise Generalisierung im MoSP-GeoTool
Key und einer Liste der Node-Objekte des generalisierten Straßenzugs als Value ge-
speichert. Bei der Durchführung des Douglas-Peucker-Algorithmus wird nicht di-
rekt der OSM-Datensatz manipuliert. In der Objektvariable __node_objects des
Datenobjekts bleiben die Node-Objekte, die den Straßenzug aufbauen, erhalten. Im
Dictionary __generalized wird die Generalisierung gespeichert. Mit der Methode
generalize können daher ausgehend vom ursprünglichen OSM-Datensatz mehrfach
Generalisierungen mit veränderten Toleranzwerten durchgeführt werden. Jedes wei-
tere Ergebnis wird entsprechend im Dictionary __generalized abgelegt. Das fol-
gende Listing zeigt beispielhaft eine mögliche Ausprägung nach drei ausgeführten
Generalisierungen.
__node_objects = [<Node1>, <Node2>, <Node3>, <Node4>, <Node5>, <Node6>]__generalized = { 5 : [<Node1>, <Node2>, <Node4>, <Node5>, <Node6>],
10 : [<Node1>, <Node4>, <Node6>],20 : [<Node1>, <Node6>]
}
Durch Aufruf der Methode apply_generalization(tolerance) aus der Klasse geo.
osm_import.OSM_objects wird die Generalisierung, die dem als Parameter überge-
6. Generalisierung 39
benen Toleranzwert entspricht, zum neuen Basis-Datensatz gemacht. Dabei werden
im Datenobjekt osm_object die Objektvariablen __nodes und __node_objects mit
den Node-Listen des entsprechenden Toleranzwertes überschrieben und die Objekt-
variable __generalized geleert. Außerdem werden die Nachbarschaftsbeziehungen
der Nodes, die nach einer Generalisierung nicht mehr Bestandteil einer Straße sind,
gelöscht. Die gewählte Generalisierung kann nun in einer OSM-Datei gespeichert
werden, die übrigen Generalisierungen gehen verloren.
7 Partitionen
Aufgrund von Ungenauigkeiten bei der Erfassung von Daten für das OpenStreetMap-
Projekt ist es möglich, dass einzelne Straßen oder ganze Straßennetze nicht voll-
ständig miteinander verbunden sind. Des Weiteren bietet das MoSP-GeoTool die
Möglichkeit, Straßen, die für Fußgänger irrelevant sind, zum Beispiel Autobahnen,
aus dem OSM-Datensatz zu löschen. Auch hierbei können unvollständig verbundene
Straßennetze entstehen. In diesem Kapitel werden die Methoden vorgestellt, die im
Rahmen dieser Arbeit entwickelt wurden, um Partitionen zu erkennen und zu einem
einzelnen Straßennetz zu verbinden.
7.1 Identifikation von Partitionen
Das Modul app.partition stellt zwei Klassen zur Verfügung: die Klasse PartitionFinder
und die Klasse Partition.
Der Konstruktor der Klasse PartitionFinder hat die Signatur PartitionFinder(osm_object),
wobei der Übergabeparameter osm_object eine Referenz auf das zugrunde liegen-
de OSM-Datenobjekt ist. Beim erstmaligen Aufruf einer Methode, die auf Partitio-
nen zugreifen muss, wird eine Instanz der Klasse PartitionFinder erzeugt und
in der Objektvariable __partitions der Datenmodell-Klasse OSM_objects gespei-
chert. Ein OSM-Straßennetz stellt mathematisch einen Graphen dar mit den OSM-
Nodes als Knoten des Graphen und den OSM-Ways als Kanten des Graphen. Wäh-
rend der Initialisierung der Klasse PartitionFinder werden durch die Methode
find_partitions() die Zusammenhangskomponenten des Kartengraphens ermit-
telt. Jede Zusammenhangskomponente stellt eine Partition dar.
Zur Bestimmung der Zusammenhangskomponenten bieten sich zwei Verfahren an,
ein Tiefendurchlauf oder ein Breitendurchlauf. Ein Tiefendurchlauf wird in der Re-
gel rekursiv umgesetzt. Da aufgrund der großen Datenmengen einer OSM-Karte
eine Rekursionstiefe erforderlich wäre, die die von Python vorgegebene maximale
40
7. Partitionen 41
Rekursionstiefe überschreitet, scheidet eine rekursive Umsetzung aus. Ein Breiten-
durchlauf lässt sich sehr einfach iterativ implementieren, so dass dieses Verfahren
zur Bestimmung der Zusammenhangskomponenten gewählt wird. Für jede Zusam-
menhangskomponente wird dabei eine Instanz der Klasse Partition erzeugt. Der
Konstruktor dieser Klasse hat die Signatur Partition(partition_id), wobei der
Übergabeparameter partition_id ein eindeutiger Integerwert größer 0 ist, der wäh-
rend des Breitendurchlaufs zur Partitionsbestimmung ermittelt wird.
In der Klasse PartitionFinder werden in einer Dictionary-Datenstruktur die ein-
zelnen Partitionen mit der partition_id als Key und dem Partitionsobjekt als Value
gespeichert. Des Weiteren stellt die Klasse Methoden zur Zusammenführung von
Partitionen oder zum Entfernen von Partitionen zur Verfügung.
In der Klasse Partition werden die konkreten Eigenschaften einer Partition verwal-
tet. Dazu werden in Listen die Node- und Straßen-Objekte der Partition gespeichert.
Nodes und Straßen, die während des Breitendurchlaufs zur Partitionsbestimmung
einer Partition zugeordnet werden, werden in den Listen der entsprechenden Partiti-
on abgelegt. Ausgehend von diesen Daten wird die geographische Ausdehnung der
Partition (Bounding Box) bestimmt.
Wenn Nodes und Straßen einer bestimmten Partition zugeordnet werden, wird den
Objektvariablen __partition_id der entsprechenden Objekte die Partitions-ID der
zugewiesenen Partition übergeben. Der bei der Initialisierung der Node- bzw. Way-
Objekte vorgegebene Wert ist __partition_id = 0 und dient während des Breiten-
durchlaufs als Indikator, ob das Objekt bereits einer Partition zugewiesen wurde.
Das Verbinden von Points of Interest mit dem Straßennetz (siehe Kapitel 8) und
die Liniengeneralisierung von Straßen (siehe Kapitel 6) verändern Partitionen durch
Hinzufügen oder Löschen von Straßen oder Nodes. Nach diesen Operationen, die
die Struktur einer Partition beeinflussen, wird in der Klasse PartitionFinder die
Objektvariable __recalculate auf True gesetzt. Bei der nächsten Operation, die Zu-
griff auf Partitionen nimmt, wird durch Aufruf der Methoden reset_partitions()
und find_partitions() eine Neuberechnung der Partitionen initiiert. Die Methode
reset_partitions setzt die Partition-IDs der Node- und Way-Objekte auf 0 zurück,
die Methode find_partitions baut wie oben beschrieben die Partitionen neu auf.
Das MoSP-GeoTool bietet die Möglichkeit, Straßen, die für Fußgänger irrelevant
sind, zum Beispiel Autobahnen, aus dem OSM-Datensatz zu löschen. Der Benutzer
soll zunächst überprüfen können, ob eine solche Filterung neue Partitionen entste-
hen lässt. Eine mögliche Situation ist in Abbildung 7.1 dargestellt. Ein Ausschluss
7. Partitionen 42
der waagrechten Straße, die als Autobahn gekennzeichnet ist, führt zu drei Partitio-
nen. Der Algorithmus muss dabei sicherstellen, dass an Straßenkreuzungen keine
Aufspaltung in zwei Partitionen erfolgt. So wird die in der Abbildung dargestellte
Straße1 vollständig einer Partition zugeordnet. Auch die Straßen Straße3 und Stra-
ße4 gehören zu einer gemeinsamen Partition.
'highway':'motorway'
Straße1
Straße2
Straße3
Straße4
Partition1
Partition2
Partition3
Partition3
Abbildung 7.1: Partitionierung durch Straÿen�lterung
Die Methode filter_streets(filter) ermittelt die Partitionierung des Straßen-
netzes, wenn Straßen bestimmter Kategorien ausgeschlossen werden. Der Überga-
beparameter filter ist eine Liste von Strings. Jedes Listenelement entspricht dem
Namen einer Straßenkategorie, die gefiltert werden soll. Straßen, die einem Filterkri-
terium entsprechen, werden mit einer partition_id = -1 versehen. Durch Aufruf
der Methode remove_filtered_streets() werden die gefilterten Straßen aus dem
OSM-Datensatz entfernt.
7.2 Zusammenführen von Partitionen
Die Methode connect_partitions(partition_thresholds) initiiert die Zusammen-
führung von Partitionen. Der Übergabeparameter partition_thresholds enthält als
Dictionary der Form { threshold_type : threshold_value, ... } verschiedene
Parameter, die das Verhalten der Zusammenführung bestimmen. Der Key threshold_type
kann dabei folgende Werte annehmen: search, projection, size, connection und
distance.
Die Bedeutung der einzelnen Parameter ist im folgenden erklärt:
• Search Distance (search):
Die Search Distance definiert die Größe des Suchgebiets um einen Knoten in
Metern. Innerhalb dieses Gebiets wird nach benachbarten Straßen gesucht.
7. Partitionen 43
• Projection Threshold (projection):
Der Projection Threshold in Metern bestimmt, um wie viel länger eine Stra-
ßenverbindung sein darf, die durch die Methode connect_by_node erzeugt
wird, gegenüber einer Straßenverbindung, die durch die Methode connect_by_projection
erzeugt wird (siehe Abschnitt 5.1).
• Minimum Partition Size (size):
Partitionen mit einer geringeren Knotenzahl als der Minimum Partition Size
werden bei der Zusammenführung ignoriert. Die betroffene Partition und die
dazugehörigen Straßen werden aus dem OSM-Datensatz entfernt.
• Maximum Connections (connection):
Der Wert für Maximum Connections legt fest, wie viele Knoten einer Parti-
tion maximal bei der Zusammenführung zweier Partitionen mit der zweiten
Partition verbunden werden sollen.
• Minimum Node Distance (distance):
Wenn ein oder mehr Knoten einer Partition bereits neu geknüpfte Verbindun-
gen zu einer anderen Partition haben, so müssen weitere Knoten mindestens
die Minimum Node Distance in Metern von den verbundenen Knoten entfernt
liegen, um ebenfalls mit der Partition verknüpft werden zu können.
Bei Ausführung der Methode connect_partitions wird zunächst überprüft, ob die
Objektvariable __recalculate auf True gesetzt ist. Gegebenenfalls wird durch Auf-
ruf der Methoden reset_partitions und find_partitions eine Neuberechnung
der Partitionen initiiert. Anschließend wird in einer while-Schleife so lange über al-
le Partitionen iteriert und die aktuell betrachtete Partition mit einer anderen Partition
verbunden, bis entweder nur noch eine Partition übrig ist oder Partitionen aufgrund
der vorgegebenen Parameter nicht verbunden werden konnten.
Bei jedem Schleifendurchlauf wird zunächst die Größe der aktuell betrachteten Parti-
tion überprüft. Liegt die Anzahl der Knoten unterhalb des durch die Minimum Parti-
tion Size vorgegebenen Wertes, so wird die Partition und die Straßen dieser Partition
entfernt. Die Knoten dieser Straßen werden nicht entfernt, da jeder Knoten potentiell
ein Point of Interest sein kann (siehe Kapitel 8) und durch eine Löschung verloren
wäre.
Wenn die Partition groß genug ist, wird für jeden Knoten dieser Partition eine Liste
mit Straßen aufgebaut, die sich innerhalb des Suchgebiets befinden, das durch die
Search Distance bestimmt wird. Durch die Methode get_adjacent_streets(node,
7. Partitionen 44
search_distance) der Klasse geo.osm_import.OSM_objects werden alle Straßen
gefunden, die das Suchgebiet berühren. Die Nodes einer Straße müssen nicht inner-
halb des Suchfensters liegen. Es reicht, wenn die Verbindungslinie zweier benach-
barter Straßenknoten durch das Suchgebiet läuft. In der Situation aus Abbildung 7.2
werden die schwarzen Straßen gefunden und der Liste hinzugefügt, während die
grauen Straßen bei der Suche ignoriert werden. Ziel dieser Operation ist es, die Su-
che nach möglichen Verbindungspunkten auf eine Auswahl nahe gelegener Straßen
einzugrenzen und so den Rechenaufwand der Partitionszusammenführung zu mini-
mieren.
search_distance
Abbildung 7.2: Funktionsweise der Methode get_adjacent_streets
Da Straßen, die zur selben Partition wie der betrachtete Knoten gehören, für die Ver-
bindung zu benachbarten Partitionen uninteressant sind, werden diese Straßen bei
der Erstellung der Liste ignoriert. Anschließend wird aus der so erzeugten Straßen-
liste die für den betrachteten Knoten nächstgelegene Straße sowie die Entfernung zu
dieser Straße bestimmt (Methode get_nearest_street(node, streets) der Klas-
se geo.geo_utils). Entfernung, Knoten, nächstgelegene Straße und Abstandsmodus
werden als Quadrupel in einer Liste gespeichert (zur Erklärung des Abstandsmodus
siehe Abschnitt 5.1). Diese Liste wird für jeden Knoten der Partition mit den ent-
sprechenden Werten erweitert. Zuletzt wird diese Liste aufsteigend nach den gespei-
cherten Entfernungen sortiert.
Einen möglichen Aufbau dieser Liste zeigt das folgende Listing:sorted_nodes_by_distances = [(2.4461237, <Node1>, <Way1>,<mode1>),
(3.3661097, <Node4>, <Way4>,<mode4>),(18.4205467, <Node3>, <Way3>,<mode3>),(19.8662921, <Node2>, <Way2>,<mode2>)]
In einer while-Schleife, in deren Schleifenkopf überprüft wird, ob die Anzahl der
gewünschten Verbindungsstellen erreicht ist, werden die Elemente der Liste sorted_
7. Partitionen 45
nodes_by_distances durchlaufen. Der Listen-Index zeigt dabei immer auf das Listen-
Element, das von den noch nicht bearbeiteten Elementen die kürzeste Distanz zu
einer benachbarten Partition hat. Knoten und Straße werden dem aktuellen Listen-
Element entnommen. Es wird überprüft, ob der Knoten entsprechend dem vorgege-
benen Wert für die Minimum Node Distance weit genug von den Knoten entfernt
ist, die bereits mit einer Partition verbunden wurden. Ist dies der Fall, so wird der
Knoten mit der Straße verbunden. In der in Abbildung 7.3 dargestellten Situation
soll Partition 1 mit Partition 2 verbunden werden. Die erste Verbindung wird über
Knoten 1 erzeugt, da dieser den geringsten Abstand zu der zweiten Partition hat.
Das nächste Element der Liste sorted_nodes_by_distances wäre Knoten 2. Dieser
liegt innerhalb der Minimum Node Distance um den bereits verbundenen Knoten
1. Über Knoten 2 erfolgt daher keine Verbindung. Knoten 3 liegt außerhalb der Di-
stanz, daher kann eine Verbindung erfolgen. Dieses Vorgehen soll verhindern, dass
bei ausgedehnten Partitionen die Verbindungsstellen zu anderen Partitionen zu dicht
beieinander liegen, sondern besser verteilt sind.
distance_thresholdPartition 1
Partition 2
12
3
Abbildung 7.3: Auswirkung der Minimum Node Distance
Anhand des Projection Thresholds wird bestimmt, ob die Verbindung mit einem Stra-
ßenknoten erfolgt (Methode connect_by_node des Moduls geo.geo_utils) oder ob
die Projektion des Knotens auf die Straße den Verbindungspunkt bestimmt (Methode
connect_by_projection des Moduls geo.geo_utils). Die Methode connect_by_projection
erzeugt die Verbindung eines Nodes mit einer Straße über die kürzeste Distanz.
Dabei wird in die Straße ein neuer Node eingefügt (siehe Abbildung 7.4). Diese
Verbindung wird daher immer kürzer sein als eine Verbindung über die Methode
connect_by_node. Wenn die Differenz der Längen der beiden neuen Verbindun-
gen den Projection Threshold übersteigt, erfolgt die Verbindung durch die Methode
connect_by_projection, ansonsten durch die Methode connect_by_node.
Ein kleiner Wert für den Projection Threshold erzeugt mehr neue Nodes als ein
großer Wert und verkompliziert damit das Straßennetz, was zu einem höheren Re-
chenaufwand für den MoSP-Simulator führt. Umgekehrt bevorzugt ein großer Pro-
7. Partitionen 46
connect_by_projectionconnect_by_node
Partition 1
Partition 2
Abbildung 7.4: Gegenüberstellung der Methoden connect_by_node undconnect_by_projection
jection Threshold lange Verbindungswege, was nicht den Verhältnissen in der Reali-
tät entspricht. Es bleibt dem Benutzer des MoSP-GeoTools überlassen, durch Wahl
eines optimalen Projection Thresholds eine Balance zwischen den beiden Möglich-
keiten zu finden.
Wenn entweder die Anzahl der gewünschten Verbindungen erreicht ist oder wenn die
Liste vollständig abgearbeitet ist, bricht die Schleife ab. Zuletzt werden die beiden
verbundenen Partitionen auch in der Datenstruktur selbst zusammengeführt. Dazu
werden Straßen und Knoten der einen Partition der anderen Partition hinzugefügt,
die partition_id der Straßen und Knoten angepasst und die Bounding Boxes der
beiden Partitionen verschmolzen.
8 Points of Interest
In den Simulationen des MoSP-Simulators sollen sich Personen zu Points of Inte-
rest (POI) bewegen. POI sind im Allgemeinen alleinstehende OSM-Nodes ohne Ver-
bindung zum Straßennetz. Damit ein Fußgänger in einer Simulation einen Point of
Interest erreichen kann, muss aber eine Verbindung zum Straßennetz bestehen. In
diesem Kapitel werden die Methoden vorgestellt, die im Rahmen dieser Arbeit ent-
wickelt wurden, um Points of Interest zunächst auszuwählen und anschließend mit
dem Straßennetz zu verbinden.
8.1 POI-Auswahl
Durch die Auswahl von Points of Interest über die graphische Benutzeroberfläche
durch den Benutzer des MoSP-GeoTools wird ein Objekt der Klasse Poi erzeugt. Der
Konstruktor der Klasse hat die Signatur Poi(osm_object). Der Übergabeparameter
osm_object beinhaltet eine Referenz auf das zugrunde liegende OSM-Datenobjekt.
Bei der Initialisierung des Objekts wird in der Objektvariablen __nodes eine Liste
aller Node-Objekte des Datenmodells gespeichert. Die Objektvariable __poi_nodes
wird als leeres Set initialisiert. In dieser Variablen werden Referenzen auf die als
Points of Interest ausgewählten Node-Objekte gespeichert. Mit der Methode get_poi(items)
werden Nodes als POI markiert. Points of Interest werden über Key/Value-Paare der
OSM-Node-Tags ausgewählt. Der Übergabeparameter items der Methode ist eine
Liste mit Tupeln aus Key/Value-Paaren als Listenelemente. Das folgende Beispiel
wählt Nodes als Points of Interest aus, die entweder den Tag-Key amenity und den
Tag-Value cafe haben oder den Tag-Key shop und den Tag-Value bakery haben:
items = [(amenity, cafe), (shop, bakery)]
Nach Ausführung der Methode get_poi mit diesen Parametern sind alle Nodes als
Points of Interest markiert, die im OSM-Datenmodell als Café oder Bäckerei ge-
kennzeichnet sind.
47
8. Points of Interest 48
In der Methode get_poi wird über alle Nodes des OSM-Datensatzes iteriert und
überprüft, ob deren Tags ein Key/Value-Paar aus der übergebenen Liste enthalten. Ist
dies der Fall, wird das entsprechende Node-Objekt der Objektvariable __poi_nodes
hinzugefügt. Außerdem wird in der Objektvariablen __poi des Node-Objekts die
Konstante POI_SELECTED gespeichert und das Objekt damit als „als POI ausge-
wählt“ markiert.
8.2 Algorithmen zur Verbindung von POI mit demStraßennetz
Im Folgenden wird die Arbeitsweise der Methoden erklärt, die im Rahmen dieser
Arbeit entwickelt wurden, um ausgewählte Points of Interest mit dem Straßennetz
zu verbinden.
Wenn die gewünschten Points of Interest ausgewählt wurden, wird durch Aufruf der
Methode connect_poi(poi_thresholds) der Algorithmus zum Verbinden der aus-
gewählten Nodes mit dem Straßennetz gestartet. Der Übergabeparameter poi_thresholds
enthält als Dictionary der Form { threshold_type : threshold_value, ... } ver-
schiedene Parameter, die das Verhalten des Algorithmus bestimmen. Der Key threshold_type
kann dabei folgende Werte annehmen: search, projection und address.
Die Bedeutung der einzelnen Parameter ist im Folgenden erklärt:
• Search Distance (search):
Die Search Distance definiert die Größe des Suchgebiets um einen Knoten in
Metern. Innerhalb dieses Gebiets wird nach benachbarten Straßen gesucht.
• Projection Threshold (projection):
Der Projection Threshold in Metern bestimmt, um wie viel länger eine Stra-
ßenverbindung sein darf, die durch die Methode connect_by_node erzeugt
wird, gegenüber einer Straßenverbindung, die durch die Methode connect_by_projection
erzeugt wird (siehe Abschnitt 5.1).
• Address Threshold (address):
Der Address Threshold in Metern bestimmt, um wie viel länger eine Straßen-
verbindung sein darf, wenn die Verbindung nicht zur nächstgelegenen Straße
erfolgt, sondern zu einer Straße mit einem bestimmten Straßennamen.
8. Points of Interest 49
Bevor die Funktionsweise der Methode connect_poi weiter erläutert wird, erfolgt
eine Beschreibung der Methoden, auf die diese Methode zugreift, um die Verbindun-
gen der Points of Interest mit dem Straßennetz herzustellen.
Die folgenden Methoden arbeiten analog zu Methoden, die bereits in früheren Kapi-
teln beschrieben wurden. An dieser Stelle wird daher nur auf die wesentlichen Unter-
schiede eingegangen. Die Methode get_adjacent_buildings(node, threshold)
arbeitet analog zu der in Kapitel 7.2 beschriebenen Methode get_adjacent_streets.
Statt einer Liste von Straßenobjekten wird hier eine Liste der umliegenden Gebäude-
objekte um einen Node erzeugt. Die Methode get_nearest_building(node, buildings)
bestimmt analog zu der Methode get_nearest_street (Kapitel 5.1) aus einer Liste
von Gebäudeobjekten das nächstgelegene Gebäude zu einem Node und die dazu-
gehörige Distanz. Im Unterschied zu den Straßen wird bei den Gebäuden kein Ab-
standsmodus benötigt, so dass der Rückgabewert der Methode get_nearest_building
ein Tupel aus Referenz auf das Gebäude-Objekt und Abstand ist. Die Methode connect_
with_nearest_street(node, streets, projection_threshold) bestimmt aus ei-
ner Liste von Straßenobjekten streets die zu einem gegebenen Node-Objekt node
nächstgelegene Straße (Methode get_nearest_street des Moduls geo.geo_utils).
Anhand des dabei ermittelten Abstandsmodus und des Übergabeparameters projection_threshold
entscheidet die Methode, ob der Node über die Methode connect_by_node des Mo-
duls geo.geo_utils mit einem Straßenknoten erfolgt oder ob die Projektion des No-
des auf die Straße den Verbindungspunkt bestimmt (Methode connect_by_projection
des Moduls geo.geo_utils) (siehe Kapitel 7.2).
Die folgenden Methoden haben keine Entsprechung in anderen Kapiteln. Die Metho-
de is_street_node(node) überprüft durch Abfrage der Objektvariable __neighbours
des Node-Objekts, ob ein gegebener Node Bestandteil einer Straße ist. Die Methode
is_area(way) entscheidet, ob das als Parameter übergebene Way-Objekt eine Fläche
ist. Dazu muss das erste und das letzte Element der referenzierenden Nodes identisch
sein. Die Methode is_building(way) überprüft, ob das übergebene Way-Objekt
ein Gebäude ist. Dazu wird mit der Methode is_area abgefragt, ob das Objekt ei-
ne Fläche ist, und es wird überprüft, ob die Tags des Objekts ein Key/Value-Paar
’building’ : ’yes’ enthalten. Die Methode get_building_entrance(building)
erstellt für ein gegebenes Gebäudeobjekt eine Liste von Eingängen. OSM-Nodes
können in den Tags durch das Key/Value-Paar ’building’ : ’entrance’ als Ge-
bäudeeingang gekennzeichnet sein. Die Methode überprüft die Tags der Node-Objekte,
aus denen das Gebäudeobjekt aufgebaut ist, auf dieses Key/Value-Paar und fügt ge-
fundene Eingangsnodes in die Liste ein. Die Methode get_street_by_name(address,
8. Points of Interest 50
streets) erzeugt aus der mit dem Parameter streets übergebenen Liste aus Stra-
ßenobjekten eine neue Liste, die nur Straßenzüge enthält, die den mit address als
String übergebenen Straßennamen haben. Die Liste ist an dieser Stelle notwendig,
da eine in der Realität durchgehende Straße im OSM-Datenmodell durch mehrere
Straßenobjekte mit demselben Straßennamen abgebildet werden kann. Wenn keine
Straße mit diesem Namen enthalten ist, wird eine leere Liste zurückgegeben.
Mit Hilfe der bisher beschriebenen Methoden erfolgt durch zwei weitere im Rah-
men dieser Arbeit entwickelte Methoden die Verbindung der ausgewählten Points of
Interest mit dem Straßennetz.
Die Methode connect_by_address(poi_node, address, streets, projection_threshold,
address_threshold) versucht, das übergebene POI-Node-Objekt poi_node mit ei-
ner Straße mit dem Straßennamen address zu verbinden. In der Variablen connected,
die mit False initialisiert wird, wird der Erfolg der Verbindung als Boolean-Wert
zwischengespeichert. Nach Ausführung der Methode connect_by_address ist die-
se Variable der Rückgabewert der Methode. Mit der Methode get_street_by_name
werden wie oben beschrieben aus der übergebenen Straßenliste streets die Stra-
ßenobjekte mit dem entsprechenden Straßennamen herausgefiltert und in der Varia-
blen named_streets gespeichert. Im Folgenden wird entweder mit der Liste streets
oder mit der Liste named_streets die Methode connect_with_nearest_street auf-
gerufen. Wenn keine Straße mit dem entsprechenden Straßennamen gefunden wurde,
wird die Liste streets verwendet. Ansonsten wird über den Parameter address_threshold
entschieden, ob die Liste named_streets oder die Liste streets übergeben wird.
Die Methode connect_with_nearest_street versucht nun ihrerseits, eine Verbin-
dung zwischen Node und Straßennetz herzustellen und gibt je nach Erfolg True oder
False zurück. Der Rückgabewert wird in der Variablen connected gespeichert.
Die Methode connect_by_building(poi_node, building, streets, projection_threshold,
address_threshold) versucht, ein POI-Node-Objekt poi_node, das innerhalb eines
Gebäude building liegt, mit einem Straßennetz streets zu verbinden. Auch hier
wird in der Variablen connected der Erfolg der Verbindung als Boolean-Wert zwi-
schengespeichert. Zu Beginn wird überprüft, ob es sich bei dem übergebenen Ge-
bäudeobjekt tatsächlich um ein Gebäude handelt (Methode is_building) und ob der
übergebene Node tatsächlich innerhalb dieses Gebäudes liegt (Methode is_inside_polygon
aus dem Modul geo.geo_utils). Sollten diese Kriterien nicht zutreffen, bricht die
Methode connect_by_building ab und gibt False zurück. Treffen die Kriterien zu,
werden im Folgenden die Gebäudeadresse, die Adresse des Points of Interest und die
8. Points of Interest 51
Gebäudeeingänge ermittelt. Bei Erfolg stehen in den Variablen building_address
bzw. poi_address Straßennamen als Strings, ansonsten None, und in building_entrance
eine Liste von Gebäudeeingängen oder eine leere Liste. Im weiteren Verlauf wird nun
versucht, den POI-Node mit folgenden Prioritäten mit dem Straßennetz zu verbinden:
1. Wenn Gebäudeeingänge vorhanden sind, dann verbinde den Node über die
Eingangsnodes mit dem Straßennetz (näheres siehe weiter unten)
2. Wenn der Point of Interest eine Adresse hat, dann verbinde den POI-Node über
seine Adresse mit dem Straßennetz (Aufruf der Methode connect_by_address
mit poi_node als Node-Parameter und poi_address als Adress-Parameter)
3. Wenn das Gebäude eine Adresse hat, dann verbinde den POI-Node über die
Gebäudeadresse mit dem Straßennetz (Aufruf der Methode connect_by_address
mit poi_node als Node-Parameter und building_address als Adress-Parameter)
4. Ansonsten verbinde den POI-Node mit der nächstgelegenen Straße ohne Be-
rücksichtigung des Gebäudes (Aufruf der Methode connect_with_nearest_street
mit poi_node als Node-Parameter).
Wenn Gebäudeeingänge vorhanden sind, enthält die Liste building_entrance die
Node-Objekte der Eingänge als Listenelemente. Über diese Liste wird iteriert. In
jedem Iterationsschritt wird der POI-Node mit dem entsprechenden Eingangsno-
de entrance verbunden (Aufruf der Methode connect_by_node aus dem Modul
geo.geo_utils mit poi_node und entrance als Übergabeparameter). Anschließend
wird überprüft, ob der Eingangsnode entrance eine Adresse hat. Im Folgenden wird
nun der Eingangsnode analog der obigen Prioritäten mit dem Straßennetz verbunden:
1. über die Adresse des Eingangs, 2. über die POI-Adresse, 3. über die Gebäude-
adresse, 4. direkt mit der nächstgelegenen Straße. Der Aufruf der Methoden erfolgt
analog zu oben mit dem Eingangsnode entrance als Node-Parameter. Der Rückga-
bewert der aufgerufenen Methoden wird in der Variablen connected gespeichert.
In Abbildung 8.1 ist die Situation dargestellt, dass ein Point of Interest innerhalb
eines Gebäudes mit einer Adresse liegt. Zudem ist ein Knoten des Gebäudeobjekts
als Eingang markiert. Die Wege der näheren Umgebung haben im OSM-Datensatz
keine Namen. Der nächste Weg, der einen zur Gebäudeadresse passenden Straßen-
namen trägt, ist ca. 75 Meter vom Gebäudeeingang entfernt. Der Algorithmus ver-
bindet zuerst den POI mit dem Eingang des Gebäudes. Da weder der POI noch der
Eingang eine Adresse aufweisen, erfolgt dann die Verbindung über die Adresse des
Gebäudes. Beim Aufruf des Algorithmus wurde ein Wert von 100 Metern für den
8. Points of Interest 52
Address Threshold eingegeben. Daher erhält die sehr lange Straßenverbindung über
die Adresse den Vorzug vor der direkten Verbindung zur nächstgelegenen Straße.
Abbildung 8.1: Verbindung eines POI über Gebäudeeingang und Gebäude-adresse mit dem Straÿennetz
Wie eingangs dieses Kapitels erwähnt, wird durch den Aufruf der Methode connect_
poi(poi_thresholds) der Algorithmus zum Verbinden der ausgewählten Nodes mit
dem Straßennetz gestartet. Zu Beginn der Methode werden die entsprechenden Threshold-
Werte in den Variablen search_threshold, projection_threshold und address_threshold
gespeichert. Diese werden als Übergabeparameter bei den Aufrufen der verschiede-
nen Verbindungsmethoden benötigt. Anschließend wird über die in der Objektva-
riablen __poi_nodes gespeicherte Liste der Node-Objekte, die als Points of Interest
ausgewählt wurden, iteriert. Im Folgenden wird der Algorithmus beschrieben, der
für jeden Listeneintrag poi_node durchgeführt wird.
Die Variable connected, in der im weiteren Verlauf gespeichert wird, ob eine Verbin-
dungsmethode erfolgreich war, wird mit False initialisiert. Wenn ein Point of Inte-
8. Points of Interest 53
rest bereits Bestandteil des Straßennetzes ist (Aufruf der Methode is_street_node),
wird in der Objektvariablen __poi des Node-Objekts die Konstante POI_CONNECTED
gespeichert und das Objekt damit als „POI mit Straßennetz verbunden“ markiert. Der
aktuelle Schleifendurchlauf wird abgebrochen. Ansonsten bestimmt der Algorith-
mus eine Liste der benachbarten Straßen des POI-Nodes durch Aufruf der Metho-
de get_adjacent_streets und speichert die Straßenliste in der Variable streets.
Wenn der Search Threshold zu klein gewählt wird und daher keine benachbarten
Straßen gefunden werden, ist diese Straßenliste leer. Die folgenden Anweisungen
werden dann übersprungen, da keine Straße zum Verbinden ausgewählt werden kann.
Der Algorithmus bestimmt die Adresse des Points of Interest und eine Liste der
benachbarten Gebäude (Aufruf der Methode get_adjacent_buildings). Die Er-
gebnisse werden in den Variablen poi_address und building gespeichert. Konn-
te kein entsprechendes Ergebnis bestimmt werden, steht in der jeweiligen Variable
None. Mit diesen Ergebnissen wird das nächstgelegene Gebäude (Aufruf der Me-
thode get_nearest_building) und der nächstgelegene Straßenknoten (Aufruf der
Methode get_nearest_street_node) ermittelt. Diese Ergebnisse werden in den Va-
riablen nearest_building bzw. nearest_node gespeichert.
Insbesondere bei Hochhäusern kann es sein, dass verschiedene Points of Interest mit
denselben geographischen Koordinaten im OSM-Datenmodell enthalten sind. Um
das Ziehen unnötiger Straßen zu verhindern, wird nur der Node, auf den als erstes
zugegriffen wird, mit dem Straßennetz verbunden. Jeder weitere Node mit densel-
ben geographischen Koordinaten wird über den bereits verbundenen POI-Node mit
dem Straßennetz verknüpft. Dazu wird mit der Methode have_same_coords(node1,
node2) aus dem Modul geo.geo_utils überprüft, ob die in poi_node und nearest_node
gespeicherten Node-Objekte dieselben Koordinaten haben. Wenn dies der Fall ist,
werden die beiden Nodes über die Methode connect_by_node aus dem Modul geo.geo_utils
über eine Straße der Länge 0 miteinander verknüpft. Wenn an dieser Stelle des Algo-
rithmus die Variable connected noch auf False steht, wird versucht, den POI-Node
über die Methode connect_by_building mit dem in nearest_building gespeicher-
ten Gebäudeobjekt als building-Parameter mit dem Straßennetz zu verbinden. Ist
diese Methode nicht erfolgreich, weil der POI-Node zum Beispiel nicht innerhalb
des Gebäudes liegt, steht die Variable connected an dieser Stelle immer noch auf
False. Wenn in der Variablen poi_address ein Straßenname gespeichert ist, wird
als Nächstes probiert, die Verbindung mit der Methode connect_by_address her-
zustellen. Wenn auch diese Methode nicht erfolgreich ist, weil zum Beispiel in-
nerhalb des vorgegebenen Suchgebiets keine Straße mit diesem Straßennamen ge-
8. Points of Interest 54
funden werden kann, wird als letztes versucht, den POI-Node über die Methode
connect_with_nearest_street mit der nächstgelegenen Straße zu verbinden. An
dieser Stelle des Algorithmus ist der Anweisungsblock beendet, der nur ausgeführt
wird, wenn die Liste streets nicht leer ist.
Sofern der letzte Anweisungsblock durchlaufen wird, wird spätestens mit dem Auf-
ruf der Methode connect_with_nearest_street erfolgreich eine Straßenverbindung
hergestellt und die Variable connected auf True gesetzt. In der Objektvariablen
__poi des Node-Objekts wird die Konstante POI_CONNECTED gespeichert und das
Objekt damit als „POI mit Straßennetz verbunden“ markiert. Wenn der letzte An-
weisungsblock übersprungen wird, weil die Liste streets leer ist, steht die Variable
connected nach wie vor auf False. In der Objektvariablen __poi des Node-Objekts
wird die Konstante POI_NOT_CONNECTED gespeichert und das Objekt damit als „POI
nicht mit Straßennetz verbunden“ markiert. An dieser Stelle des Algorithmus ist ein
Iterationsschritt beendet und das Verfahren wird mit dem nächsten POI-Node in der
Objektvariablen __poi_nodes fortgesetzt.
Der Benutzer des MoSP-GeoTools kann nach Ausführung der Methode connect_poi
entscheiden, ob die Methode erneut aufgerufen wird, um mit veränderten Parametern
poi_thresholds noch unverbundene POI-Nodes mit dem Straßennetz zu verbinden.
Die Kennzeichnung der POI mit den oben erwähnten Konstanten ermöglicht eine
entsprechende Markierung der POI in der Kartendarstellung des MoSP-GeoTools.
Darüber hinaus erhält der Algorithmus zur Liniengeneralisierung durch diese Mar-
kierung das Signal, dass der betroffene Node nicht aus dem Straßennetz entfernt
werden darf (siehe Kapitel 6).
9 Fazit
Zusammenfassung der Ergebnisse
Im Rahmen dieser Arbeit wurde eine Datenreduktion durch Liniengeneralisierung
implementiert. Die Effizienz des Algorithmus wird im folgenden mit drei verschie-
denen Karten überprüft, einer Karte des gesamten Stadtgebiets von Hannover, einer
Karte der innerstädtischen Stadteile von Hannover (Linden, Calenberger Neustadt,
Nordstadt, Vahrenwald, List, Mitte, Südstadt und Ricklingen) sowie einer Karte des
Stadtbezirks Hannover-Mitte. Hier sind jeweils ähnliche Reduktionswerte zu erwar-
ten, da das Straßennetz einer kleineren Karte ein Teilnetz der jeweils größeren Karten
darstellt. Als Vergleich wird daher diesen Karten eine Karte der Innenstadt Chicagos
(The Loop) gegenübergestellt. Aufgrund des schachbrettartigen Straßenmusters mit
langen, geraden Straßenzügen ist zu erwarten, dass sich bereits mit niedrigen Tole-
ranzwerten sehr große Reduzierung der Straßenknoten erzielen lassen. Zur Auswer-
tung wird eine Funktion verwendet, die die Straßenobjekte einer Karte zählt. Die
referenzierended Nodes aller Straßen werden in dem Python-Mengen-Datentyp set
gespeichert, so dass jeder Straßenknoten genau einmal gezählt wird. Da bei der Im-
plementierung des Algorithmus der Anfangs- und Endknoten eines Straßenobjekts
sowie Straßenknoten, die Straßenkreuzungen darstellen, als feste Punkte angesehen
werden, ergibt sich für jede Karte eine minimale Knotenmenge als Grenzwert. Um
diese Knotenmenge zu bestimmen werden jedes erste und jedes letzte Node-Objekt
einer Straße sowie alle Node-Objekte der Straßen, die einen Nachbarschaftsgrad von
drei und größer haben, ebenfalls in einem set gespeichert. In der folgenden Tabelle
werden für jede der genannten Karten die Anzahl der Straßenobjekte, Anzahl der
Straßenknoten des OSM-Datenmodells und der Grenzwert sowohl absolut als auch
als Prozentwert bezogen auf die gesamte Anzahl der Straßenknoten aufgelistet.
55
9. Fazit 56
Karte Straßen Straßenknoten Grenzwert Grenzwert (%)
Hannover gesamt 17563 62725 27904 44,5
Han. innere Stadtteile 6847 22396 10727 47,9
Han.-Mitte 4672 15336 7190 46,9
Chicago The Loop 669 2574 1192 46,3
Der Tabelle kann entnommen werden, dass durch den Algorithmus etwa jeder zweite
Straßenknoten entfernt werden kann. In Abbildung 9.1 ist für die Karten die Anzahl
der Straßenknoten in Abhängigkeit vom Toleranzwert der Liniengeneralisierung dar-
gestellt. Die Werte sind für eine bessere Vergleichbarkeit auf die Anfangswerte der
jeweiligen Kurve normiert. Für die drei hannoverschen Karten ergeben sich wie er-
wartet ähnliche Reduktionswerte. Durch einen Toleranzwert von 10 Metern können
breits etwa 40 % der Straßenknoten entfernt werden. Dies Entspricht 80 % der mög-
lichen Datenreduktion. Ab einem Toleranzwert von 20 Metern werden 90 % der
maximal möglichen Knoten entfernt. Bei höheren Werten ergibt sich keine signifi-
kante Datenreduktion mehr. Wie ebenfalls erwartet, schneidet die Karte von Chi-
cagos Innenstadt bei niedrigen Toleranzwerten besser ab. Allerdings ist der Unter-
schied nicht sehr signifikant. Auf den ersten Blick scheint dies im Widerspruch zu
der oben gemachten Aussage zu stehen. Bei genauerer Betrachtung der Karte ist
aber zu erkennen, dass Straßenzüge des Schachbretts teilweise ohne Zwischenkno-
ten von Kreuzung zu Kreuzung gehen. Die Liniengeneralisierung hat hier bereits
bei der Datenerfassung durch die OpenStreetMap-Community stattgefunden (siehe
Abbildung 9.2).
In Abbildung 9.3 sind unveränderte Straßenverläufe (oben) und Verläufe nach einer
Generalisierung mit einem Toleranzwert von 10 Metern (unten) dargestellt. Dieser
Toleranzwert sorgt bereits für eine fast nicht mehr zu verbessernde Datenreduktion.
Die generalisierten Straßenverläufe bei diesem Wert entsprechen durchaus noch der
Realität. Insgesamt läßt sich mit diesem Toleranzwert also sehr gut arbeiten. Eine
deutlich stärkere Generalisierung ließe sich nur noch erreichen, imdem auch die bis-
her festgehaltenen Punkte der Generalisierung unterworfen werden. Dieses bedeutete
aber sehr viel komplexere Algorithmen, da nun aktiv die Topologien von Kreuzungs-
punkten erhalten werden müssen.
Der Algorithmus zur Zusammenführung von Partitionen ist so angelegt, dass immer
eine Verbindung zwischen zwei Partitionen hergestellt werden kann. Der Benutzer
des MoSP-GeoTools muss nur die Search Distance groß genug wählen. Für jeden
Node einer Partition wird innerhalb dieses Suchbereichs nach Straßen anderer Parti-
9. Fazit 57
0 2 4 6 8 1 0 1 2 1 4 1 6 1 8 2 0 2 2 2 4
0 , 5
0 , 6
0 , 7
0 , 8
0 , 9
1 , 0
�
C h i c a g o ( T h e L o o p ) H a n n o v e r ( g e s a m t ) H . ( i n n e r e S t a d t t e i l e ) H . - M i t t e
����
����
����
�����
�����
�����
������
�����
���
���
T o l e r a n z ( m )
Abbildung 9.1: Anzahl der Straÿenknoten in Abhängigkeit vom Toleranzwertder Liniengeneralisierung
tionen gesucht, mit denen die Partition verknüpft werden kann. Ein größeres Such-
fenster erhöht zwar die Wahrscheinlichkeit, eine Verbindungsstelle zu finden, erhöht
aber auch gleichzeitig den Aufwand an anderen Stellen des Straßennetzes, an denen
dieser Aufwand nicht nötig wäre. Wie groß das Suchfenster sein muss, um alle Par-
titionen einer Karte in einem Durchlauf des Algorithmus zu verbinden, hängt sehr
stark von der Karte ab. Bei der Karte von Hannover-Mitte reicht bereits ein Such-
fenster von zwei Metern, um alle 55 Partitionen der Karte zu verbinden. Die Karte
mit dem gesamten Stadtgebiet von Hannover erfordert dagegen eine Search Distan-
ce von Mindestens 40 Metern um alle 151 Partitionen gleichzeitig zu verbinden. Bei
niedriegeren Werten nimmt die Erfolgsrate sehr schnell ab. Als sinnvolle Vorgehens-
weise wird daher erachtet, die Partitionszusammenführung mit einem kleinen Wert
für das Suchfenster zu starten.
Für die Verbindung von Points of Interest mit dem Straßennetz gilt dasselbe wie für
Partitionen, da die Methoden für die Bestimmung der Verknüpfungsstellen dieselben
sind. Interessant wäre noch die Fragestellung, in wie weit eine Verknüpfung der POI
die Komplexität des Straßennetzes beeinflusst. Die Anzahl der möglichen Points of
Interest ist allerdings gering im Vergleich zu der Gesamtzahl der Straßenknoten. So
kommen bei der Karte von ganz Hannover auf rund 60.000 Straßenknoten rund 100
Points of Interest vom Typ Café. Somit hat eine Verbindung der POI zum Straßennetz
nur einen vernachlässigbar kleinen Einfluß auf die Komplexität des Straßennetzes.
9. Fazit 58
Abbildung 9.2: Ausschnitt des Straÿennetzes von Chicago (Darstellung imJava-OpenStreetMap-Editor
Ausblick
Points of Interest sind nur während der Bearbeitung im MoSP-GeoTool als solche
markiert. Nach Abspeichern der Karte und erneutem Öffnen der Karte sind die ver-
knüpften POI-Nodes nur noch normale Straßenknoten. Sofern sie nicht erneut als
POI markiert werden, können sie bei einer möglichen weiteren Generalisierung aus
dem Straßennetz entfernt werden. Es wäre also überlegenswert, ob zum Zwecke ei-
ner permanenten Markierung als Point of Interest beim Abspeichern der Karte ein
für den internen Gebrauch im MoSP-GeoTool gedachtes OSM-Tag gesetzt wird.
Sowohl bei der Verbindung von Points of Interest mit dem Straßennetz als auch bei
der Zusammenführung von Partitionen werden neue Straßen gezogen. Es wird aller-
dings nicht überprüft, ob die neuen Straßenverbindungen in der Realität auch sinn-
voll sind. So können Straßen durch OSM-Tags als nicht für Fußgänger benutzbar
gekennzeichnet sein, z. B. die Zufahrt zu einer Tiefgarage. Tags sind zwar optional,
so dass nicht gewährleistet ist, dass Straßen entsprechend markiert sind, aber wenn
eine solche Information vorhanden ist, dann kann sie auch als Entscheidungshilfe
herangezogen werden. Auch durch Anwendung der Straßenfilterfunktion (siehe Ab-
schnitt 7.1) können in der Realität nicht mögliche Straßenverbindungen geschaffen
werden. Wenn zum Beipiel durch die Methode eine Autobahn entfernt wird, so kann
eine eventuell notwendige Partitionszusammenführung durch einen Fußweg über die
Autobahn hinweg erfolgen. Hier können in zukünftigen Arbeiten durch genauere
Analyse der Umgebung sinnvollere Verbindungen geschaffen werden.
9. Fazit 59
Abbildung 9.3: Unveränderte (oben) und generalisierte (unten, Toleranzwert10 Meter) Straÿenverläufe
Literaturverzeichnis
[3DS] Polyline reduction. 3DSoftware.com. [Online]. Available: http:
//mappinghacks.com/code/PolyLineReduction/
[Bar05] N. Bartelme, Geoinformatik: Modelle, Strukturen, Funktionen, 4th ed.
Springer, 2005.
[Bou87] P. Bourke. (1987) Determining if a point lies on the interior of a polygon.
[Online]. Available: http://paulbourke.net/geometry/insidepoly/
[DP73] D. H. Douglas and T. K. Peucker, “Algorithms for the reduction of the
number of points required to represent a line or its caricature.” The Cana-
dian Cartographer, vol. 10, no. 2, pp. 112–122, 1973.
[Ebi02] K. Ebisch, “A correction to the Douglas–Peucker line generalization al-
gorithm,” Computers & Geosciences, vol. 28, pp. 995–997, 2002.
[EPS] EPSG:3857. EPSG Geodetic Parameter Registry. [Online]. Available:
http://www.epsg-registry.org/report.htm?type=selection&entity=urn:
ogc:def:crs:EPSG::3857&reportDetail=short&style=urn:uuid:
report-style:default-with-code&style_name=OGP%20Default%
20With%20Code&title=EPSG:3857
[Gut84] A. Guttman, “R-trees: A dynamic structure for spatial searching,” in Pro-
ceedings of the ACM SIGMOD International Conference on Management
of Data, 1984, pp. 47–57.
[HGM02] G. Hake, D. Grünreich, and L. Meng, Kartographie: Visualisierung
raum-zeitlicher Informationen, 8th ed. de Gruyter, Berlin, New York,
2002.
[HSS11] B. Henne, C. Szongott, and M. Smith, “Towards a mobile security & pri-
vacy simulator,” in 2011 IEEE Conference on Open Systems (ICOS2011),
Langkawi, Malaysia, Sep. 2011.
60
Literaturverzeichnis 61
[Ins] GIS II - Liniengeneralisierung. Institut für Kartographie und
Geoinformatik, Universität Hannover. [Online]. Availa-
ble: http://www.ikg.uni-hannover.de/geosensor/lehre/katalog/gis/gisII_
uebung/Liniengeneralisierung.pdf
[Lan09] (2009) UTM-Abbildung und UTM-Koordinaten. Lan-
desamt für Vermessung und Geoinformation Bay-
ern. [Online]. Available: http://vermessung.bayern.de/file/pdf/1910/
UTMAbbildungundKoordinaten.pdf
[map] Pure-Python Douglas-Peucker line simplification/generalization. map-
pinghacks.com. [Online]. Available: http://mappinghacks.com/code/dp.
py.txt
[Opea] EPSG:3857. OpenStreetMap Wiki. [Online]. Available: http://wiki.
openstreetmap.org/wiki/EPSG:3857
[Opeb] JOSM file format. OpenStreetMap Wiki. [Online]. Available: http:
//wiki.openstreetmap.org/wiki/JOSM_file_format
[Opec] OSM XML. OpenStreetMap Wiki. [Online]. Available: http://wiki.
openstreetmap.org/wiki/DE:OSM_XML
[Oped] Slippy map. OpenStreetMap Wiki. [Online]. Available: http://wiki.
openstreetmap.org/wiki/DE:Slippy_Map