69
Gottfried Wilhelm Leibniz Universität Hannover Fachgebiet Distributed Computing Distributed Computing & Security Group Bachelorarbeit im Studiengang Informatik (B. Sc.) Generalisierung und Anreicherung von Geodaten für den Mobile Security & Privacy Simulator Verfasser: Carsten Protsch Erstprüfer: Prof. Dr. rer. nat. M. Smith Zweitprüferin: Prof. Dr.-Ing. G. von Voigt Betreuer: M. Sc. B. Henne Datum: 30. September 2011

Generalisierung und Anreicherung von Geodaten für den ... · die Charakteristik der Straßenzüge möglichst erhalten bleiben, um eine wirklich- keitsgetreue Simulation zu ermöglichen

  • Upload
    dokhanh

  • View
    213

  • Download
    0

Embed Size (px)

Citation preview

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

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