Institut für Informatik AG Medieninformatik Erfassung

Transcription

Institut für Informatik AG Medieninformatik Erfassung
Institut für Informatik
AG Medieninformatik
Masterarbeit
Erfassung und Visualisierung von
Echtzeitverkehrsdaten mit Smartphones
Daniel Künne
Dezember 2011
Erstgutachter:
Prof. Dr. Oliver Vornberger
Zweitgutachter:
Dr. Jutta Göers
Zusammenfassung
In dieser Arbeit wird die Konzeption und Implementation einer Open-Source-Software zur Erfassung und Visualisierung von Echtzeitverkehrsdaten vorgestellt. Dabei handelt es sich um eine
klassische Client-Server-Architektur, bestehend aus der Android-Anwendung
TracJamDroid
und einem in Java implementierten Server.
Auf den mobilen Endgeräten wird Autofahrern das Verkehrsaufkommen auf ihrer aktuellen Strecke graphisch aufbereitet angezeigt. Des Weiteren erhalten sie Informationen über Geschwindigkeitsbegrenzungen und vorliegende Verkehrsstörungen, wie Unfälle oder Staus. Die hierfür
als Grundlage verwendeten Daten sind komplett nutzergeneriert und wurden im Rahmen dieser
Applikation entweder automatisiert erfasst oder von den Anwendern gemeldet.
Der Server dient als zentraler Sammelpunkt aller Informationen und bereitet diese in vielfältigen
Prozessen für die Verwendung auf. Er kann dabei verschiedene Aktualitätsgrade der erfassten
Geschwindigkeitsdaten unterscheiden, wiederkehrende Verkehrsprobleme identizieren und die
vorhandenen Straÿeninformationen um fehlende Werte erweitern. Auÿerdem bietet er Schnittstellen an, über die den Clients ein vereinfachtes Navigationssystem zur Verfügung gestellt wird,
welches zeitnah auf neu eingehende Verkehrsmeldungen reagiert und gegebenenfalls eine neue
Route berechnet.
Neben den zugrundeliegenden Technologien und Frameworks werden auch noch die Architektur und die verschiedenen Techniken zur Problemidentikation betrachtet. Auÿerdem werden
die eingesetzten Analyse- und Aggregationsprozesse näher behandelt. Abschlieÿend erfolgt eine
Gegenüberstellung von Aufwand und Nutzen, sowie ein Vergleich der erstellten Software mit
ähnlichen proprietären Systemen.
Inhaltsverzeichnis
1
2
Einleitung
Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.2
Zielsetzung
3
1.3
Aufbau der Arbeit
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
7
2.1
PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.2
Kartographische Grundbegrie
2.3
Android
PostGIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.3.1
Systemarchitektur
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.3.2
Software Development Kit . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.3.3
Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
2.3.4
Views
13
2.3.5
Activities
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
2.3.6
Services, Handler und Asynchrone Tasks . . . . . . . . . . . . . . . . . . .
15
2.3.7
Ressourcen
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.3.8
Menüs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.3.9
Datenhaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Frameworks
3.1
Hibernate
3.2
3.3
CloudMade
21
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
Hibernate Spatial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
OpenStreetMap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3.1.1
3.2.1
4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Grundlagen
2.1.1
3
1
1.1
OSMdroid-Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
26
Architektur
29
4.1
Das Client-Server-Konzept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
4.2
Kommunikation zwischen den Komponenten . . . . . . . . . . . . . . . . . . . . .
30
4.2.1
32
Protokoll
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
Server
33
5.1
34
5.2
5.3
6
Vorbereitung der Datenbasis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1.1
Erstellen von Bibliotheken für die Clients
. . . . . . . . . . . . . . . . . .
37
5.1.2
Probleme bei der Verarbeitung der OpenStreetMap-Daten . . . . . . . . .
38
5.1.3
Datenbankdesign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
Verarbeitung der Nutzerinteraktion . . . . . . . . . . . . . . . . . . . . . . . . . .
40
5.2.1
Bereitstellung des Verkehrsaufkommens
. . . . . . . . . . . . . . . . . . .
41
5.2.2
Bearbeitung von Verkehrsmeldungen . . . . . . . . . . . . . . . . . . . . .
42
5.2.3
Routing
43
Datenaggregation und -analyse
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Mapping der GPS-Informationen
5.3.2
Analyse der Geschwindigkeit
5.3.3
Aktualisierung des Routings . . . . . . . . . . . . . . . . . . . . . . . . . .
48
5.3.4
Erfassung der Geschwindigkeitsbegrenzungen
. . . . . . . . . . . . . . . .
49
5.3.5
Erkennung wiederkehrender Probleme
. . . . . . . . . . . . . . . . . . . .
51
5.3.6
Verarbeitung ungültiger Einträge . . . . . . . . . . . . . . . . . . . . . . .
52
. . . . . . . . . . . . . . . . . . . . . . .
45
. . . . . . . . . . . . . . . . . . . . . . . . .
46
55
6.1
Das Android-Manifest
6.2
Datenverwaltung
6.4
44
5.3.1
Android-Client
6.3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
6.2.1
Positionsbestimmung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
6.2.2
Overlays und Overlay Items . . . . . . . . . . . . . . . . . . . . . . . . . .
59
6.2.3
Verkehrsinformationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
Hintergrundprozesse
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.1
Verwaltung der ID
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3.2
Aktualisierung der Daten
61
62
. . . . . . . . . . . . . . . . . . . . . . . . . . .
62
Streckenauslastung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
6.4.1
Informationen zum aktuellen Abschnitt
. . . . . . . . . . . . . . . . . . .
65
6.4.2
Übersichtskarte und Overlays
. . . . . . . . . . . . . . . . . . . . . . . . .
66
6.4.3
Beispielimplementation: SpeedOverlayItem und RoadOverlay
6.4.4
Wechsel zu anderen Komponenten
. . . . . . .
66
. . . . . . . . . . . . . . . . . . . . . .
69
6.5
Meldung von Verkehrsstörungen . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
6.6
Routing
6.5.1
. . . . . . . . . . . . . . . . . . . . . . . .
71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
Hintergrundaktualisierung . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
6.7
Anzeige erkannter Problemstellen . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
6.8
Einstellungen
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
6.9
Online-Hilfe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
6.6.1
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Visualisierung und Interaktion
Weiterführende Überlegungen, Ausblick und Fazit
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
7.1
Probleme
7.2
Vergleich mit proprietären Systemen
7.3
Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
7.4
Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
. . . . . . . . . . . . . . . . . . . . . . . . .
77
78
Kapitel 1
Einleitung
Mit der stetig zunehmenden Anzahl von Kraftfahrzeugen, allein in 2011 ein Zuwachs von 700000
[SBD11], steigt auch die Häugkeit von Staus, Unfällen und weiteren Behinderungen des Verkehrsusses. Aus diesem Grund werden Dienste notwendig, die die Verkehrsteilnehmer über die
aktuelle Situation informieren.
Die Entwicklung in diesem Bereich begann mit den Staumeldungen im Radio, die zumeist auf
Informationen von Polizei, Automobilclubs oder menschlichen Staumeldern beruhten. Die erste
Weiterentwicklung dieses Konzeptes ist das
Trac Message Channel System (TMC),
welches
die Informationen im nicht hörbaren Frequenzbereich des UKW-Signals sendet, so dass diese
von Navigationsgeräten empfangen, interpretiert und zur Berechnung von alternativen Routen
verwendet werden können. Allerdings werden über TMC fast nur Meldungen für Autobahnen und
Bundesstraÿen übertragen, während Landstraÿen und Innenstädte komplett auÿen vor bleiben.
Des Weiteren hat sich gezeigt, dass die Quellen und der Übertragungsweg zu langsam und zu
fehleranfällig sind und somit ein Stau oder Unfall oftmals schon nicht mehr existiert wenn die
Meldung ausgestrahlt wird [BIT11].
Mit der Verbreitung des mobilen Internets haben diverse Unternehmen damit begonnen, Systeme zu entwickeln, die Verkehrsinformationen in Echtzeit erfassen und dem Nutzer zur Verfügung
stellen. Vorreiter auf diesem Weg waren TomTom und Vodafone, die mit
TomTom HD Trac
als Erste einen Dienst vorgestellt haben, der die bestehende Infrastruktur des Mobilfunknetzes nutzt [Wik11b]. Dieser erfasst die Bewegungsinformationen von in Fahrzeugen mitgeführten
Mobiltelefonen, erstellt daraus Verkehrsprole und übermittelt diese wiederum an alle mit dem
Internet verbundenen TomTom Navigationsgeräte.
Ein ähnlicher Ansatz wird inzwischen auch von einigen Autoherstellern, wie Audi und BMW,
aufgegrien um die integrierten Navigationssysteme mit aktuellen Informationen zu versorgen.
Allerdings ist die Erfassung von Verkehrsdaten nur ein Teil dieses
Floating Car Data (FCD)
genannten Modells. Bei BMW wird auÿerdem noch auf weitere Assistenzsysteme wie Antiblockiersystem, Antriebsschlupfregelung oder Regensensoren zugegrien. Das Endgerät im Fahrzeug
sammelt alle diese Informationen und wertet sie aus. Wird beispielsweise anhand der Werte von
1
2
KAPITEL 1. EINLEITUNG
ABS und dem Electronic Stability Program erkannt, dass an einer passierten Stelle Glatteis sein
könnte, werden diese Daten ebenfalls an die zugehörige FCD-Zentrale übermittelt. Dort werden
die ankommenden Informationen nochmals überprüft und gegebenenfalls eine Warnmeldung an
+
alle anderen FCD-Teilnehmer für die entsprechende Position gesendet [L 03].
Seit Sommer 2011 ist es auch bei Google Maps möglich, Informationen über die aktuelle Verkehrslage in Deutschland zu erhalten. Google protiert dabei von der Verbreitung der Google
Maps-Applikation für mobile Endgeräte und der Nutzung dieser Anwendung als kostenlose Navigationssoftware. Sobald ihr Start erfolgt ist, sendet sie Informationen über Position, Richtung
und Geschwindigkeit des Nutzers an die Server von Google, welche die eingehenden Daten zur
Berechnung des Verkehrsoverlays, sowie des Routings nutzen.
Abbildung 1.1:
Google Maps mit aktiviertem Verkehrsoverlay
1.1 Motivation
Bei Ausgabe dieser Arbeit gab es auf dem Markt nur die Angebote von Navteq und TomTom/Vodafone im Bereich der Ermittlung von Echtzeitverkehrsinformationen für Kraftfahrzeuge. Beide
Systeme sind jedoch anwendungsgebunden und erreichen somit nur eine relativ geringe Anzahl
Nutzer, die helfen können, die Datenbasis zu verbessern.
An diesem Punkt soll diese Arbeit ansetzen: Sie soll zum einen möglichst viele Android-Nutzer
direkt erreichen und zum anderen den Entwicklern von mobilen Betriebssystemen, wie Apples iOS
oder Symbian, Schnittstellen anbieten, um ähnliche Applikationen auf der jeweiligen Plattform
mit dem gesamten System verbinden zu können. Die Nutzer erfassen dabei mit ihren Smartphones
automatisiert ihre gefahrene Geschwindigkeit, können aber auch zusätzliche Informationen zu
vorliegenden Verkehrsproblemen an einen zentralen Server schicken und somit allen anderen
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
1.2. ZIELSETZUNG
3
Anwendern zukommen lassen.
Sehr bekannte Beispiele dafür, dass Anwendungen mit ausschlieÿlich nutzergeneriertem Inhalten
funktionieren, sind die Wikipedia oder auch das OpenStreetMap-Projekt. Die Nutzer kontrollieren sich dabei gegenseitig und stellen ihre gesammelten Daten der Allgemeinheit zur Verfügung.
Ein aktuelles Projekt, welches zeigt, dass es auch möglich ist innerhalb kürzester Zeit eine breite
Anzahl Nutzer für einen speziellen Themenbereich zu gewinnen, ist Wheelmap.org. Dort werden
Karten mit rollstuhlgerechten Orten erstellt, deren Rollstuhltauglichkeit mit einem Ampelsystem
gekennzeichnet ist [whe11].
1.2 Zielsetzung
Ziel dieser Masterarbeit ist die Bereitstellung eines Systems, das dem Nutzer Echtzeitverkehrsdaten, sowie Informationen über das Vorliegen von Staus oder anderen Behinderungen zur Verfügung stellt und es ihm ebenfalls ermöglicht, seine gesammelten Daten den anderen Teilnehmern zu
übermitteln. Neben diesem Informationsdienst soll auch noch ein Interface geschaen werden,
welches die Planung von Routen erlaubt, die um bereits bekannte Problemstellen herumführen.
Bei einer Umsetzung kommt es nun darauf an, dem Nutzer eine klar strukturierte Oberäche zur
Verfügung zu stellen, die ihm im normalen Betriebsmodus während der Fahrt nicht ablenkt und
trotzdem alle Informationen vermittelt. Bei diesen ausgelieferten Daten handelt es sich um Angaben zur Auslastung der einzelnen Straÿenabschnitte, Meldungen über vorliegende Störungen,
die Geschwindigkeitsbegrenzung - sofern bekannt - und die approximierte Geschwindigkeit der
anderen Verkehrsteilnehmer. Da für den letztgenannten Wert nicht immer aktuelle Messungen
vorliegen, muss auch noch der Ermittlungszeitraum angezeigt werden um den Nutzer über die
Qualität der vorliegenden Daten aufzuklären.
Neben der reinen Visualisierung vorhandener Daten, soll der Anwender auch die Möglichkeit
bekommen andere Verkehrsteilnehmer vor vorhandenen Problemen zu warnen. Da eine solche
Interaktion mit dem Smartphone während der Fahrt in Deutschland verboten ist, muss die
Anwendung die Möglichkeit bieten, Meldungen auch noch zu einem späteren Zeitpunkt unter
Angabe der Position der Verkehrsbehinderung zu übermitteln [Mar11].
Ein weiterer wichtiger Punkt ist die Navigations-Komponente. Sie soll eine möglichst einfache
Erstellung von Routen erlauben, aber gleichzeitig auch einen Groÿteil des Komforts einer kommerziellen Navigationssoftware bieten. Hierunter fallen die Eingabe von Adressen, die Suche eines
Ziels auf der Karte oder auch das Umstrukturieren einer vorhandenen Route.
Um nun die Idee eines Systems umzusetzen, das auf eine Datenbasis aus nutzergenerierten Inhalten zurückgreifen kann, müssen Daten wie Position, Geschwindigkeit und Bewegungsrichtung
der Anwender gespeichert werden. Allerdings soll ein Augenmerk bei der Implementation darauf
liegen, dass keine komplexen Bewegungsprole der Anwender erstellt werden können. Auÿerdem
soll noch die Möglichkeit bestehen, dass die Anwendung auch ohne serverseitige Speicherung der
ortsbezogenen Daten genutzt werden kann.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
4
KAPITEL 1. EINLEITUNG
Diese Überlegungen sind notwendig geworden, da es in der Vergangenheit immer wieder Anwendungen mit Problemen in diesem Bereich gab und ein heimliches Erfassen der Standort-Daten
eines Smartphones einen Eingri in die Privatsphäre des Nutzers darstellt, der mit dem deutschen Datenschutz nicht vereinbar ist. So setzt beispielsweise Apple seit 2008 das iPhone als
Umgebungsscanner ein, um Daten über WLAN-Netzwerke und Mobilfunkmasten zu sammeln
und könnte somit ein Bewegungsprol, wie in Abbildung 1.2 gezeigt, erzeugen.
Abbildung 1.2:
von einem iPhone gespeichertes Bewegungsprol [Ste11]
Ein weiterer Punkt, der allerdings nicht direkt die Implementation betrit, liegt in der Lizensierung. Da die erstellte Applikation unter einer Open-Source-Lizenz veröentlicht werden soll,
unterliegt sie gewissen Einschränkungen die verwendeten Bibliotheken betreend. So muss sichergestellt sein, dass diese ebenfalls unter Open-Source-Lizenzen stehen, welche wiederum auch
untereinander kompatibel sind.
1.3 Aufbau der Arbeit
Zu Beginn der Arbeit werden die allgemeinen Grundlagen der erstellten Software vorgestellt.
Hierbei gibt es zum einen die serverseitig verwendeten Komponenten, wie das Datenbank-Managementsystem PostgreSQL mit der Erweiterung PostGIS und zum anderen das SmartphoneBetriebssystem Android von Google mit seinen diversen Bestandteilen. Auÿerdem wird zum
besseren Verständnis der nachfolgenden Kapitel eine kurze Einführung in kartographische Grundbegrie gegeben.
Im anschlieÿenden Kapitel werden dann externe Frameworks und Webservices vorgestellt, auf
deren Dienste von Client oder Server zurückgegrien wird. Hierbei liegt der Fokus besonders auf
den Karten- und Routingdiensten von OpenStreetMap und CloudMade. Des Weiteren erfolgt
eine kurze Übersicht über die Arbeitsweise der ORM-Bibliothek Hibernate.
In Kapitel 4 wird dann zuerst ein allgemeiner Überblick über das Zusammenspiel der einzelnen
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
1.3. AUFBAU DER ARBEIT
5
Komponenten in der entstandenen Software gegeben, bevor in den folgenden Kapiteln Planung
und Implementation detailliert vorgestellt werden. Beim Server liegt dabei das Hauptaugenmerk
auf den verschiedenen Analyse- und Aufbereitungsprozessen der Daten, während clientseitig die
Visualisierung der Informationen und die Benutzerinteraktion im Fokus stehen.
In den letzten beiden Kapiteln erfolgt dann ein Vergleich mit bereits bestehender Software von
Google und Navteq. Auÿerdem soll sowohl eine Bewertung solcher Echtzeitsysteme für die Verkehrsanalyse im Allgemeinen, als auch der im Rahmen dieser Arbeit entstandenen Applikation
im Speziellen vorgenommen werden. Der abschlieÿende Ausblick dient dazu, mögliche Erweiterungen für
TracJamDroid
aufzuzeigen und sie hinsichtlich ihrer Umsetzbarkeit und Integration
in die bestehende Software zu analysieren.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 2
Grundlagen
In diesem Kapitel soll kurz auf die grundlegenden Komponenten und Begriichkeiten eingegangen werden, die bei der Umsetzung dieser Arbeit zum Einsatz gekommen sind. Neben dem
verwendeten Datenbank-Managementsystem PostgreSQL und der zugehörigen Erweiterung für
geographische Objekte und Funktionen PostGIS sind dies das Android OS und einige Begrie
aus dem Umfeld von Kartograe und Geoinformationssystemen.
2.1 PostgreSQL
Datenbank-Managementsysteme werden immer dann eingesetzt, wenn groÿe Datenmengen zu
verwalten sind und sich die vorhandenen Informationen häug ändern.
Bei PostgreSQL handelt es sich um ein Open-Source-Datenbank-Managementsystem, das unter
der
PostgreSQL License
veröentlicht ist und aktuell in fünf stabilen Versionen verfügbar ist. Ur-
sprünglich entwickelt wurde es als Forschungsprototyp unter dem Namen Postgres von der Berkeley Universität in Kalifornien im Jahr 1986. Nachdem 1995 allerdings die interne Abfragesprache
durch einen SQL-Dialekt ersetzt wurde, erfolgte die Umbenennung in PostgreSQL [Pos11].
Aufgrund konstanter Weiterentwicklung unterstützt es mittlerweile die SQL92- und SQL99Standards und ermöglicht referentielle Integrität, Transaktionsmanagement, sowie Stored Procedures und Trigger.
2.1.1
PostGIS
Normalerweise können in Datenbanken nur atomare Daten abgelegt werden. Um auch komplexere, geographische Objekte speichern zu können, ist ein Hilfsmodul erforderlich.
PostGIS wurde von Refractions Research Inc. als Forschungsprojekt für raumbezogene DatenbankTechnologien entwickelt und erweitert das objekt-relationale Datenbank-Managementsystem PostgreSQL um geographische Funktionen und Objekte. Auÿerdem folgt PostGIS im Gegensatz zu
7
8
KAPITEL 2. GRUNDLAGEN
den Implementation von MySQL oder Oracle der
SQL
OpenGIS Simple Feature Specication For
[Ope99] und bietet damit die Möglichkeit in der Datenbank Punkte, Linien, Polygone und
andere vektororientierte Daten wie Multilinien, Multipolygone und geometrische Sammlungen zu
speichern. Somit kann der Datenbank-Server in Verbindung mit einem
Geoinformationssystem
genutzt werden.
Die Speicherung der Geometrien erfolgt innerhalb einer PostgreSQL-Datenbank im
Binary (WKB)
Well-Known
Format in einer für Geoinformationen reservierten Tabelle, deren Einträge dann
durch PostGIS mit der eigentlichen Datenbank-Struktur verbunden werden. Neben dem binären
Datenformat WKB, welches vom Open Geospatial Consortium extra standardisiert wurde um
Geodaten in einer Datenbank abzulegen, gibt es noch die Möglichkeit das
(WKT)
Well-Known Text
Format zu nutzen. Dieses dient aber lediglich zur Verbesserung der Lesbarkeit eines
Datensatzes und sollte nicht zur Speicherung verwendet werden.
-- WKT Repräsentation eines Punktes
POINT (8.0000116 52.4779105)
-- WKT Repräsentation eines Straÿenabschnittes
LINESTRING (8.0577672 52.2957632 ,8.056455 52.2971603 ,8.0562393
52.2974051 ,8.0557423 52.2978854 ,8.0556342 52.2980611)
Listing 2.1:
WKT-Repräsentation geographischer Objekte
Neben der reinen Persistierung von geographischen Informationen stellt PostGIS auch noch eine
Vielzahl von Funktionen zur Verfügung. Diese ermöglichen es beispielsweise Abstände und Überschneidungen zwischen zwei Geometrien durch Funktionsaufrufe innerhalb einer SQL-Anfrage zu
berechnen.
SELECT * FROM roadstrips
WHERE ST_DWithin ( way , GeometryFromText ( ' POINT (8.0000116 52.4779105) ' ,
4326) , 2.2 E -4)
ORDER BY ST_DISTANCE ( way , GeometryFromText ( ' POINT (8.0000116
52.4779105) ' , 4326) ) ASC
LIMIT 1
Listing 2.2:
SQL-Abfrage mit PostGIS-Funktionalität
roadstrips nach Entitäten sucht, die zu
2.2E-4 Grad (ca. 15 Meter) heben. Es sortiert
Listing 2.2 zeigt eine SQL-Abfrage, die in der Tabelle
einem gegebenen Punkt maximal die Entfernung
die Ergebnisliste anschlieÿend aufsteigend nach ihrem Abstand und liefert den ersten Datensatz
zurück. Somit ist das Ergebnis dieser Abfrage die nächstliegende Entität aus
roadstrips zu dem
gegebenen Punkt.
Aufgrund des Einsatzes von Hibernate als objektrelationaler Mapper und der Verwendung des
Aufsatzes Hibernate Spatial müssen im Java-Code keine SQL-Anfragen für geometrische Objekte
formuliert werden. Da im Hintergrund allerdings sehr wohl SQL für die Kommunikation mit der
Datenbank verwendet wird, ist obige Anfrage das SQL-Äquivalent für das in Listing 3.4 gezeigte
Beispiel.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.2. KARTOGRAPHISCHE GRUNDBEGRIFFE
9
Da räumliche Abfragen im Vergleich zu herkömmlichem SQL sehr komplex sind, bietet es sich an
Indizes zu verwenden, um den Zugri auf die entsprechenden Spalten zu optimieren. Allerdings
sind die bereits vorhandenen Indextypen nicht mit Binärdaten kompatibel und müssen ersetzt
werden. Die hierfür benötigte Funktionalität liefert ebenfalls PostGIS: den Generalized Search
Tree (GiST). Dieser hat zwar eine ähnliche Struktur wie ein B-Baum mit Schlüssel-Wert-Paaren,
allerdings handelt es sich bei den Schlüsseln nicht um reine Integer-Werte, sondern um fest
denierte Klassen wie zum Beispiel
Geometry
[GIS11].
-- GIST - Index auf die Spalte way in der Tabelle roadstrips
CREATE INDEX idx_strip_way ON data . roadstrips USING gist ( way
GIST_GEOMETRY_OPS )
Listing 2.3:
Indizierung einer Spalte
Obwohl durch das Anlegen von Indizes immer ein Overhead entsteht, werden innerhalb der
Serverimplementation alle Spalten mit geometrischen Werten mit einem solchen versehen. Dieser
Einsatz ist dabei das Ergebnis der Abwägung zwischen zusätzlicher Belastung des Basissystems
und einem Geschwindigkeitszugewinn in der Abarbeitung der SQL-Anfragen.
2.2 Kartographische Grundbegrie
Da im Rahmen dieser Arbeit einige Begrie aus dem Umfeld von Kartographie, Fernerkundung
und Geoinformationssystemen verwendet werden, soll an dieser Stelle eine eindeutige Terminologie geschaen und die entsprechenden Ausdrücke erläutert werden.
geographischen Koordinaten, beziehungsweise
Geokoordinaten. Diese bestehen in der Regel aus zwei Werten: der geographischen Länge und
der geographischen Breite. Vereinzelt wird auch noch die Höhe als dritte Gröÿe verwendet. Zusammen mit dem Spatial Reference System Identier (SRID) kennzeichnen sie eine eindeutige
Der häugste Begri in diesem Bereich ist der der
Position auf der Erdoberäche, wobei der SRID notwendig ist, um das Basissystem der Koordinaten bestimmen zu können und gegebenenfalls zwischen verschiedenen Systemen Umrechnungen
vorzunehmen. Da Android OS das
World Geodetic System 1984 (WGS 84)
als Referenzsystem
verwendet, muss auch die serverseitige Datenbank die gleichen Einstellungen haben und die zugehörige SRID 4326 einsetzen.
Die Verwendung von WGS84 bedeutet, dass die Werte für die Geokoordinaten auf Basis eines
Gradnetzes festgelegt werden, welches sich über die gesamte Erdoberäche erstreckt. Die geographische Breite kann dabei Werte von 90 Grad am Nordpol über 0 Grad am Äquator bis zu
90 Grad am Südpol annehmen. Bei den ganzzahligen, erdumlaufenden Kreisen mit konstanter
Breitengraden.
Längengrade, die
geographischer Breite spricht man auch von
Diese haben jeweils einen Abstand
von etwa 111 Kilometern zueinander. Die
keinen konstanten Abstand haben,
sind Groÿreise, die sich jeweils in Nord- und Südpol schneiden. Des Weiteren reicht der Wertebereich der geographischen Länge von 0 Grad, dem Groÿkreis durch den Londoner Stadtteil
Greenwich, bis zu 180 Grad östlicher beziehungsweise westlicher Länge. Die Werte werden dabei
mit einem positiven (Ost) oder negativen (West) Vorzeichen versehen. Um die Bereiche zwischen
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
10
KAPITEL 2. GRUNDLAGEN
den ganzzahligen Längen- und Breitengraden genauer zu beschreiben, sind diese gleichmäÿig in
60 Unterabschnitte, die sogenannten Minuten, unterteilt. Diese sind wiederum ebenfalls in 60
weitere Abschnitte, die Sekunden, aufgeteilt und erreichen somit eine Genauigkeit von etwa 31
◦ 16' 44 Nord, 8◦ 2' 35 Ost.
Metern. Die Repräsentation von Osnabrück wäre beispielsweise: 52
Da aber im Rahmen dieser Ausarbeitung eine höhere Genauigkeit für die Angabe von Positionen
benötigt wird, kommen noch zwei weitere Darstellungen zum Einsatz: Zum einen als Gleitkom-
◦
◦
mazahl (52.278889 , 8.043056 ) und zum anderen als natürliche Zahl (52278889, 8043056). Diese
beiden, um den Faktor eine Million verschiedenen, Werte ermöglichen es nun, eine zentimetergenaue Aussage über eine Position auf der Erdoberäche zu treen. Allerdings erlauben sie keine
Unterscheidung ob diese im Osten oder Westen beziehungsweise im Norden oder Süden ist. Aus
diesem Grund werden die Werte für die südliche Breite und die westliche Länge in negierter Form
angegeben und verwendet.
Ein weiterer wichtiger Begri ist
Georeferenzierung
oder auch
Geocoding.
Er bezeichnet den
Vorgang der Konvertierung von Adressen (z.B. Albrechtstraÿe, Osnabrück) in geographische
Koordinaten (z.B. geographische Breite 52.283689 und geographische Länge 8.026603). Der Umkehrprozess, also die Umwandlung einer Geokoordinate in eine lesbare Adresse, wird als
kehrte Geocodierung
oder
Reverse Geocoding
umge-
bezeichnet.
2.3 Android
Android ist ein Betriebssystem für mobile Endgeräte und seit November 2007 das Hauptprojekt
der
Open Handset Alliance (OHA).
Diese ist ein Zusammenschluss von aktuell etwa 80 Firmen,
die gröÿtenteils aus der IT- und Mobilfunkbranche stammen und es sich zum Ziel gesetzt haben
oene Standards für Smartphones zu entwickeln. Initiator und treibende Kraft ist dabei Google.
Die Open Handset Alliance deniert Android wie folgt:
Android is a software stack for mobile devices that includes an operating system, middleware
and key applications. [And11a]
Im Oktober 2008 wurde mit dem HTC Dream das erste Smartphone mit Android OS zum Verkauf
angeboten: Zunächst allerdings nur in Verbindung mit einem T-Mobile Vertrag. Seit 2009 ist
es aber auch ohne SIM-Lock erhältlich. Inzwischen gibt es weitere Geräte von verschiedenen
Herstellern, darunter Samsung und Motorola, im Handel [Wik11a].
Die Open Handset Alliance arbeitet seit ihrer Gründung kontinuierlich an einer Weiterentwicklung des Betriebssystems, welches aktuell in der Version 4.0 zur Verfügung steht. Der Groÿteil
der aktuell im Umlauf bendlichen Smartphones läuft laut [And11c] allerdings noch mit den
Versionen 2.2 und 2.3, was zum einen damit zusammenhängt, dass die Hersteller zumeist noch
Zusatzfunktionen auf das Basissystem aufsetzen und eine Verzögerung der Updates in Kauf nehmen. Zum anderen hängt dieser scheinbar groÿe Versionsunterschied aber auch damit zusammen,
dass die Version 4.0 eine Zusammenführung der Entwicklungspfade für Smartphones (2.X) und
Tablets (3.X) darstellt.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.3. ANDROID
11
Android ist momentan das sich am schnellsten verbreitende Betriebssystem für Smartphones auf
der Welt. Laut [PT11] stieg der Marktanteil von 3,9% im Jahr 2009 auf über 17% in 2010 an.
Auÿerdem wird erwartet, dass die Anzahl der täglichen Aktivierungen von Androidgeräten noch
im Oktober 2011 die Marke von einer Million übersteigt [Deg11].
2.1:
Samsungs
Galaxy Nexus mit Android 4.0
Abbildung
2.3.1
Abbildung 2.2:
Android System Architektur
Systemarchitektur
In der Systemarchitektur von Android lassen sich fünf Hauptkomponenten identizieren: der
Linux Kernel, die Bibliotheken, die Laufzeitumgebung, das Anwendungsgerüst und die Anwendungen selbst.
Linux Kernel: Die Basis für das Android Betriebssystem bildet ein Linux Kernel der Reihe 2.6.
Er beinhaltet die Gerätetreiber und übernimmt die Energie-, Speicher- und Prozessverwaltung. Auÿerdem dient er als Abstraktionsschicht zwischen der Hard- und der Software.
Bibliotheken: Android beinhaltet eine Reihe von C/C++-Bibliotheken, die von verschiedenen
Komponenten genutzt werden. Diese werden darüber hinaus auch den Entwicklern durch
das Anwendungsgerüst zur Verfügung gestellt.
Laufzeitumgebung: Neben den Kernbibliotheken, welche die meisten Funktionen zur Verfü-
gung stellen, die auch im normalem Java Development Kit zu nden sind, gehört auch
die
Dalvik Virtual Machine (DVM)
zur Android-Laufzeitumgebung. Sie wurde mit dem
Ziel entwickelt auf einem Gerät mehrere virtuelle Maschinen ezient parallel ausführen
zu können und benötigt ein spezielles Dateiformat. Dieses ist vergleichbar mit den jarArchiven herkömmlicher Java-Anwendungen, verfügt jedoch über Optimierungen für einen
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
12
KAPITEL 2. GRUNDLAGEN
minimalen Speicherverbrauch.
Anwendungsgerüst: Aufbauend auf der Android Runtime und den mitgelieferten Bibliotheken
bendet sich die eigentliche Basis von Android: das Application Framework. Neben den
Objekten für die graphische Oberäche gehören hierzu auch die Klassen zur Verwaltung
von Daten, Nutzung der Hardware und zur Kommunikation mit anderen Geräten.
Anwendungen: Die oberste Schicht der Architektur bilden die Anwendungen. Dazu gehören
sowohl die Standardprogramme wie Browser oder Telefon, aber auch Software von Drittanbietern.
2.3.2
Software Development Kit
Das Android Software Development Kit bietet Entwicklern die Möglichkeit, eigene Anwendungen für Android OS zu erstellen. Es wurde 2008 erstmals veröentlicht und steht aktuell für
Windows, Linux und Mac OS zur Verfügung. Als oziell unterstützte Entwicklungsplattform
dient Eclipse, für welche ein Plugin zur Entwicklung (Android Development Tools) bereitgestellt
wird. Auÿerdem beinhaltet das SDK einen Emulator, den Dalvik Debug Monitor Service, sowie
Tutorials und eine umfassende Dokumentation.
Die etwa 1500 Klassen sind zu einem Teil in den Core Libraries und zum anderen im Application
Framework zu nden. Zu den Kernbibliotheken, welche den gröÿten Teil abdecken, gehören die
aus dem Java Development Kit von Oracle/Sun verwendeten Klassen. Dabei sind bis auf die
graphischen Bestandteile von Swing und AWT nahezu alle bekannten Datentypen und Funktionalitäten vorhanden. Der plattformspezische Teil im Application Framework beinhaltet dagegen
die Grundklassen für alle Android-Komponenten, sowie Pakete für die Unterstützung der
Script Object Notation (JSON)
2.3.3
Java-
und von JUnit.
Permissions
Eine zentrale Rolle bei der Entwicklung von Android stellt die Sicherheit dar. So hat eine Applikation zunächst keinen Zugri auf andere Anwendungen, das System oder Hardwarekomponenten.
An dieser Stelle setzen die Permissions an. Sie werden im Manifest der Applikation deniert und
können so Freigaben bestimmter Komponenten anfordern.
Systemseitig bietet Android dabei etwa 100 Permissions an, die den Zugri auf Hardwarekomponenten, Daten und Standardfunktionalität regeln. Versucht eine Anwendung nun ohne die notwendigen Berechtigungen auf eine dieser Funktionen zuzugreifen, so wird eine
SecurityException
geworfen und das Programm beendet. Genauso verhält es sich mit selbstdenierten Permissions,
welche dazu dienen, anderen Anwendungen Teile der eigenen Implementation zur Verfügung zu
stellen und ebenfalls im Manifest deniert werden.
Auf welche Permissions eine Anwendung zugreifen möchte, wird dem Benutzer vor der Installation, beziehungsweise bereits im Android-Market angezeigt. Nun muss dieser entscheiden, ob
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.3. ANDROID
13
er die beantragten Berechtigungen erteilen oder lieber auf eine Installation verzichten möchte. Sobald jedoch die Anwendung auf dem Client installiert ist, können die Permissions nicht
mehr zurückgezogen werden und nur eine Deinstallation kann eventuell entstandene Probleme
beheben.
2.3.4
Views
Die Gestaltung von graphischen Oberächen erfolgt in Android mit Hilfe von XML-Dateien
oder in gewissem Maÿe auch direkt in den Activites. Die XML-Dateien werden im RessourcenVerzeichnis
layout abgelegt und beinhalten eine Schachtelung verschiedener GUI-Komponenten.
Das Wurzelelement dieses Baumes repräsentiert dabei immer die gesamte zur Verfügung stehende
Fläche und muss für diese zuerst ein Layout denieren. Dieses kann dann Komponenten zur
Anzeige, wie Buttons oder Textfelder, aufnehmen oder weiter aufgeteilt werden. Die Kinder
unterliegen dabei immer den Vorgaben der umschlieÿenden Elemente, können aber individuelle
Angaben zu Form, Farbe und Gröÿe besitzen.
Die Gröÿenangaben einer View sind zwingend erforderlich und folgen zumeist relativ zum jeweiligen Eltern-Element. Wird beispielsweise die Höhe mit
android:layout_height=fill_parent
angegeben, so beansprucht die Komponente die gesamte Höhe des umschlieÿenden Elementes.
Wird anstatt
fill_parent
jedoch
wrap_content
verwendet, so wird für die View nur die Höhe
beansprucht, die notwendig ist um den gesamten Inhalt darzustellen.
2.3.5
Activities
Eine Activity ist das Herzstück einer Anwendung. Sie stellt die Benutzeroberäche zur Verfügung, reagiert auf Eingaben des Anwenders und steuert den Ablauf des gesamten Programmes.
Dabei wird der Lebenszyklus einer Activity von verschiedenen auftretenden Ereignissen, die den
aktuellen Status verändern, beeinusst. So schiebt zum Beispiel ein Druck auf den Home-Button
oder ein eingehender Anruf die bisher im Vordergrund bendliche Activity in den Hintergrund,
beendet sie aber nicht.
Auf Abbildung 2.3 ist zu erkennen, dass eine Activity drei Methoden durchläuft, bevor sie im
Zustand Running und damit für den Benutzer sichtbar ist:
Die
onCreate-Methode
onCreate, onStart
und
onResume.
wird immer dann aufgerufen, wenn eine Activity zum ersten Mal aufge-
rufen wird und somit noch noch keinen Speicher belegt. Sie dient dazu Layouts und Ressourcen
einzubinden und Zugrie auf andere View-Komponenten zu initialisieren. Nachdem dann der
Code von
onStart
und
onResume
ausgeführt wurde, läuft die Activity.
Wenn jetzt beispielsweise ein Anruf ankommt, das heiÿt wenn eine andere Activity in den Vordergrund kommt, wird automatisch die Callback-Methode
onPause
aufgerufen und die Activity
in den Hintergrund geschoben. Allerdings verbleibt sie weiterhin im Speicher und sorgt so dafür,
dass alle bereits initialisierten Variablen ihre Werte beibehalten. Wenn jetzt die Anruf-Activity
abgeschlossen ist, kehrt die eigene Activity wieder in den Vordergrund zurück und die Methode
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
14
KAPITEL 2. GRUNDLAGEN
Abbildung 2.3:
onResume
Der Lebenszyklus einer Activity aus [And11a]
wird ausgeführt. Wird die Activity dagegen mittels des im Gerät verbauten Zurück-
Button beendet, werden nacheinander
onPause, onStop
und
onDestroy
aufgerufen.
Ist die eigene Activity nur nicht mehr sichtbar, was beispielsweise durch einen Druck des HomeButtons ausgelöst werden kann, wurde sie dadurch gestoppt, aber nicht zerstört. In diesem Fall
kann sie entweder von Android beendet werden, wenn der Speicher benötigt wird, oder aber
erneut aufgerufen werden und mittels
onStart
wieder in den Vordergrund geholt werden.
Die vorgestellten Methoden müssen bei der Implementation jedoch nicht zwangsläug alle ausprogrammiert werden. Es ist lediglich erforderlich, dass die Activity von
abgeleitet ist und, dass die Methode
onCreate
android.app.Activity
implementiert ist.
startActivity ( new Intent ( this , RoutingActivity . class ) ) ;
this . finish () ;
Listing 2.4:
Starten und Beenden einer Activity
Um innerhalb einer Applikation zwischen verschiedenen Activities zu wechseln, werden sogenannte Intents benötigt. Ein Intent ist hierbei ein abstraktes Objekt, das an das System gesendet wird
und Informationen darüber enthält, welche Activity als nächstes gestartet werden soll. Somit
zeigt obiger Beispielcode die einfachste Form um in die
RoutingActivity
zu wechseln, welche
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.3. ANDROID
15
auf dem Activity-Stack abgelegt wird und es dem Nutzer ermöglicht nach ihrer Beendigung oder
der Betätigung des Zurück-Buttons des Gerätes wieder zur aufrufenden Activity zu gelangen.
Mit dem Aufruf von
this.finish()
wird die aktuelle Activity komplett beendet,
onDestroy
aufgerufen und dem Garbage-Collector mitgeteilt, dass er die zurückgebliebenen Daten abräumen
kann. Der Aufruf von
finish
hat allerdings noch den Nebeneekt, dass die Funktionalität des
Zurück-Buttons auf dem Android-Gerät eingeschränkt wird, und es nun nicht mehr möglich ist
zum letzten Stand der zerstörten Activity zurückzukehren.
2.3.6
Services, Handler und Asynchrone Tasks
Beim Starten der ersten Komponente einer Applikation erzeugt Android lediglich einen einzigen
Ausführungsthread für diese, den
main
oder
UI-Thread.
Es ist aber auch möglich, Teile der
Anwendung in andere Prozesse auszulagern um Ressourcen zu sparen und um zu verhindern,
dass der Nutzer eine sogenannte
application not responding
Meldung erhält. Diese kann dann
auftreten, wenn das Smartphone so stark mit Rechenoperationen belastet ist, dass es nicht mehr
auf Nutzerinteraktionen reagieren kann und als Konsequenz daraus den Bildschirm einfriert und
versucht die Applikation zu beenden.
Eine Möglichkeit der Auslagerung sind die Services. Im Gegensatz zu den Activities verfügen
sie über keine eigene Benutzeroberäche und laufen im Hintergrund. Sie sollen zur Entlastung
der Activities bei leistungsintensiven Operationen dienen, laufen allerdings in der Regel genau
wie der Rest der Applikation im UI-Thread, so dass die Gefahr besteht, dass die Anwendung
blockiert wird. Um dies zu verhindern, kann im Manifest das Attribut
android:process gesetzt
werden. Wird hier ein Name angegeben, so erhält der Service einen eigenen Prozess auf den dann
von auÿen zugegrien werden kann.
Abbildung 2.4 zeigt die beiden, von der Art des Aufrufs abhängigen, Lebenszyklen eines Services.
Der linke Pfad wird dabei durchlaufen, wenn der Service mit
startService(Intent)
gestartet
wird. Allerdings ist in diesem Fall kein Datenaustausch zwischen Service und aufrufenden Komponente möglich und somit läuft der Prozess bis er sein Ende erreicht hat oder von auÿen gestoppt
wird.
Um nun Zugri auf die vom Service gesammelten Informationen zu erhalten, wird eine Schnittstelle benötigt. Android stellt hierfür die
Binder-Objekte zur Verfügung, welche über die onBind-
Methode des Service von anderen Komponenten geholt werden können und eine Möglichkeit der
Kommunikation für die verschiedenen Prozesse bieten. Nach Abschluss der Transaktion lässt sich
mit
unbindService
diese Verbindung wieder lösen und wenn keine weiteren Clients registriert
sind, wird der Service automatisch beendet.
Eine weitere Möglichkeit um Nebenläugkeit zu erreichen, stellen Threads dar. Sollen sie aber
unter Android Zugri auf Komponenten der graphischen Oberäche erhalten, dürfen sie nicht in
der Java-üblichen Form verwendet werden. Wird ein Thread als innere Klasse implementiert und
gestartet, so verstöÿt dies gegen das
single-threaded model
für die Benutzerschnittstelle und kann
zu undeniertem Verhalten führen. Um dies zu verhindern, stellt Android drei verschiedene Methoden zum Starten eines neuen Threads zur Verfügung:
Activity.runOnUiThread(Runnable),
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
16
KAPITEL 2. GRUNDLAGEN
Abbildung 2.4:
Der Lebenszyklus eines Services aus [And11a]
View.post(Runnable) und View.postDelayed(Runnable, long). Auÿerdem gibt es noch einen
Callback-Mechanismus, der auf einem Handler beruht, der es dem Thread ermöglicht, mit dem
eigentlichen Programmcode zu kommunizieren.
Als best practice für aufwendige Hintergrundoperationen, die mit dem UI kommunizieren müs-
AsyncTask abgeleitet
doInBackground
Überschreiben von onPreExecute,
sen, haben sich die Asynchronen Tasks erwiesen [And11b]. Sie werden von
und müssen mindestens die in einem separaten Thread ausgeführte Methode
implementieren. Auÿerdem besteht die Möglichkeit durch
onPostExecute
und
onProgressUpdate
threadsicheren Zugri auf Ressourcen der graphischen
Oberäche zu erlangen. Da den Asynchronen Tasks im Rahmen dieser Arbeit eine zentrale Rolle
in der Kommunikation zwischen Client und Server zukommt, werden sie im Kapitel 6.3 noch
genauer behandelt.
2.3.7
Ressourcen
Innerhalb einer Anwendung werden viele statische Daten, wie Layouts, Graphiken oder feste Zeichenketten verwendet. Alle diese Komponenten werden unter Android zu den Ressourcen einer
Drawable enthält dabei
layout werden die XML-Dateien der bereits vorgestellten Views
values bendet sich beispielsweise die strings.xml. In dieser
Applikation gezählt und jeweils in einem speziellen Verzeichnis abgelegt.
sämtliche Multimediadateien, in
gespeichert und im Verzeichnis
Datei sind einfache Zeichenketten hinterlegt, die aus Gründen der Übersichtlichkeit aus dem eigentlich Programmcode herausgehalten und nur noch durch die Verwendung einer Referenz eingebunden werden. Auÿerdem wird so eine einfache Möglichkeit geschaen Programmoberächen
in verschiedenen Sprachen zu unterstützen. So würde ein Gerät, welches als Standardeinstellung
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.3. ANDROID
17
die deutsche Sprache verwendet, zuerst nach dem Ordner
values-de
suchen und die dort hin-
terlegten Dateien verwenden. Ist der entsprechende Ordner oder der gesuchte Wert jedoch nicht
vorhanden , wird auf den Standardordner
values
Des Weiteren wird vom Compiler die Datei
zurückgegrien.
gen/R.java erzeugt. Diese enthält für jede Ressource
eine eindeutige ID, welche es wiederum ermöglicht, die zugehörigen Objekte mittels der bereitgestellten API-Methoden in die Implementation einzubinden. Der Zugri erfolgt dabei über den
Kontext der Anwendung, der über die Methode
getResources
ein Objekt mit allen Ressourcen
der Applikation zur Verfügung stellt.
2.3.8
Menüs
Unter Android werden zwei Arten von Menüs unterschieden. Zum einen gibt es das Optionsmenü,
welches das Hauptmenü einer Applikation darstellt und zum anderen besteht die Möglichkeit für
einzelne Komponenten ein Kontextmenü zu erstellen.
Listing 2.5 zeigt die Denition eines Optionsmenüs mit fünf verschiedenen Einträgen, die jeweils
eine ID, einen Titel und ein Symbol zur Anzeige besitzen. Diese XML-Datei wird im RessourcenVerzeichnis
menu
abgelegt und mit Hilfe der Klasse
MenuInflater
mit einer Activity verknüpft.
Ein solches Optionsmenüs wird dabei mittels der im Gerät verbauten Menü-Taste aufgerufen und
am unteren Bildschirmrand eingeblendet. Da dies allerdings nicht ausreicht um auf Nutzerinteraktion zu reagieren, muss in der zugehörigen Activity noch ein Überschreiben der Methode
onOptionsItemSelected(MenuItem)
erfolgen.
<? xml version = " 1.0 " encoding = " utf -8 " ? >
< menu xmlns:android = " http: // schemas . android . com / apk / res / android " >
< item android:id = " @ + id / menu_jam " android:title = " @string / jam "
android:icon = " @drawable / ic_menu_jam " / >
< item android:id = " @ + id / menu_route " android:title = " @string / route "
android:icon = " @drawable / ic_menu_route " / >
< item android:id = " @ + id / menu_problems " android:title =
" @string / problems " android:icon = " @drawable / ic_menu_block " / >
< item android:id = " @ + id / menu_prefs " android:title = " @string / prefs "
android:icon = " @drawable / ic_menu_manage " / >
< item android:id = " @ + id / menu_help " android:title = " @string / help "
android:icon = " @drawable / ic_menu_help " / >
</ menu >
Listing 2.5:
Android Menü-Beispiel
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
18
KAPITEL 2. GRUNDLAGEN
Das Kontextmenü dagegen ist nicht mit der gesamten Activity verknüpft, sondern kann an jede einzelne View-Komponente gebunden werden. Diese muss sich dafür allerdings zuerst durch
Aufruf der Methode
registerForContextMenu(View) bei der zugehörigen Activity anmelden
onCreateContextMenu erstellte Menü anbie-
und kann dann bei einem langen Klick das in
ten. Die Reaktion auf eine Nutzerinteraktion erfolgt dabei analog zum Optionsmenü in der
onContextItemSelected-Methode
2.3.9
der Activity.
Datenhaltung
Um Daten persistent zu speichern bietet Android drei unterschiedliche Möglichkeiten, welche
sich in Programmieraufwand und Art stark voneinander abgrenzen.
Zuerst seien hier die Shared Preferences genannt, welche die einfachste Art der Datenhaltung
darstellen und auch nur für sehr einfache Strukturen (Schlüssel-Wert-Paare) nutzbar sind. Sie
werden vom System verwaltet und ermöglichen eine Bearbeitung, ohne dass sich der Entwickler
um die eigentliche Speicherung kümmern muss. In erster Linie dienen sie aber zur Vorhaltung
von nutzer- oder anwendungsspezischen Einstellungen und unterstützen nur die primitiven Datentypen und Strings.
Lesenden Zugri auf die gespeicherten Daten erhält man entweder über den Kontext der An-
getSharedPreferences(String, int) oder mit Hilfe der Klasse
der Methode getDefaultSharedPreferences(Context). Das zurück-
wendung mit der Methode
PreferenceManager
und
gelieferte Objekt stellt dann für alle möglichen Datentypen get-Methoden zur Verfügung und
liefert auf Angabe des Schlüssel den zugehörigen Wert. Des Weiteren bieten die Methoden die
Möglichkeit Standardwerte anzugeben, um somit sicherstellen zu können, dass Variablen auch
dann korrekt initialisiert werden, wenn ein Schlüssel nicht gefunden werden kann.
Um Änderungen an den Daten der Shared Preferences vorzunehmen, muss der zugehörige Editor
verwendet werden. Dieser stellt nun analog zu den Gettern put-Methoden für die verschiedenen Datentypen bereit und kann auÿerdem komplette Einträge löschen. Zum abschlieÿenden
Festschreiben der Änderungen muss die Methode
commit
aufgerufen werden.
Auÿerdem bieten die Preferences UI-Komponenten an, die es dem Entwickler ermöglichen auf
einfache Weise eine Benutzeroberäche zu erstellen, auf der die Einstellungen bearbeitet werden
können. Dies wird aber später bei der Vorstellung der Implementation des Clients noch genauer
betrachtet.
Die nächstkomplexere Möglichkeit der Datenhaltung stellt das Speichern von Dateien im Dateisystem dar. So ist es möglich jeglichen Dateityp im System anzulegen, zu schreiben und wieder
auszulesen. Auch die SD-Karte, sofern vorhanden, kann zur Speicherung von Dateien genutzt
werden. Da sich die Vorgehensweise zur Arbeit mit Dateien unter Android nicht wesentlich von
der Vorgehensweise im normalem Java unterscheidet und im Rahmen dieser Arbeit auch nur
eine untergeordnete Rolle spielt, soll an dieser Stelle auf eine ausführliche Vorstellung verzichtet
werden.
Neben Shared Preferences und Files unterstützt Android, ebenso wie das iPhone, die Speicherung
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
2.3. ANDROID
19
von Daten in einer SQLite-Datenbank. Hierbei handelt es sich um ein kompaktes, freies und
relationales Datenbanksystem, das fast alle Funktionen komplexerer Systeme (umfangreiche SQLSyntax, Transaktionen, etc.) unterstützt. Auÿerdem ist es für den Einsatz in mobilen Endgeräten
hervorragend geeignet, da das gesamte System nur ein Minimum an Speicher, zumeist zwischen
150kB und 250kB, belegt. Auch benötigt es keine Installation auf den Clients und ermöglicht
es somit komplette Datenbanken zwischen verschiedenen Systemen problemlos auszutauschen
[SQL11].
Um nun mit einer solchen Datenbank-Datei arbeiten zu können, wird eine Verwaltungsklasse deniert, welche von
android.database.sqlite.SQLiteOpenHelper
abgeleitet ist und als
Datenbank-Manager bezeichnet wird. Dieser muss mindestens drei Parameter kennen: den Namen der Datenbank, die aktuelle Version des Datenbankschemas und den Anwendungskontext
des Eigentümers. Die ersten beiden Werte werden dabei zumeist als Konstanten implementiert,
während der aktuelle Kontext beim Erzeugen des Datenbank-Managers von auÿen mitgegeben
werden muss.
Da allerdings innerhalb der im Rahmen dieser Ausarbeitung erstellten Anwendung mehrere parallele Datenbanken zum Einsatz kommen, muss ein abweichendes Konzept verwendet werden.
So wird erst zur Laufzeit entschieden welche Datenbank für die aktuelle Anfrage verwendet werden muss und mittels der Methode
SQLiteDatabase
openOrCreateDatabase(File, CursorFactory)
der Klasse
in den Speicher geladen. Eine genauere Erläuterung erfolgt aber noch bei der
Betrachtung des Clients (siehe Kapitel 6.4.3).
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 3
Frameworks
In diesem Kapitel soll auf einige externe Dienste und Open-Source-Bibliotheken eingegangen werden, die bei der Umsetzung dieser Arbeit verwendet werden. Während Hibernate und CloudMade
dabei aber nur serverseitig zum Einsatz kommen, nden sich OpenStreetMap-Komponenten auch
auf dem Android-Smartphone wieder.
3.1 Hibernate
Hibernate ist ein Framework, das objektorientierten Zugri auf die Daten einer Datenbank bietet.
Dieser Vorgang wird auch als
Object-Relational-Mapping (ORM)
bezeichnet.
object-relational mapping is the automated (and transparent) persistence of objects in a Java
application to the tables in a relational database, using metadata that describes the mapping
between the objects and the database [BK04]
Das Hibernate-Projekt wurde 2001 von Gavin King gegründet und bis zum Jahre 2003 als nichtkommerzielles Open-Source-Projekt geführt (siehe [BK04]). Seit diesem Zeitpunkt ist es unter
kommerziellem Aspekt Teil der JBoss-Incorporation, ist aber selbst weiterhin kostenlos erhältlich
und darf in eigenen (auch kommerziellen) Projekten frei verwendet werden. Es steht unter der
Lesser GNU Public License (LGPL)
und ist aktuell in der Version 3.6.5 erhältlich.
Das Mapping zwischen Java-Objekten und der relationalen Datenbank geschieht wahlweise mittels einer XML-Datei oder per Java-Annotations. In Listing 3.1 ist ein beispielhafter Auszug
aus einem Mapping für die Klasse
tribut
id,
Road
zu sehen. Hibernate verlangt für alle Klassen ein At-
dass datenbankseitig als Primärschlüssel verwendet wird. Neben den Informationen
wie der Primärschlüssel erzeugt werden soll, im Listing generiert eine Sequenz die Werte, enthält die XML-Datei mit den Mappinginformationen alle Attribute einer Klasse, die persistiert
werden sollen. Dabei ist es nicht erforderlich explizit einen Datentyp anzugeben, da Hibernate
diese Informationen direkt aus dem Java-Quellcode ableiten kann. Neben dem reinen Abbilden
von Attributen werden auch Beziehungen, wie beispielsweise Vererbung oder Assoziationen, zwi-
21
22
KAPITEL 3. FRAMEWORKS
Road eine 1:N-Beziehung
Set mit allen abhängigen
schen den Klassen unterstützt. In Listing 3.1 sieht man, dass die Klasse
mit der Klasse
RoadStrip
hat und eine Entität der Klasse
Road
ein
Entitäten enthält.
< hibernate - mapping package = " org . traffic . models . traffic " >
< class name = " Road " table = " roads " >
< id name = " id " column = " id " >
< generator class = " sequence " >
< param name = " sequence " > routes_id_seq </ param >
</ generator >
</ id >
< property name = " name " / >
< property name = " highway " / >
< property name = " maxspeed " type = " integer " / >
< set name = " strips " inverse = " false " cascade = " all " >
< key column = " road_id " / >
<one - to - many class = " RoadStrip " / >
</ set >
</ class >
</ hibernate - mapping >
Listing 3.1:
Mapping der Klase Road
Damit Hibernate das objekt-relationale Mapping durchführen kann, werden zusätzlich noch die
sogenannten Java Beans oder
Plain old Java objects (POJOs)
benötigt, welche mindestens über
einen öentlichen Standard-Konstruktor sowie Getter- und Setter-Methoden für alle Attribute
aus dem Mapping verfügen müssen. Da Hibernate aber nicht zusichert, dass die Objekte direkt
mit den korrekten Werten initialisiert werden, muss bei der Implementation der Setter auf jegliche
Gültigkeitsprüfungen verzichtet werden.
Neben dem reinen Mapping bietet Hibernate weitere Funktionalitäten wie die Anbindung an
verschiedenste Datenbanksysteme. Da die verschiedenen Backends sich jedoch häug im verwendeten SQL-Dialekt unterscheiden, wird hierfür eine eigene Anfragesprache zur Verfügung gestellt,
die sogenannte
Hibernate Query Language (HQL).
Sie ist ebenfalls ein Dialekt der Structured
Query Language, wurde allerdings auf eine objektorientierte Basis angepasst. Eine zweite Möglichkeit der Datenbank-Kommunikation bietet
Criteria-API. Mit ihr lassen sich Schritt für Schritt
Ergebnismengen einengen und Queries mit vordenierten Methoden erstellen. Für beide Arten
sind im Folgenden kurze Beispiele gegeben.
Session session = HibernateUtil . getSessionFactory () . getCurrentSession () ;
session . beginTransaction () ;
int deletedClients = session
. createQuery ( " DELETE Client c WHERE c . lease < : date " )
. setDate ( " date " , new Date ( System . currentTimeMillis () ) )
. executeUpdate () ;
session . getTransaction () . commit () ;
Listing 3.2:
Anfrage mit HQL
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
3.1. HIBERNATE
23
Session session = HibernateUtil . getSessionFactory () . getCurrentSession () ;
session . beginTransaction () ;
List < OSMLine > l = ( List < OSMLine >) session
. createCriteria ( OSMLine . class )
. addOrder ( Order . asc ( " name " ) )
. list () ;
session . getTransaction () . commit () ;
Listing 3.3:
Anfrage mit der Criteria-API
Der generelle Ablauf einer durch Hibernate unterstützen Datenbankanwendung ist dabei immer
gleich aufgebaut. Nachdem zuerst die Hibernate Konguration initialisiert wurde, muss eine
SessionFactory
erstellt werden. Diese ist das zentrale Modul für Hibernate und erlaubt das
Instanziieren einer
Session,
welche beim Erstellen automatisch mit der Datenbank verbunden
wird und die Verbindung bis zu ihrer Beendigung aufrechterhält. Des Weiteren werden über die
Sessions Objekte geladen und gespeichert. Allerdings muss dies nicht immer explizit erfolgen, da
Hibernate automatisch Änderungen an die Datenbank weiterreicht oder auch Objekte nachlädt,
falls diese von der Applikation angefordert werden und sich noch nicht im Hauptspeicher benden.
Dieses Konzept ist allgemein als
3.1.1
Lazy Loading
bekannt.
Hibernate Spatial
Hibernate Spatial bietet eine generische Erweiterung für das Datenbank-Framework Hibernate
um die Arbeit mit geographischen Daten zu ermöglichen. Es unterstützt dabei die meisten Funktionen der
OpenGIS Simple Feature Specication For SQL
[Ope99] und kann mit allen groÿen
Datenbank-Managementsystemen verwendet werden.
Um mit Hibernate Spatial arbeiten zu können, muss die entsprechende Bibliothek in das Projekt eingebunden werden. Zusätzlich wird auch noch eine Bibliothek mit den PostGIS-Klassen
benötigt, damit Hibernate ein korrektes Mapping vornehmen kann. Ist dies geschehen, stehen zusätzlich zu den normalen
Restrictions noch die SpatialRestrictions für Datenbankanfragen
zur Verfügung.
com . vividsolutions . jts . geom . Point p = GeomHelper . createPoint ( lon , lat ) ;
RoadStrip rs = ( RoadStrip ) session
. createCriteria ( RoadStrip . class )
. add ( new DWithinExpression ( " way " , p , 2.2 E -4) )
. addOrder ( LocalDistanceOrder . asc ( " distance " , p ) )
. uniqueResult () ;
Listing 3.4:
Verwendung von SpatialRestrictions wie DWithinExpression
In obigen Code-Beispiel wird der nächstliegende
RoadStrips
aus der Datenbank ermittelt, der
innerhalb eines Abstandes von 15 Metern zum Punkt p liegt. Die Klasse
Point
ist dabei Be-
standteil der bereits erwähnten PostGIS-Bibliothek.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
24
KAPITEL 3. FRAMEWORKS
Neben den geographische Funktionen zur Erweiterung der SQL-Anfragen, bietet Hibernate Spatial auch die Möglichkeit in Java-Klassen Attribute zu verwenden, die mit einer Spalte mit geographischen Objekten in der Datenbank verbunden sind. Das folgende Beispiel ist Teil eines solchen
Mappings und zeigt ein Attribut mit dem Bezeichner
way,
welches vom Typ
GeometryUserType
ist. Wird einer Datenbank-Spalte dieser Typ zugewiesen, so kann sie alle Formen von geographischen Objekten im
Well-Known Binary
Format speichern.
< property name = " way " type = " org . hibernatespatial . GeometryUserType " / >
Listing 3.5:
Mapping eines Attributes vom Typ Geometry
3.2 OpenStreetMap
Da Karten und Geodaten eine wichtige Rolle in vielen Anwendungen und Webangeboten spielen,
haben in den letzten Jahren auch einige groÿe IT Firmen, wie Google, Microsoft und Yahoo,
Systeme entwickelt, die den Nutzern Karten, Routingdienste und Points of Interest zur Verfügung
stellen. Man spricht dabei von MapProvidern.
OpenStreetMap (OSM) ist ein freier MapProvider auf Basis von Open-Source-Software. Das
Kartenmaterial wird dabei nach dem Wikipedia-Prinzip von Nutzern zusammengetragen, die
beispielsweise Straÿenverläufe mit einem GPS-Empfänger vermessen und die Koordinatenverläufe in die Datenbank von OpenStreetMap einspeisen. Hierfür stehen auch noch eine Vielzahl
an zustäzlichen Klassikationsmöglichkeiten zur Verfügung, mit denen die einzelnen Abschnitte
genauestens beschrieben werden können. So können bei einer Straÿe neben dem Typ, wie Bundesstraÿe oder Fuÿweg, auch noch Werte für die Geschwindigkeitsbegrenzung oder die Fahrtrichtung
angegeben werden.
(a) OpenStreetMap
Abbildung 3.1:
(b) Google Maps
Karte der Osnabrücker Altstadt
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
3.2. OPENSTREETMAP
25
Da sich immer mehr Menschen bei OSM engagieren, wird das Kartenmaterial stetig genauer
und umfangreicher. Durch die Verteilung der Nutzer ist es allerdings häug so, dass ländliche
Regionen noch nicht sonderlich gut erschlossen sind.
Vergleicht man OpenStreetMap mit Google Maps, so wird deutlich, dass OSM Informationen
enthält, die deutlich über die reine Anzeige einer Straÿenkarte hinausgehen. So enthält Google
Maps zwar auch Informationen über Restaurants, Hotels oder Wohngebiete, bei OSM sind aber in
hochaufgelösten Gebieten sogar einzelne Gebäudeumrisse, Verkehrsampeln oder gar Parkbänke
vermerkt.
Neben der reinen MapProvider-Funktionalität bietet OpenStreetMap zusätzlich die Möglichkeit,
auf die zugrundeliegenden Basisdaten zuzugreifen. Hierfür gibt es neben der API noch das sogenannten
Planet-File.
Dieses enthält alle Informationen, über die OpenStreetMap verfügt und
wird in regelmäÿigen Abständen aktualisiert. Da diese Datei aber sehr umfangreich ist, bietet die
Geofabrik GmbH auch einzelne Ausschnitte zum separaten Download an. Dieser Datenbestand
umfasst dabei Dateien für alle Länder Europas, sowie die einzelnen Bundesländer Deutschlands.
3.2.1
OSMdroid-Bibliothek
Für den bereits vorgestellten MapProvider OpenStreetMap gibt es ein Projekt namens OSMDroid. Dieses stellt Kartenmaterial für Android-Anwendungen zur Verfügung und unterstützt
Zoomen, Scrollen und die Transformation zwischen Geokoordinaten und Bildschirmkoordinaten.
Auÿerdem ist es möglich, Overlays auf der Karte zu erzeugen um somit Objekte und Routen
darzustellen und mit ihnen interagieren zu können.
Generell ist OSMDroid stark an den Aufbau der Google Maps API für Android angelehnt und
hat den gleichen Funktionsumfang mit einer zusätzlichen Unterstützung von Minimaps. Dies
sind kleine Karten in der Karte, die eine Zuordnung der aktuellen Ansicht in ein gröÿeres Umfeld kleineren Maÿstabes vornehmen, um eine Übersicht des gerade angezeigten Ausschnitts zu
schaen.
Abbildung 3.2:
Schematische Darstellung der Android OpenStreetMap API
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
26
KAPITEL 3. FRAMEWORKS
Bei der Implementation der beiden APIs unterscheiden sich lediglich die Paketnamen der Klassen,
so dass bei einem Wechsel nur eine Reorganisation der Imports erfolgen muss. Klassen- und
Funktionsnamen, sowie deren Parameter sind identisch.
OSMDroid kommuniziert direkt mit der OSM API (vgl. Abbildung 3.2), verwendet dabei aber
nicht die Features des
OpenStreetMap Binary Protocol,
welches für den Einsatz auf mobilen
Endgeräten vorgesehen ist. Da man sich von einer diesbezügliche Umstellung einen spürbaren
Performancegewinn verspricht, bendet diese sich zur Zeit in der Entwicklung und soll mit einer
der nächsten Versionen veröentlicht werden.
Aktuell liegt OSMDroid in der Version 3.0.5 aus dem Juli 2011 vor und ist unter der LGPL
veröentlicht.
3.3 CloudMade
Eine Einschränkung bei der Verwendung von OSMDroid ist die fehlende Unterstützung von
Geocoding und Navigation. Diese Funktionen sind aber auch nicht Bestandteil der Google Maps
Bibliothek, sondern müssen immer per Webservice oder mit Hilfe des Android-Frameworks implementiert werden. Allerdings verbietet Google die Nutzung ihrer Dienste in Verbindung mit
einem anderen Kartenmaterial als Google Maps. Aus diesem Grund muss auf freie Dienste wie
CloudMade oder pgRouting zurückgegrien werden.
CloudMade wurde im Jahr 2007 vom OpenStreetMap-Gründer Steve Coast und Nick Black gegründet um Entwicklern Schnittstellen zur Verfügung zu stellen, die den Umgang mit Geodaten
vereinfachen. Seitdem ist eine Vielzahl von Produkten, wie SDKs für das iPhone oder Navigationssoftware, entstanden. Auÿerdem bieten sie
Location Based Advertising
an.
Um die Dienste von CloudMade nutzen zu können, muss sich ein Entwickler kostenlos registrieren
und erhält nach der Anmeldung einen eindeutigen Schlüssel. Falls mehrere verschiedene Anwendungen oder Dienste genutzt werden, können auch mehrere dieser API-Keys parallel verwendet
werden.
Des Weiteren stellt CloudMade auch einige HTTP-APIs bereit, die es unter anderem ermöglichen
Routen berechnen zu lassen oder Ausschnitte der Weltkarte als Graken abzufragen:
http: // navigation . cloudmade . com / KEY / api /0.3/ START ,[ TRANSIT ] , END / TYPE .
FORMAT ? BLOCKED
Listing 3.6:
Routing-Anfrage über die HTTP-API
START, TRANSIT und END handelt es sich um Geokoordinaten, die die Route beschreiben. Mit
TYPE ist es möglich verschiedene Prole für die Fortbewegung zu wählen. CloudMade ermöglicht
dabei Navigation angepasst für Kraftfahrzeuge, Fahrräder und Fuÿgänger. Der Parameter FORMAT
Bei
gibt an, in welchem Dateiformat das Ergebnis ausgeliefert werden soll und unterstützt neben
XML auch noch GPX und JSON. Mit
BLOCKED
können ganze Straÿen oder einzelne Geokoordi-
naten für die Route ausgeschlossen werden. Sofern möglich, wird dies beim Routing berücksich-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
3.3. CLOUDMADE
27
tigt. Andernfalls erhält der Nutzer trotzdem eine Route, wird aber mittels einer Statusnachricht
darüber informiert, dass das Routing nicht wie gewünscht erfolgen konnte.
Ebenfalls über eine HTTP-API bietet CloudMade Dienste für Geocoding und Reverse Geocoding
an:
http: // geocoding . cloudmade . com / KEY / geocoding / v2 / find . TYPE ? query = QUERY
http: // geocoding . cloudmade . com / KEY / geocoding / v2 / find . TYPE ? around = OBJECT &
object_type = OBJECT_TYPE
Listing 3.7:
Geocoding-Anfragen über die HTTP-API
Die erste Anfrage dient zum Geocoding. Mittels
QUERY
kann ein beliebiger Text als Ortsbe-
schreibung angegeben werden und löst diese in Geokoordinaten auf. Die zweite Anfrage geht den
OBJECT steht für eine, aus Breitengrad und Längengrad bestehende, KoordiOBJECT_TYPE kann zusätzlich das Ergebnis noch weiter eingeschränkt werden. So ist es
umgekehrten Weg:
nate.Mit
zum Beispiel möglich nur Restaurant um eine bestimmte Position herum zu ermitteln. Der Platzhalter
TYPE
gibt wieder den Datentyp des Ergebnisses an. Hier kann neben dem textbasierten
Format JSON auch noch HTML gewählt werden, welches eine HTML-Seite mit OpenStreetMapKarte und gesetzten Markern zurückliefert.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 4
Architektur
Wie bereits erwähnt, erfolgt die Umsetzung dieser Arbeit auf Basis einer Client-Server-Architektur,
wo der Server nicht nur die zentrale Stelle zur Datenhaltung ist, sondern auch die rechenintensiven Aufgaben beinhaltet. Die Clients dienen ausschlieÿlich zur automatisierten Erfassung und
zur Information der Nutzer.
Abbildung 4.1:
Systemarchitektur
Wie in Abbildung 4.1 zu sehen ist, kommunizieren die Clients innerhalb der erstellten Applikation
nur mit dem Server. Alle Anfragen an OpenStreetMap oder CloudMade werden von diesem
dann weiter aufbereitet und letztendlich an die entsprechenden Dienste weitergereicht. Auch die
Antworten gehen somit beim Server ein, werden von diesem gespeichert, auf das Wesentliche
reduziert und in einem speziellen Übertragungsformat an den Client zurückgesendet.
29
30
KAPITEL 4. ARCHITEKTUR
4.1 Das Client-Server-Konzept
Bei der Betrachtung der verschiedenen Client-Server-Architekturen lassen sich zwei grundlegende Konzepte unterscheiden: die Zwei-Schichten-Architektur und die Drei-Schichten-Architektur.
Allerdings haben beide System gemein, dass sich die folgenden Aufgabenbereiche identizieren
lassen:
•
Präsentationslogik: Hierunter fällt die Implementation der graphischen Benutzerschnitt-
stelle, sowie jeglicher Programmcode, der für die Aufbereitung der Anwendungsinformationen für die visuelle Darstellung benötigt wird.
•
Anwendungslogik: Die Anwendungslogik regelt die Verbindung von graphischer Ober-
äche zur Datenhaltung. Zu ihr werden allgemein alle Dienste gezählt, die über das reine
Ausliefern von Daten hinausgehen.
•
Datenhaltung: Für die Datenhaltung wird in der Regel ein relationales Datenbankmodell
verwendet, welches mit einem zugehörigen Datenbank-Managementsystem verwaltet wird.
Bei der zwei-Schichten-Architektur ist die Anwendungslogik nicht sonderlich stark ausgeprägt
und komplett Bestandteil des Clients, während der Server kaum über die Funktionalität eines
reinen Datenbank-Servers hinauskommt. Eine solche Umsetzung wirft aber das Problem auf,
dass sämtliche Client-Applikationen refaktorisiert werden müssen, sobald es zu Änderungen an
der Struktur der zugrundeliegenden Tabellen kommt. In der heutigen Zeit, wo Smartphones ihre
Applikationen aus dem App Store oder dem Android Market beziehen und Anwendungen eine
hohe Verfügbarkeit aufweisen müssen, ist ein solcher Prozess jedoch nicht ideal. Auÿerdem kann
es zu Problemen in der Datenintegrität kommen, wenn ein Client falsche oder unvollständige
Werte an den Server schickt und dieser sie direkt in den jeweiligen Tabellen speichert.
Um diese Probleme zu umgehen, wurde die drei-Schichten-Architektur entwickelt. Hier erhält
der Server die Anwendungslogik und kann somit den Clients Schnittstellen zur Verfügung stellen, über welche für jede Ansicht die Daten bereits passend aufbereitet abgefragt werden können.
Es entsteht ein sogenannter
Application-Server. Dieser ermöglicht es auch, dass gänzlich verschie-
dene Clients, wie zum Beispiel iPhones und Android-Geräte, mit ihm über ein fest deniertes
Protokoll kommunizieren können und keinerlei Anpassung erforderlich wird, wenn sich an der
Datenstruktur etwas ändern sollte.
4.2 Kommunikation zwischen den Komponenten
Die Kommunikation zwischen Server und OpenStreetMap beschränkt sich auf den einmaligen
Import der Straÿendaten. Dabei wird mit Hilfe des Konsolen-Programmes
Osm2pgsql
ein kom-
plettes Abbild der OSM-Tabellen in die Datenbank des Servers eingespielt und dort anschlieÿend
für die Nutzung aufbereitet. Eine ausführliche Erläuterung der dafür notwendigen Schritte erfolgt
später in Kapitel 5.1
Obwohl das Routing auf den Clients gestartet wird, erzeugt der Server die endgültige Anfrage
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
4.2. KOMMUNIKATION ZWISCHEN DEN KOMPONENTEN
31
und reicht diese an die bereits vorgestellte HTTP-API von CloudMade weiter. So wird ermöglicht, zusätzliche Parameter, wie bereits bekannte Staus oder Baustellen, bei der Navigation zu
berücksichtigen. Grundsätzlich bietet CloudMade zwar die Möglichkeit automatisiert aktuelle
Verkehrsmeldungen in das Routing mit einzubeziehen, da dieser Dienst aber kostenpichtig ist,
soll im Rahmen dieser Arbeit auf eine Nutzung verzichtet werden.
Die wichtigste Verbindung besteht zwischen dem Server und den Clients. Um die Kommunikation
zwischen ihnen zu ermöglichen, muss zuerst eine eindeutige Schnittstelle deniert werden, welche
sowohl das Datenformat, als auch die Struktur von Anfragen und Antworten festlegt.
Ein weiterer Punkt ist die Beschränkung der zu übertragenden Datenmenge und der benötigten
Zeit auf ein Mindestmaÿ. Da aber die Kommunikation über Java Sockets erfolgt, ist es problemlos
möglich, die zu übertragenden Daten zu komprimieren.
Vorgang
komprimierte Übertragung
normale Übertragung
Zeit - Lesen
13,19ms
7,77ms
Zeit - Schreiben
20,33ms
9,83ms
Datenmenge
882.74byte
5118.93byte
Tabelle 4.1:
Durchschnittliche Werte bei 500 Testmessungen
Tabelle 4.1 zeigt, dass die Datenmenge durch das Komprimieren auf etwa ein Viertel reduziert
werden kann, während sich die Zeit, die für das Lesen beziehungsweise Schreiben benötigt wird
verdoppelt. Da die Abarbeitungszeit einer kompletten Anfrage an den Server allerdings zwischen
zwei und vier Sekunden benötigt, können Änderungen im Millisekundenbereich vernachlässigt
werden.
Der wichtigste Punkt bei der Kommunikation zwischen Client und Server ist die Identikation.
Zwar soll es, wie bereits ausgeführt, nicht möglich sein Bewegungsprole zu erstellen, trotzdem
werden aber eindeutige IDs benötigt um die Fahrtrichtung bestimmen zu können oder um Aktualisierungen für gefahrene Routen zur Verfügung zu stellen (siehe auch Kapitel 5.3.3). Um
dem Client nun diesen Wert zuzuweisen, wird ein Verfahren ähnlich dem vom TCP bekannten
Three-Way-Handshake angewandt. Die Entscheidung für solch ein verbindungsorientiertes Transportprotokoll ist darauf zurückzuführen, dass es bei der Benutzung von Smartphones aufgrund
der nicht ächendeckenden Ausstattung mit mobilem Internet immer wieder zu kurzfristigen
Verbindungsabbrüchen kommen kann und somit nicht sichergestellt ist, dass der Client die ID
auch erhält.
Der Vorgang der eigentlichen ID-Vergabe besteht ebenfalls aus drei Schritten. Zuerst schickt der
Client eine Registrierungs-Anfrage an den Server. Dieser generiert eine eindeutige Identikationsnummer, liefert sie aus und vermerkt intern, dass noch keine Bestätigung vorliegt. Sobald diese
vom Smartphone eingegangen ist, wird die Verbindung aktiviert und mit dieser ID versehene
eingehende Anfragen werden bearbeitet. Damit dieser Austausch nicht vor jeder Anfrage an den
Server notwendig ist, erhalten die IDs eine Lebensdauer von zwölf Stunden. Wird die Anwendung
längerfristig benutzt, erfolgt im Hintergrund eine automatische Aktualisierung.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
32
KAPITEL 4. ARCHITEKTUR
Somit könnten serverseitig zwar Bewegungsprole für einen Zeitraum von maximal zwölf Stunden
erstellt werden, da es aber keinerlei Verknüpfung zwischen der vergebenen Identikationsnummer
und dem Client gibt, wären diese jedoch keinem Anwender zuzuordnen.
4.2.1
Protokoll
Eine weitere Möglichkeit um die zu übertragende Datenmenge gering zu halten, ist die Verwendung der
JavaScript Object Notation, kurz JSON. Diese bietet die gleichen strukturellen MögXML, benötigt allerdings nicht den Overhead eines Tag-basierten
lichkeiten wie beispielsweise
Markups.
{
}
" data " : {
" lon " : 8.3873534 ,
" lat " : 52.3285769 ,
" time " : 1319916078759 ,
" save " : true ,
" speed " : 0 ,
" bbox " : 2
},
" meta " : {
" id " : " 3 b5fdf2d441d910a46fa3ccc2ea4bec " ,
" type " :2
}
Listing 4.1:
Client-Anfrage zur Aktualisierung der Daten
JSON erlaubt das Serialisieren von komplexen Objekten, Zahlen, Zeichenketten, Wahrheitswerten, dem Wert Null, sowie Arrays der aufgezählten Typen. Ein JSON-Objekt besteht dabei
immer aus dem Tupel
{name : value},
wobei der Name immer durch einen String ausgedrückt
wird und innerhalb eines Objektes eindeutig sein muss. Der Wert kann dagegen aus allen zur
Verfügung stehenden Datentypen gebildet werden und es ist sogar möglich, beliebig viele Objekte
rekursiv ineinander zu fügen. Die serialisierte Form dieser Objekte ist dabei sehr einfach gehalten
und auch vom Menschen gut lesbar.
Ein Beispiel für die Serialisierung einer Aktualisierungs-Anfrage an den Server ist in Abbildung
4.1 dargestellt und besteht aus den JSON-Objekten
data und meta. Während innerhalb des meta-
Objektes immer die allgemeinen Informationen, wie Anfragetyp und ID des Clients, übermittelt
werden, kann der Inhalt von
data
variieren und ist abhängig vom angegebenen Typ.
Entwickelt wurde JSON ursprünglich für die Programmiersprache JavaScript. Es existieren inzwischen jedoch Bibliotheken für nahezu alle gebräuchlichen Programmiersprachen und Android
bietet sogar native Unterstützung an.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 5
Server
Der Server besteht aus zwei groÿen Komponenten: Zum einen ist dies die PostgreSQL-Datenbank
zur Persistierung der Daten und zum anderen ist es der eigentliche Serverdienst, welcher die
Anfragen der Clients entgegennimmt, verarbeitet und beantwortet.
Das Datenbank-Backend dient als zentrale Sammelstelle aller Informationen. Dort sind sowohl
die von OpenStreetMap importierten Straÿen, als auch die Störungsmeldungen und Geschwindigkeitsinformationen der Clients hinterlegt. Der Serverdienst kommuniziert mit dieser Datenbank
über den objektrelationalen Mapper Hibernate und kann somit intern Java-Objekte verwenden,
ohne dass diese erst aus den Ergebnissen der SQL-Anfragen erzeugt werden müssen.
Des Weiteren stellt der Dienst einige Schnittstellen für die Kommunikation mit den Clients
zur Verfügung. Diese
Request-Handler
sind jeweils für einen speziellen Anfragetyp beim Server
registriert und werden aktiv, sobald eine solche Anfrage entgegengenommen wird. Auÿerdem
gibt es noch einige
Services,
die in regelmäÿigen Abständen laufen. Beide Komponenten haben
dabei die Möglichkeit über bereitgestellte Interfaces mit OpenStreetMap und Cloudmade zu
kommunizieren.
Abbildung 5.1:
Serverarchitektur
33
34
KAPITEL 5. SERVER
5.1 Vorbereitung der Datenbasis
Um Berechnungen auf Basis von Straÿeninformationen durchführen zu können, ist es notwendig die Koordinaten der einzelnen Streckenzüge vorliegen zu haben. Diese Informationen sind
Bestandteil von OpenStreetMap und können mit Hilfe des Programmes
Osm2pgsql
abgefragt
und in eine eigene Datenbank importiert werden [osm11]. Allerdings umfassen diese Daten nicht
nur Straÿen, sondern auch alle anderen Objekte, die mit einem
LineString
beschrieben werden
können. Das können beispielsweise Häuser, Wälder oder Flüsse sein.
Da im Rahmen dieser Arbeit aber nur Straÿen benötigt werden, muss im ersten Schritt eine
Filterung der relevanten Daten erfolgen. Dies geschieht durch die Überprüfung des
highway-
Attributes. Enthält dieses einen von Null verschiedenen Wert, so handelt es sich um eine Straÿe
des angegebenen Typs.
(a) Straÿenabschnitte aus OpenStreetMap
(b) Zusammenfassen der Abschnitte
(c) neue Unterteilung der Abschnitte
(d) Anzeige mit Daten
Abbildung 5.2:
Schritte zur Erstellung der Datenbasis am Beispiel der Römereschstraÿe
Abbildung 5.2(a) zeigt die Römereschstraÿe in Osnabrück, die in den importierten OpenStreetMap-Daten in sechs Abschnitte unterteilt ist, welche sich in einem oder mehreren ihrer Attribute
unterscheiden. So gibt es hier zwei Abschnitte, die Brücken über den Hafen beziehungsweise
die Hase beschreiben und einen, der als Verbindung zu einer Bundesstraÿe gekennzeichnet ist.
Allerdings haben alle den Wert
secondary
in ihrem
highway-Attribut,
welcher Land-, oder sehr
gut ausgebaute Kreisstraÿen identiziert.
Um einem Nutzer die Möglichkeit zu geben auf vorliegende Probleme zu reagieren, soll im Rah-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.1. VORBEREITUNG DER DATENBASIS
35
men der erstellten Applikation eine Unterteilung der Straÿenzüge anhand von Kreuzungen vorgenommen werden. Somit ist es dem Fahrer selbst überlassen, ob er auf die Meldung, dass auf
dem nächsten zu befahrenden Abschnitt Verkehrsprobleme vorliegen, durch das Nutzen einer
anderen Straÿe reagieren möchte.
Zur Erreichung dieser neuen Aufteilung muss eine mehrschrittige Aufbereitung der vorhandenen Datensätze erfolgen. Wie Abbildung 5.2(b) zeigt, müssen dafür zuerst die einzelnen Abschnitte zu einem Straÿenzug zusammengefasst werden. Dies geschieht mit Hilfe der PostGISFunktionen
ST_Union und ST_LineMerge. ST_Union funktioniert dabei ähnlich wie herkömmliche
SQL-Aggregatfunktionen und vereint mehrere gruppierte Datensätze. Da es allerdings auf geograhischen Objekten arbeitet, stellt sich der Vorgang etwas komplizierter dar als beispielsweise
bei einer
max-Funktion
aus SQL.
Im hier vorliegenden Fall enthält jeder Datensatz aus OpenStreetMap im Attribut
LineString.
way
einen
Werden nun mehrere dieser Objekte zusammengefasst, entsteht ein neues geogra-
phisches Objekt: ein
MultiLineString,
der eine Sammlung der einzelnen Objekte, vergleichbar
mit einer Collection in Java, darstellt. Wird auf diesen die Funktion
ST_LineMerge
angewendet,
so werden die Einträge miteinander verbunden, die über Schnittstellen untereinander verfügen.
SELECT name , highway , maxspeed , ST_LineMerge ( ST_Union ( way ) )
FROM planet_osm_line
GROUP BY name , highway , maxspeed
Listing 5.1:
SQL-Kommando zum Zusammenführen der Straÿenabschnitte
Listing 5.1 zeigt, dass das Zusammenfassen der einzelnen Datensätze nicht nur anhand des Straÿennamens erfolgt, sondern dass auch die Geschwindigkeitsbegrenzung und die Art der Straÿe
berücksichtigt werden. Diese zusätzliche Unterscheidung ermöglicht es, dem Nutzer später auch
korrekt die maximal erlaubte Geschwindigkeit anzuzeigen und diese innerhalb eines einzelnen
Abschnittes nicht wechseln zu müssen.
Da viele Straÿennamen jedoch mehrfach vorkommen, ist es nicht immer möglich, dass die Funktion
ST_LineMerge
LineString als Ergebnis liefert. In einem solchen Fall
MultiLineString, der eine Vielzahl an Abschnitten beinhaltet, die über
nur einen einzigen
entsteht wiederum ein
keinerlei Schnittmenge untereinander verfügen. Hier muss dann nochmals eine programmatische
Unterteilung in einzelne Datensätze erfolgen.
Die nun in der Tabelle
osmlines vorliegenden Daten haben alle die in Abbildung 5.2(b) gezeigte
Form und können jetzt anhand der Schnittstellen mit anderen Straÿen in einzelne Abschnitte
unterteilt werden. Da für eine solche Berechnung ein geographischer Vergleich eines jeden Datensatzes mit allen anderen erfolgen muss, wird dies mit einem Java-Programm gelöst, das über
die einzelnen Einträge iteriert und somit die Last auf dem Datenbankserver etwas verteilt.
Zuerst erfolgt die Ermittlung aller Schnittstellen der gerade betrachteten Straÿe mit anderen
Straÿen. Die PostGIS-Funktionen
ST_Crosses
und
ST_Touches
dienen dabei zur Selektion von
Datensätzen, die überhaupt über einen Berührungspunkt mit der aktuellen Straÿe verfügen. In
der Projektion erfolgt dann die Ermittlung dieses Punktes durch die Funktion
ST_Intersection.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
36
KAPITEL 5. SERVER
Für den Fall, dass sich dieselben Straÿen mehrfach kreuzen und der Schnitt somit ein
ist, unterteilt
ST_Dump
Die auf diesem Weg errechneten Punkte werden anschlieÿend verwendet, um den
Attribut
MultiPoint
diesen in einzelne Datensätze der Ergebnismenge.
LineString im
way zu unterteilen. Die Funktion ST_Split, die seit der aktuellsten Version von PostGIS
zum Funktionsumfang zählt, ermöglicht dies und stellt eine Menge zur Verfügung, die nun die
beiden einzelnen Teilstücke beinhaltet, welche dann für die weiteren Iterationen in die Tabelle
osmlines
zurückgeschrieben werden.
Nach Abschluss des Aufteilungsvorgangs benden sich im Attribut
des Typs
MultiLineString.
way
geographische Objekte
Da mit diesen aber eine spätere Arbeit nicht möglich ist, erfolgt
ST_Dump und die Speicherung in der endgültigen Taroads_split (siehe auch Abbildung 5.2(c)), welche im Produktivsystem mittels Hibernate
noch eine erneute Trennung mit Hilfe von
belle
angesprochen wird.
Dass Hibernate bei der Vorbereitung der Datenbasis noch nicht zum Einsatz kommt, ist darin
begründet, dass der Speicherverbrauch bei einem Kreuzprodukt von circa 100.000 Datensätzen
allein für Niedersachsen viel zu groÿ würde und die Verarbeitungszeit somit unnötig hoch wäre.
Statement st = connection . createStatement () ;
ResultSet rs = st . executeQuery ( " SELECT id FROM osmlines " ) ;
while ( rs . next () ) {
int id = rs . getInt (1) ;
Statement stCut = connection . createStatement () ;
ResultSet rsCut = stCut . executeQuery (
" SELECT ST_AsText (( ST_Dump ( ST_Intersection ( o . way , c . way ) ) )
. geom ) FROM osmlines o , osmlines c
WHERE o . id = " + id + "
AND ( ST_Crosses ( o . way , c . way ) or
ST_Touches ( o . way , c . way ) ) " ) ;
while ( rsCut . next () ) {
String point = rsCut . getString (1) ;
Statement stSplit = connection . createStatement () ;
stSplit . execute ( " UPDATE osmlines SET way =
ST_CollectionExtract ( ST_Split ( way , ST_GeomFromEWKT (
' SRID =4326; " + point + " ') ) ,2) WHERE id = " + id ) ;
}
Statement stSave = connection . createStatement () ;
stSave . execute ( " INSERT INTO roads_split ( road_id , way )
SELECT id , ( ST_Dump ( way ) ) . geom
FROM osmlines WHERE id = " + id ) ;
}
Listing 5.2:
Aufteilen der Straÿen in einzelne Abschnitte
Das endgültige Erscheinungsbild der Straÿenabschnitte, wie in Abbildung 5.2(d) dargestellt,
wird später clientseitig aus den übermittelten Informationen zu Geschwindigkeitsbegrenzung
und bekannter Durchschnittsgeschwindigkeit erzeugt. Das Farbspektrum reicht dabei von Grün
(ideale Geschwindigkeit) über Gelb (zäh ieÿender Verkehr) bis Rot (Stau).
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.1. VORBEREITUNG DER DATENBASIS
5.1.1
37
Erstellen von Bibliotheken für die Clients
Um eine Visualisierung auf den Smartphones zu ermöglichen, müssen diese neben den Geschwindigkeitswerten auch noch die Koordinaten erhalten, die zur Beschreibung der einzelnen Abschnitte notwendig sind und als
LineString
in der Datenbank vorgehalten werden.
Geht man von einer Aktualisierungsrate von circa 30 Sekunden auf den Clients aus und würde
jeweils die Daten für den aktuell befahrenen und alle benachbarten Abschnitte übertragen, käme
pro Stunde etwa ein Datenvolumen von einem Megabyte zusammen, wovon der gröÿten Teil
durch die Übertragung der Koordinaten anfallen würde, da diese jeweils aus zwei Werten vom
Datentyp Double bestehen.
Das eigentlich Problem besteht aber nicht in der Datenmenge selbst, sondern in der benötigten
Übertragungszeit. Da die Anwendung auch in Regionen nutzbar sein soll, die nur
Rates for GSM Evolution (EDGE)
Enhanced Data
als Datenübertragungsrate in GSM-Mobilfunknetze ermögli-
chen, muss die Übertragungszeit und damit auch die Datenmenge minimal sein. Grundsätzlich
sind mit EDGE zwar Übertragungsraten von 220 kbit/s im Download und 110 kbit/s im Upload
zu erreichen, da aber neben den Serveranfragen auch die anzuzeigenden Karten geladen werden
müssen und weitere Programme des Nutzers Hintergrundaktualisierungen durchführen, steht nur
selten die komplette Bandbreite zur Verfügung.
Bei Tests mit dem beschriebenen Konzept werden im Durchschnitt drei Sekunden für die Übertragung der Antwort des Servers benötigt. Mit Verbindungsaufbau, Senden der Anfrage und der
serverseitigen Bearbeitung kann somit schnell eine Gesamtdauer von zehn Sekunden für eine
Aktualisierung entstehen.
Um diesem Problem zu begegnen, werden SQLite-Bibliotheken erstellt, die jeweils Informationen
über die Straÿenverläufe in einem bestimmten Kartenbereich enthalten. Die Aufteilung erfolgt
dabei anhand von Längen- und Breitengraden, sodass eine Bibliothek die Daten für eine Fläche von einem halben Grad im Quadrat zur Verfügung stellt. Für Niedersachsen ergibt das 48
Dateien, die jede mit der südwestlichsten Koordinate bezeichnet ist. Für Osnabrück mit dem Ko-
◦
◦
ordinatenpaar [8.043056 , 52.278889 ] wäre dies beispielsweise die Datenbank mit dem Namen
08005200.db.
Diese Datenbanken werden in komprimierter Form auf einem Fileserver zur Verfügung gestellt
und haben eine Gröÿe zwischen 400 Kilobyte und einem Megabyte. Sie werden vom Client bei Bedarf nachgeladen oder können vorher auf der SD-Karte gespeichert werden. Somit ist es möglich
zuhause über eine Breitbandverbindung die notwendigen Daten auf das Smartphone zu kopieren
und bei einem mobilen Einsatz müssen nur noch die Informationen zu den Geschwindigkeiten
in den einzelnen Abschnitten, sowie deren ID übertragen werden. Clientseitig werden dann die
Geokoordinaten aus der SQLite-Datenbank geladen und die Straÿensegmente erzeugt (siehe auch
Kapitel 6.4).
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
38
KAPITEL 5. SERVER
5.1.2
Probleme bei der Verarbeitung der OpenStreetMap-Daten
Bei der Vorbereitung der Datenbasis mit den vorgestellten Methoden, kommt es zu einigen Problemen mit dem originalen Datenbestand von OpenStreetMap. Dies liegt zum einen am Umfang
von mehr als 500.000 Datensätzen und zum anderen an der Vielzahl von Null-Werten in den
Attributen
name
und
maxspeed.
Dem groÿen Volumen kann relativ einfach durch einem leistungsstarken Datenbankserver begegnet werden. Die Null-Werte stellen jedoch ein weitaus gröÿeres Problem dar und sind dafür
verantwortlich, dass der in Listing 5.1 gezeigte SQL-Befehl bei der Gruppierung der Datensätze
ohne Wert im
name-Attribut
an seine Grenzen stöÿt. Die circa 280.000 Einträge für Niedersach-
sen müssen somit in einem Extraschritt in kleinere geographische Bereiche unterteilt werden. Für
diese kann dann eine erste Zusammenfassung erfolgen, deren Ergebnisse mit der abschlieÿenden
Gruppierung in den endgültigen Zustand für die Anwendung überführt werden.
Die Null-Werte im Attribut
maxspeed haben zwar keine direkte Auswirkung auf die Vorbereitung
der Datenbasis, allerdings erschwert das Fehlen dieser Werte später die korrekte Visualisierung
auf den Clients und macht es notwendig, dass der Server versucht diese Daten aus den erfassten
Nutzerinformationen zu generieren. Dies geschieht mit den im Kapitel 5.3 vorgestellten Jobs.
5.1.3
Datenbankdesign
Neben den importierten Straÿendaten werden vom Server auch eigene Daten generiert. Da aber
im Betrieb nicht direkt auf die Datenbank zugegrien, sondern immer nur mit den von Hibernate
bereitgestellten Java-Objekten gearbeitet wird, soll in diesem Abschnitt nur auf deren Struktur
näher eingegangen werden.
Die Klasse
Client
dient zur Identikation eines angemeldeten mobilen Gerätes und speichert
neben dem Hashwert, der zur Identikation dient, auch noch die Gültigkeitsdauer dieses Wertes.
Des Weiteren ist im Attribut
ack
der aktuelle Status des
Three-Way-Handshakes
vermerkt. Ist
dieser noch nicht abgeschlossen, so werden alle eingehenden Anfragen durch den Server abgewiesen und es ist nicht möglich eine Route zu erstellen.
Um den Anwendern eine Navigation zu ermöglichen, welche um stark ausgelastete Straÿen und
andere Verkehrsstörungen herumführt, wird die Klasse
und
Route
verwendet. Die Attribute
route
started speichern dabei die Informationen über den Straÿenverlauf und den Startzeitpunkt
updated handelt es sich um ein Flag, welches von einem Dienst des Servers
des Routings. Bei
gesetzt wird, falls er festgestellt hat, dass sich der Verlauf des Routings aufgrund von neu erfassten
Verkehrsproblemen verändert hat (siehe auch Abschnitt 5.3.3).
In der Klasse
Road
werden die Informationen gespeichert, nach denen die Gruppierung der
OpenStreetMap-Daten erfolgt ist. Ein Objekt dieser Klasse verfügt wiederum über einen oder
mehrere
RoadStrips, welche die einzelnen Abschnitte darstellen, für die später die Visualisierung
der Geschwindigkeiten auf den Clients vorgenommen wird. Um dabei sowohl Fahrtrichtung als
auch verschiedene Aktualitätsstufen vorhalten zu können, werden bis zu drei Instanzen der Klas-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.1. VORBEREITUNG DER DATENBASIS
Abbildung 5.3:
sen
SpeedToStart
und
SpeedToEnd
39
Diagramm der Modelklassen
verwendet. Wie die Namen schon andeuten, unterscheiden
die beiden Klassen die Fahrtrichtung, für die eine Geschwindigkeit gemessen wurde. So dient
SpeedToEnd
als Wrapper für alle Werte, bei denen eine Bewegung vom Beginn zum Ende inner-
way-Attribut des zugehörigen Straÿenabschnittes erfolgte.
SpeedToStart ist die Richtung folglich umgekehrt. Das Attribut category gibt die Aktualität
halb des geographischen Objektes im
Bei
der berechneten Geschwindigkeitswerte an und wird in drei Stufen unterschieden:
1. Liegen Daten für diesen Abschnitt vor, die innerhalb der letzten Stunde erfasst wurden, so
gelten diese als sehr genau und werden mit der höchsten Qualitätsstufe gekennzeichnet.
2. Gibt es Daten, die am gleichen Wochentag innerhalb eines identischen Zeitfensters gespeichert wurden, erhalten diese die zweithöchste Qualitätsstufe. So bekommt man beispielsweise an einem Montag zwischen sieben und acht Uhr einen Wert angezeigt, der auf Basis
von Messungen der vergangenen Montage aus diesem Zeitraum berechnet wurde.
3. Bei der dritten und somit schlechtesten Stufe, erfolgt die Berechnung der möglichen Geschwindigkeit für einen Abschnitt auf Basis von allen vorliegenden Werten. Der Erfassungszeitraum ndet hier keine Berücksichtigung.
Neben den errechneten Durchschnittsgeschwindigkeiten werden zu einem Straÿenabschnitt auch
noch die gemeldeten Verkehrsprobleme gespeichert. Dies geschieht mit der Klasse
Congestion,
die zu einer geographischen Koordinate sechs verschiedene Arten von Störungen verwalten kann.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
40
KAPITEL 5. SERVER
Obwohl es durchaus ausreichen würde, mittels der angegebenen Position eine Visualisierung auf
den Clients vorzunehmen, erfolgt hier ein genaues Abbilden der Meldung auf eine bestimmte
Straÿe. Dies ist notwendig, um später bei der Berechnung von Routen vorliegende Probleme zu
erkennen und zu umfahren. Liegen die Meldungen dabei auch nur minimal neben der Straÿe, so
werden sie von der
CloudMade NavEngine
ignoriert und ihre Erfassung wäre zumindest für das
Routing unnötig geworden.
Ebenso wie die gemeldeten Störungen werden auch die eingehenden Informationen der Benutzer auf einen Straÿenabschnitt abgebildet. Dies geschieht mittels der Klasse
UserData,
die alle
nötigen Daten kapselt, persistiert und für die Aufbereitung durch die verschiedenen Services des
Servers vorbereitet.
Alle vorgestellten Klassen werden jeweils eins zu eins auf Tabellen in der Datenbank abgebildet.
Die Verwaltung der Beziehungen wird automatisch von Hibernate geregelt und unter Verwendung
von Fremdschlüsseln umgesetzt.
5.2 Verarbeitung der Nutzerinteraktion
Wie bereits in Abbildung 5.1 gezeigt, verfügt der Server über eine Komponente, welche die komplette Kommunikation mit den Clients regelt und die eingehenden Anfragen dann an verschiedene
Request-Handler weiterreicht.
Um den Clients eine Verbindungsmöglichkeit anzubieten, wird beim Start ein
ServerSocket
erstellt. Dieser nimmt dann in einer Endlosschleife Anfragen entgegen und erzeugt für jede einen
Controller, der in einem eigenen Thread läuft und dort die eingehenden Daten analysiert.
Map < Integer , Class <? extends RequestHandler > > handler =
new HashMap < Integer , Class <? extends RequestHandler > >() ;
..
Class <? extends RequestHandler > cl = handler . get ( r . getType () ) ;
if ( cl != null ) {
Constructor <? extends RequestHandler > ct = cl
. getConstructor ( Socket . class ) ;
RequestHandler handle = ct . newInstance ( socket ) ;
handle . handleRequest ( r ) ;
} else {
writeOutput ( " { ' error ': ' no matching Request - Handler found '} " ) ;
}
Listing 5.3:
Da der Controller über eine
Map
Auswahl des passenden Request-Handler
verfügt, in der für jeden denierten Anfragetyp ein Handler
registriert ist, wählt er auch den passenden Request-Handler aus und erzeugt, mit dem in Listing
5.3 gezeigten Verfahren, per Reection eine Instanz der passenden Klasse und ruft anschlieÿend
die Methode
handleRequest(Request)
für die eigentliche Bearbeitung auf.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.2. VERARBEITUNG DER NUTZERINTERAKTION
41
Da nicht immer eine Antwort des Servers erfolgen muss, erfolgt die Generierung der JSONAntwort bei Bedarf in den einzelnen Request-Handlern.
5.2.1
Da der
Bereitstellung des Verkehrsaufkommens
UpdateHandler
von allen Clients in regelmäÿigen Abständen aufgerufen wird, ist er die
am häugsten genutzte Serverkomponente. Er benötigt Informationen zu Position und Geschwindigkeit des Endgerätes und ermittelt auf Basis dieser Werte die Belastung der nächstliegenden
Straÿen. Des Weiteren werden alle gemeldeten Störungen aus der Datenbank gelesen und es
erfolgt eine Überprüfung ob für den anfragenden Client eine aktive Route vorhanden ist.
Abbildung 5.4:
Prozessablauf: Bearbeitung eines Update-Requests durch den Server
Abbildung 5.4 zeigt die einzelnen Schritte, die vom Server durchlaufen werden müssen um eine
solche Aktualisierungsanfrage zu bearbeiten. Zuerst werden die vom Client mitgelieferten Daten interpretiert und eine Instanz der Klasse
Client
erzeugt. Verfügt dieser über keine gültige
Autorisierung, wird die Verarbeitung sofort abgebrochen und eine Fehlermeldung versendet. Andernfalls wird mit der Auswertung fortgefahren, indem mittels Reverse Geocoding anhand der
Position des Endgerätes der aktuell befahrene Straÿenabschnitt ermittelt wird.
Anschlieÿend wird für eine möglichst gute Bestimmung der zu übermittelnden Daten die Fahrtrich-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
42
KAPITEL 5. SERVER
tung des anfragenden Anwenders betrachtet. Da diese vom Client aber nicht mitgeliefert wird,
muss hier eine Berechnung auf Basis der aktuellen und der letzten bekannten Position erfolgen. Falls es keinen weiteren Datensatz gibt, die letzte Meldung zu lange her oder zu weit von
der aktuellen Position entfernt ist, wird der Wert für die Geschwindigkeit über die vorliegenden
Messungen für beide Fahrtrichtungen interpoliert.
Da der Anwender die Möglichkeit hat einzustellen, für welchen Umkreis er eine Visualisierung
der Geschwindigkeiten haben möchte, muss eine Überprüfung erfolgen, ob weitere Datensätze
geladen werden sollen. Ist dies der Fall, werden die entsprechenden Straÿenabschnitte aus der
Datenbank geholt und die möglichen Geschwindigkeiten ermittelt. Als Fahrtrichtung wird dabei
jeweils davon ausgegangen, dass von der, dem aktuellen Abschnitt nächstliegenden Seite in die
Straÿe eingefahren wird.
Nach Abschluss der Ermittlung der Geschwindigkeiten, werden im nächsten Schritt alle betrachteten Abschnitte hinsichtlich des Vorliegens von Verkehrsstörungen überprüft. Werden in der
Datenbank Meldungen gefunden, so werden diese ebenfalls an die JSON-Antwort des Servers
angehängt.
Der letzte Schritt vor dem Übertragen der ermittelten Werte besteht in der Kontrolle, ob für den
Client eine Route aktiv ist und ob diese aufgrund von Änderungen des Verkehrsusses von der
letzten übermittelten abweicht. Ist dies der Fall, wird an die Antwort ein Flag angehängt, das
der Anwendung auf dem Endgerät mitteilt, dass eine Aktualisierung der Routinginformationen
erfolgen muss.
Wenn dann die Übertragung der gesammelten Daten abgeschlossen ist, wird das zeitintensive
Speichern der Objekte in der Datenbank durchgeführt. Auÿerdem erfolgt eine Aktualisierung
des Caches von Hibernate um eine schnellere Bearbeitung von Anfragen für die gleiche Region
zu ermöglichen.
5.2.2
Bearbeitung von Verkehrsmeldungen
Um den Endanwendern die bereits erwähnten Verkehrsmeldungen zur Verfügung zu stellen, müssen diese zuerst erfasst werden. Hierfür verfügt die Android-Anwendung über ein Interface, das
im Abschnitt 6.5 noch genauer betrachtet werden soll. Serverseitig gibt es zwei Request-Handler,
die mit den Störungen arbeiten: Von einem Handler werden dabei neue Meldungen aus den Daten der Nutzer erzeugt, während der andere zum Löschen bereits erfasster Datensätze dient.
Diese Aufteilung wird notwendig, da die Anfragen sich grundlegend in Umfang und Struktur
unterscheiden.
Der Handler zum Melden einer neu aufgetretenen Störung, erwartet zumindest Werte für Position
und Zeitpunkt des Auftretens beziehungsweise der Erfassung. Zusätzlich kann noch einer der
sechs Typen aus Tabelle 5.1 angegeben sein. Ist dies nicht der Fall, wird
Allgemeine Gefahrenstelle
als Standardwert gesetzt.
Da die angegebene Position nicht zwangsläug genau auf einer Straÿe liegt, muss zuerst der
nächstliegende Straÿenabschnitt aus der Datenbasis ermittelt werden. Auÿerdem erfolgt noch
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.2. VERARBEITUNG DER NUTZERINTERAKTION
Stau
Unfall
Glatteis
Groÿveranstaltung
43
Baustelle
Allgemeine
Gefahrenstelle
Tabelle 5.1:
Arten der verwendeten Verkehrsprobleme
eine Prüfung, ob bereits eine Meldung des selben Typs für die entsprechende Position vorliegt.
Ist dies nicht der Fall, wird eine neue Instanz der Klasse
Congestion
erzeugt, mit der Straÿe
verknüpft und gespeichert.
Der Löschvorgang ist um ein Vielfaches einfacher. Da dem Client die eindeutigen IDs der ihm
übermittelten Verkehrsprobleme bekannt sind, wird zum Löschen nur eine Anfrage des passenden Typs gestellt und mit der betreenden ID an den Server gesendet. Dieser lädt dann das
entsprechende Objekt in den Speicher und markiert es als gelöscht. Sobald Hibernate die oene
Transaktion beendet, wird auch der zugehörige Eintrag aus der Datenbank entfernt.
5.2.3
Routing
Für das Routing und die damit verbundenen Operationen stellt der Server drei Request-Handler
zur Verfügung, deren Aufgaben sich in Komplexität und Zeitaufwand erheblich unterscheiden.
Der
CalculateRouteHandler
kommt zum Einsatz, wenn auf dem Client eine Route erstellt und
an den Server zur Bearbeitung weitergereicht wird. Dort erfolgt zuerst eine Prüfung der eingehenden Daten hinsichtlich Gültigkeit der Client-ID und Vollständigkeit der Routeninformationen.
Sind beide Prüfungen erfolgreich bewältigt worden, wird die Abwicklung der Anfrage fortgesetzt.
Da zum Routing die bereits vorgestellte CloudMade API verwendet wird, müssen in einem ersten
Schritt alle blockierten Straÿen ermittelt werden. Um die Menge der ermittelten Datensätze dabei
zu begrenzen, erfolgt hier eine Einschränkung auf einen bestimmten geographischen Bereich,
welcher aus den vom Benutzer angegebenen Werten für Start, Ziel und möglichen Zwischenhalts
berechnet wird. Innerhalb dieses Polygons werden anschlieÿend alle Straÿenabschnitte aus der
Datenbank geladen, bei denen der aktuellste Wert für die mögliche zu fahrende Geschwindigkeit
unter 80 % der erlaubten Höchstgeschwindigkeit liegt.
Da die Routinganfrage bei CloudMade im Paramater
blockedRoad
eine Liste von Geokoordina-
ten erwartet, ist es nicht möglich die Beschreibung eines kompletten Abschnitts in Form eines
LineStrings
zu übergeben. Hier muss eine Aufbereitung erfolgen, die so umgesetzt wurde, dass
von jedem ermittelten Abschnitt einer der mittleren Punkte in die Liste der betroenen Koordinaten eingefügt wird. Dieser eine Punkt ist ausreichend, da schon bei der Unterteilung der
Straÿen darauf geachtet wurde, dass jedes der erzeugten Teilstücke von zwei Querstraÿen abgeschlossen wird und nicht über mehrere Kreuzungen hinwegreicht. Des Weiteren werden der
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
44
KAPITEL 5. SERVER
Liste auch noch die Positionen der gemeldeten Verkehrsstörungen für die betrachtete Umgebung
hinzugefügt.
Anschlieÿend wird die Anfrage mit den Werten für Start, Ziel und Zwischenstopps versehen und
an CloudMade geschickt. Die Antwort besteht im Idealfall aus einer Menge von Geokoordinaten,
die eine Route beschreiben, die um alle übergebenen Problemstellen herumgeführt wird. Ist
es aber nicht möglich alle blockierten Abschnitte zu meiden oder ein Routing zwischen den
gegebenen Positionen generell nicht möglich, so wird dies über einen Statuscode im Ergebnis
angegeben. Im letzteren Fall wird dem anfragenden Client eine Fehlermeldung zugestellt und
er kann gegebenenfalls ein neues Routing versuchen. Der erste Fall hat dagegen eine Route
erhalten und wird vom Server wie ein ideales Routing behandelt, dem Client zugesandt und in
der Datenbank für spätere Aktualisierungen gespeichert.
Der zweite Handler, der sich mit dem Routing befasst, wird indirekt durch das im Kapitel
Bereitstellung des Verkehrsaufkommens
beschriebene Flag angesprochen. Dieses veranlasst den
Client dazu eine Aktualisierungsanfrage für die Route an den Server zu senden, welche dort
vom
RefreshRouteHandler entgegengenommen wird. Die Bearbeitung ist dabei nicht besonders
komplex, da der Handler nur die aktuelle Route aus der Datenbank ausliest, in das JSON-Format
umwandelt und an den Client zurücksendet. Der eigentlich Aktualisierungsvorgang ist komplett
im Hintergrund der Anwendung abgelaufen und wird im folgenden Kapitel genauer erläutert.
Die letzte Möglichkeit für Aktionen auf Basis des Routings liefert der
DeleteRouteHandler.
Dieser wird angesprochen, wenn vom Client eine Anfrage mit der Bitte um Löschung der aktuellen
Route einhergeht. Hierfür können verschiedene Gründe vorliegen: Zum einen ist es möglich, dass
die Android-Anwendung festgestellt hat, dass das Ende der Route erreicht wurde. Zum anderen
kann es auch sein, dass durch den Nutzer ein Abbruch des Routings erfolgte um beispielsweise
eine neue Route zu erstellen oder weil die aktuelle Route nicht weiter befahren werden soll.
Das Löschen einer aktiven Route wird wiederum komplett von Hibernate übernommen, welches im Hintergrund das zugehörige Objekt lädt, die Verknüpfung mit dem Client löscht und
anschlieÿend die Route selber aus der Datenbank entfernt.
5.3 Datenaggregation und -analyse
In den Abschnitten zum Überblick über den Funktionsumfang des Servers wurden bereits einige
der wesentlichen Prozesse zu Datenaggregation und -analyse kurz skizziert. Im Folgenden werden
nun einzelne Schritte noch einmal genauer betrachtet und hinsichtlich ihres Nutzens analysiert.
Auÿerdem sollen hier die
Services
genauer vorgestellt werden, die im Hintergrund des Servers
arbeiten und es somit ermöglichen die benötigte Zeit für die Abarbeitung der verschiedenen
Anfragen durch den Client zu minimieren. Sie dienen dabei sowohl zur Überprüfung der vorliegenden Daten auf Korrektheit und Nutzbarkeit im Rahmen dieser Anwendung als auch zur
Durchführung von komplexen Operationen, wie der Aktualisierung der Routinginformationen.
Die dritte Art von Komponenten, die in diesem Abschnitt näher betrachtet werden sollen, sind
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.3. DATENAGGREGATION UND -ANALYSE
45
die Datenbank-Views. Sie werden eingesetzt, um komplexe Anfragen zu kapseln und um einen
einfachen Zugri auf die Daten zu erhalten ohne dass dafür eine Aufweichung der Normalisierung
erfolgen muss. Da Hibernate es ermöglicht, Views per Mapping-Datei zu erzeugen und als Basis
für Klassen zu verwenden, lässt sich diese Komponente auch ohne weitere Anpassungen in die
Gesamtarchitektur des Servers integrieren.
5.3.1
Mapping der GPS-Informationen
Um die von den Anwendern gemeldeten Daten einzelnen Straÿenzügen zuzuordnen und damit die
GPS-Ungenauigkeit auszugleichen, gibt es zwei Verfahren, die sich in Genauigkeit und benötigter
Zeit erheblich unterscheiden: Das
Closest Line Problem
und das
Nearest Point of Line Problem.
Point p = GeomHelper . createPoint ( lon , lat ) ;
RoadStrip rs = ( RoadStrip ) s
. createCriteria ( RoadStrip . class )
. add ( new DWithinExpression ( " way " , p , 8.2 E -4) )
. addOrder ( LocalDistanceOrder . asc ( " distance " , p ) )
. setMaxResults (1)
. uniqueResult () ;
Listing 5.4:
Beim
Closest Line Problem
Umsetzung des Closest Line Problem
soll zu einer gegebenen Geokoordinate die nächstliegende Straÿe
ermittelt werden. Bei der Umsetzung erfolgt zuerst eine Beschränkung der Datensätze auf Abschnitte, die sich innerhalb einer fest denierten, möglichst kleinen Umgebung um den betrachteten Punkt benden. Die so erhaltene Ergebnismenge wird nach dem berechneten Abstand
aufsteigend sortiert und anschlieÿend auf einen Datensatz limitiert.
Im Rahmen dieser Arbeit wird für die programmatische Umsetzung dieses Konzeptes Hibernate verwendet. Mittels der
DWithinExpression
ndet dabei die Selektion statt, während die
LocalDistanceOrder die Berechnung des Abstandes und die anschlieÿende Sortierung vornimmt.
Die Beschränkung auf einen Datensatz gewährleistet, dass auch wirklich ein eindeutiges Ergebnis geliefert wird. Andernfalls müsste mit der Methode
list
eine Liste von Straÿenabschnitten
ermittelt werden, von der nur der erste Datensatz betrachtet werden dürfte.
Dieses Verfahren wird unter anderem beim Zuordnen von Positions- und Geschwindigkeitsmeldungen zu einem bestimmten Straÿenabschnitt verwendet. Hierbei ist es nicht erforderlich, dass
die eingehenden Daten auf eine genaue Koordinate der Straÿe abgebildet werden, da alle weiteren
Prozesse die Position der Meldung ignorieren und einzig die gemessene Geschwindigkeit und die
zugewiesene Straÿe benötigen.
Bei den Meldungen von Verkehrsstörungen, sieht dies anders aus. Hier ist es für die spätere Anzeige auf den Clients zwar ebenfalls nicht von zentraler Bedeutung ob das Problem direkt auf
einer Straÿe oder in einiger Entfernung dazu liegt, jedoch wird für das Routing eine möglichst
genaue Position benötigt. Dies ist der Struktur der CloudMade API geschuldet, die für den Parameter
blockedRoad eine Liste von Geokoordinaten erwartet, die von einer Route nicht berührt
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
46
KAPITEL 5. SERVER
werden dürfen. Liegt eine Meldung dann neben einer Straÿe, wird sie bei der Berechnung nicht
weiter betrachtet und es könnte passieren, dass die ermittelte Route direkt über eine Position
führt, die eigentlich hätte vermieden werden können.
s . createSQLQuery ( " UPDATE congestions SET position = (
SELECT ST_Line_Interpolate_Point ( rs . way ,
ST_Line_Locate_Point ( rs . way , c . position ) )
FROM congestions c
INNER JOIN roadstrips rs ON rs . id = c . road_id
WHERE congestions . id = c . id ) " )
. executeUpdate ()
Listing 5.5:
Bei der Behandlung des
Umsetzung des Nearest Point of Line Problem
Nearest Point of Line Problems
muss auch zuerst immer der zugehörige
Straÿenabschnitt ermittelt werden. Dies geschieht in einem Verfahren, das auf Basis der in Listing
5.4 gezeigten Methode zur Umsetzung des
Closest Line Problems
aufsetzt und dann in einem
zweiten Schritt die Berechnung des nächstliegenden Punktes auf dem ermittelten Abschnitt zur
Position der Meldung durchführt. Da die hierfür notwendigen PostGIS-Funktionen noch sehr neu
sind, gibt es für sie noch kein Äquivalent in Hibernate und es muss eine Umsetzung auf SQLBasis erfolgen. Das so erstellte Update-Statement wird dann allerdings wieder über das ORM
gegen die Datenbank abgesetzt.
Listing 5.5 zeigt, wie zuerst mit der PostGIS-Funktion
ST_Line_Locate_Point
die Position des
nächstliegenden Punktes innerhalb des LineStrings berechnet wird. Allerdings liefert diese Methode als Ergebnis keine neue
Point-Instanz,
sondern nur einen Wert zwischen Null und Eins,
der angibt, wo im LineString der gesuchte Punkt zu nden ist. Um diesen prozentualen Wert
in ein geometrisches Objekt zu überführen, wird die Methode
ST_Line_Interpolate_Point
ge-
nutzt, welche einen Punkt anhand der vorliegenden Informationen auf der Linie interpoliert. Der
so erzeugte Wert, wird dann anstelle der in der Meldung angegebenen Position in der Datenbank
gespeichert und bei den nächsten Aktualisierungsanfragen an die Clients übergeben.
5.3.2
Analyse der Geschwindigkeit
Die Informationen über die berechneten Geschwindigkeiten für die einzelnen Straÿenabschnitte
werden durch die bereits vorgestellten Klassen
SpeedToStart
und
SpeedToEnd
gekapselt. Bei
diesen handelt es sich aber lediglich um POJOs, die intern über keine weitere Logik verfügen.
Die Ermittlung der entsprechenden Werte erfolgt im Hintergrund durch eine View. Diese sammelt
die vorliegenden Daten der Nutzer, bewertet diese und nimmt anhand eines fest denierten
Schlüssels für die Qualitätsabstufungen eine Gruppierung vor. Die Bewertungsfunktion wurde
dabei in Anlehnung an die Forschungsergebnisse von [Gol08], [Her09] und [Lin05] aufgestellt
und weist jeder Nutzermeldung einen Faktor zu, der bei der späteren Berechnung berücksichtigt
wird. Die unterschiedlichen Qualitätsstufen wurden dagegen erst im Rahmen dieser Applikation
deniert und dienen lediglich zu einer späteren Visualisierung der Aktualität der verwendeten
Datensätze.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.3. DATENAGGREGATION UND -ANALYSE
47
Da im Rahmen der erwähnten Forschungsarbeiten unter anderem festgestellt wurde, dass das
Fahrverhalten von Autofahrern in Kreuzungsbereichen durch Abbiegevorgänge und Ampelphasen
beeinusst wird, werden in diesen Bereichen erfasste Werte deutlich weniger gewertet, als auf
gerader Strecke aufgenommene. Nach ersten Testfahrten hat sich hierfür ein Verhältnis von 1:10
als ideal erwiesen.
UPDATE userdata SET factor = CASE
WHEN ( SELECT Count ( r . id ) AS count
FROM roadstrips r
WHERE ST_DWithin ( position , r . way , 0.0007) ) < 2 THEN 10
ELSE 1 END
Listing 5.6:
Gewichtung der vorhandenen Meldungen
Um nun eine möglichst performante View zu erzeugen, wird die aufwendige Bewertungsfunktion
ausgegliedert. Aufwendig meint dabei in diesem Kontext nicht unbedingt kompliziert, sondern
vielmehr rechenintensiv. Dies hängt damit zusammen, dass für jede Meldung eines Anwenders
zuerst im inneren SQL-Statement eine geometrische Funktion auf alle vorhandenen Straÿenabschnitte angewendet wird. Anschlieÿend erfolgt noch die Verwendung der Aggregatfunktion
Count um zu ermitteln, wie viele der registrierten Straÿenabschnitte sich im Umkreis von 0,0007
Grad (etwa 50 Meter) um die gemeldete Position benden. Ist dies nur einer, wird die Meldung
mit dem Faktor 10 gewertet. Andernfalls mit dem Faktor 1.
-- Berechnung mit Meldungen der letzten 2 Stunden
SELECT tmp . road_id || ' _0 ' AS id , tmp . road_id , 0 AS category ,
Round (( Sum ( tmp . speed * tmp . factor ) / Sum ( tmp . factor ) ) , 0) AS speed
FROM userdata tmp
WHERE ( Now () - tmp . time ) < ' 02:00:00 '
GROUP BY tmp . road_id
UNION ALL
-- Berechnung mit Meldungen des gleichen Wochentages u . Zeitfensters
SELECT tmp . road_id || ' _1 ' AS id , tmp . road_id , 1 AS category ,
Round (( Sum ( tmp . speed * tmp . factor ) / Sum ( tmp . factor ) ) , 0) AS speed
FROM userdata tmp
WHERE Date_Part ( ' dow ' , tmp . time ) = Date_Part ( ' dow ' , now () )
AND ( Date_Part ( ' hour ' , tmp . time ) = ( Date_Part ( ' hour ' , now () ) - 1)
OR Date_Part ( ' hour ' , tmp . time ) = Date_Part ( ' hour ' , now () ) )
GROUP BY tmp . road_id
UNION ALL
-- Berechnung mit allen vorhandenen Meldungen
SELECT tmp . road_id || ' _2 ' AS id , tmp . road_id , 2 AS category ,
Round (( Sum ( tmp . speed * tmp . factor ) / Sum ( tmp . factor ) ) , 0) AS speed
FROM userdata tmp
GROUP BY tmp . road_id
Listing 5.7:
Denition der View zur Ermittlung der Geschwindigkeiten
Diese vorgelagerte Bewertung ermöglicht es auch, zu einem späteren Zeitpunkt problemlos Anpassungen an den vergebenen Faktoren vorzunehmen oder eine Erweiterung für neu erkannte
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
48
KAPITEL 5. SERVER
Sonderfälle hinzuzufügen. Wäre die Bewertungsfunktion dagegen Bestandteil der eigentlichen
View, so könnten Änderungen sehr schnell deren Struktur beeinussen, was wiederum mit Konsequenzen für den objektrelationalen Mapper verbunden wäre. Auÿerdem haben Zeitmessungen
der Anfragen an die Sicht mit vorgelagerter Bewertung eine Dauer von unter einer Sekunde
gegenüber etwa zehn Sekunden bei einer Sicht mit integrierter Bewertungsfunktion ergeben.
Listing 5.7 zeigt die eigentlich Denition der View. Sie besteht aus drei Teilen, die jeweils die
Daten für die einzelnen Genauigkeitsabstufungen zusammenfassen und sich lediglich in der Selektion der verwendeten Datensätze unterscheiden. Das erste Statement sammelt alle Datensätze,
deren Meldung maximal zwei Stunden zurückliegt, während beim zweiten alle betrachtet werden, die am gleichen Wochentag in einem Zeitraum von zwei Stunden um die aktuelle Zeit herum
erfasst wurden. Im dritten und letzten Teil der Denition werden alle vorhandenen Datensätze zur Berechnung herangezogen und das Ergebnis in die schlechteste Kategorie (Kategorie 2)
eingeordnet.
Im System gibt es nun zwei unterschiedliche Views, deren Denition sich von obigem SQL darin
unterscheiden, dass sie um eine Betrachtung der Fahrtrichtung erweitert sind. Da dies aber
lediglich die Auswertung eines boolschen Wertes in der Tabelle
userdata erfordert, soll an dieser
Stelle auf eine eingehende Betrachtung verzichtet werden.
5.3.3
Aktualisierung des Routings
Die Arbeitsweise des
RefreshRoutesService ist der des CalculateRouteHandler in vielen Punk-
ten ähnlich. Ein wesentlicher Unterschied besteht allerdings im Zeitpunkt der Verarbeitung. Während der
Request-Handler
direkt mit dem Nutzer kommuniziert, läuft der
Service im Hintergrund
des Systems und unterliegt somit keinen zeitlichen Beschränkungen.
Solange im System aktive Routen vorhanden sind, wird der Service alle fünf Minuten gestartet. Er
liest dann zuerst alle Strecken aus der Datenbank aus und ermittelt in einem zweiten Schritt die
vorliegenden Probleme, für den zu betrachtenden Bereich. Da die nun folgende Vorgehensweise
gröÿenteils identisch mit der des bereits beschriebenen Request-Handlers ist, soll an dieser Stelle
nur eine Betrachtung der wesentlichen Unterschiede erfolgen.
So muss der Service die Anfrage-URL für CloudMade nicht komplett neu generieren, da der
unveränderliche Teil, bestehend aus Basis-URL, Start- und Zielposition, sowie möglichen Zwischenstationen, in der Datenbank gespeichert wurde. Lediglich die Liste der blockierten Straÿen
muss neu erzeugt und an die Anfrage angehängt werden.
Der zweite wesentliche Unterschied besteht in der Verarbeitung des von CloudMade gelieferten
Ergebnisses. Während im Request-Handler die JSON-Ausgabe für den Client erzeugt wurde, wird
hier ein geometrisches Objekt vom Typ
LineString
erstellt und mit der bereits vorhandenen
Route verglichen. Liegen Unterschiede vor, so wird das neue Objekt in der Datenbank gespeichert
und ein Flag gesetzt, dass sich die Route seit der letzten Übertragung an den Client verändert
hat.
Da bei jeder Anfrage eine Überprüfung dieses Attributs erfolgt, kann der Client abhängig von der
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.3. DATENAGGREGATION UND -ANALYSE
49
eingestellten Aktualisierungsrate relativ schnell über Änderungen informiert werden und somit
die aktuelle Route vom Server erfragen.
5.3.4
Erfassung der Geschwindigkeitsbegrenzungen
Um eine aussagekräftige Visualisierung der Geschwindigkeitsinformationen auf den Clients zu
erreichen, ist eine möglichst umfangreiche Datenbasis erforderlich. Die von OpenStreetMap importierten Datensätze mit Werten für Straÿentyp, Name und Geschwindigkeitsbegrenzung sind
jedoch nicht immer vollständig. So ist von den circa 500.000 Straÿenzügen in Niedersachsen nur
etwa bei der Hälfte der Name erfasst. Eine Höchstgeschwindigkeit liegt sogar nur bei 15 % der
Datensätze vor.
Da serverseitig der Straÿenname nicht verwendet wird und die Android-Clients über StandardKlassen für das Geocoding verfügen, muss dieses Attribut nicht weiter betrachtet werden. Bei
der maximal erlaubten Geschwindigkeit verhält es sich jedoch anders. Diese wird sowohl vom
Server als auch vom Client benötigt. Der Server braucht die Informationen für die Ermittlung
von blockierten Straÿen, die beim Routing und bei der Problemerkennung verwendet werden.
Auf den Clients werden die Daten zum einen für die farbliche Kennzeichnung der Straÿenzüge
benötigt und zum anderen erfolgt eine Anzeige der aktuellen Geschwindigkeitsbegrenzung zur
Information des Anwender.
Um nun die fehlenden Informationen möglichst genau bestimmen zu können, wird ein weiterer
Service
verwendet. Dieser läuft einmal täglich und betrachtet die erfassten Geschwindigkeits-
informationen für einen Straÿenabschnitt. Da nach [Gol08] die Werte in Kreuzungsbereichen
aufgrund von Abbiegevorgängen oder Ampelphasen nicht aussagekräftig für einen groÿen Abschnitt sind, benutzt der hier implementierte Dienst nur Meldungen, die mindestens einhundert
Meter von Kreuzungen entfernt aufgenommen wurden.
Attribut
Wertebereich
Meldungen
prozentualer Anteil
Straÿenname
Brockhauser Weg
-
-
Straÿentyp
tertiary (Kreisstraÿe)
-
-
< 20 km/h (Spielstraÿe)
2
0,51 %
20 - 40 km/h (30 km/h)
34
8,67 %
40 - 60 km/h (50 km/h)
61
15,56 %
60 - 85 km/h (70 km/h)
174
44,38 %
85 - 110 km/h (100 km/h)
104
26,53 %
> 110 km/h
17
4,34 %
Geschwindigkeit
Tabelle 5.2:
Erfasste Messungen für den Brockhauser Weg, Stand 11.11.2011
Neben diesen Werten greift der Algorithmus auch auf den in den Originaldatensätzen erfassten
Straÿentyp zu, da dieser oft schon die Geschwindigkeitsbegrenzung grob einschränkt. So deutet
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
50
KAPITEL 5. SERVER
beispielsweise der Wert
residential
auf eine Straÿe in Wohngebieten hin, wo zumindest in
Deutschland eine Geschwindigkeit von maximal 50 km/h erlaubt ist.
Tabelle 5.2 zeigt die erfassten Werte für einen Abschnitt des Brockhauser Weges. Dieser eignet
sich für eine beispielhafte Betrachtung des Algorithmus besonders gut, da bereits kurz nach Start
der Applikation verhältnismäÿig viele Messungen vorliegen, was darin begründet ist, dass diese
Straÿe einen Teil der Teststrecke darstellt.
Der
UpdateSpeedService
ermittelt in einem ersten Schritt alle gespeicherten Straÿenabschnit-
te, für die mindestens zweihundert Meldungen durch Endanwender vorliegen. Anschlieÿend erfolgt abhängig vom Straÿentyp die Unterteilung in die verschiedenen Wertebereiche. Da es
sich in obigem Beispiel um eine Kreisstraÿe handelt, lässt sich lediglich eine maximal erlaubte Geschwindigkeit von 100 km/h festlegen und es kommen somit fünf mögliche StandardGeschwindigkeitsbegrenzungen in Frage.
Im nächsten Schritt erfolgt eine Zuordnung der erfassten Meldungen zu den jeweiligen Wertebereichen, welche so gewählt sind, dass die Grenzen genau mittig zwischen den eigentlichen Tempolimits liegen. Gibt es Bereiche mit mehr als einhundert zugehörigen Datensätzen, so werden
diese als potentielle Geschwindigkeitsbegrenzungen vermerkt und weiter betrachtet. Im Beispiel
zum Brockhauser Weg würde also für 70 km/h und 100 km/h ein weiterer Bearbeitungsschritt
erfolgen.
Die letztendliche Entscheidung über das mutmaÿliche Tempolimit wird im letzten Schritt gefällt.
Bekommt dieser als Eingabeparameter Grenzen übergeben, die nicht direkt nebeneinanderliegen
(z.B. 30 km/h und 70 km/h), wird die Verarbeitung abgebrochen. Dies liegt darin begründet, dass
so stark abweichende Werte nur durch äuÿere Einüsse, wie Baustellen oder Feierabendverkehr,
zustande kommen können.
Handelt es sich aber um angrenzende Wertebereiche, werden diese hinsichtlich ihres prozentualen
Anteils an allen Messungen betrachtet. Liegt dieser Wert für einen der Bereich über 50 % oder
ist mehr als 20 % gröÿer als die Vergleichswerte, so wird das zugehörige Tempolimit gespeichert.
Unterscheiden sich die Werte wie in Tabelle 5.2 um weniger als 20 %, so wird die niedrigste der
Geschwindigkeitsbegrenzung vermerkt. Dies geschieht aus Sicherheitsgründen, um dem Anwender auf keinen Fall zu hohe Werte anzuzeigen. Im gewählten Beispiel würde also 70 km/h als
Tempolimit vermerkt, was auch dem tatsächlichen Wert entspricht.
Bei den bisher mit diesem Vorgehen berechneten Geschwindigkeitsbegrenzungen liegt die Trefferquote bei circa 80 %. Ob allerdings eine Anpassung der Werte für die verwendeten Meldungsstückzahlen und Prozentwerte bei steigender Nutzerzahl notwendig wird, lässt sich zum jetzigen
Zeitpunkt noch nicht feststellen. Um aber die berechneten Werte jederzeit überprüfen zu können, werden diese mit einem Flag gekennzeichnet und beim nächsten Durchlauf des Services
gegebenenfalls angepasst.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.3. DATENAGGREGATION UND -ANALYSE
5.3.5
51
Erkennung wiederkehrender Probleme
Neben den bereits vorgestellten Funktionen zur Aufbereitung und Verbesserung der Daten, sollen
auÿerdem noch häuger vorkommende Verkehrsprobleme identiziert werden. Als Erkennungsmethode wird dabei ein zweistuges Verfahren eingesetzt, welches aus einer Datenbank-View als
Datenbasis und einem Service zur Berechnung besteht.
SELECT Date_Part ( ' dow ' , u . time ) AS dow , Date_Part ( ' hour ' , u . time )
AS hour , u . road_id , r . maxspeed , AVG ( u . speed ) AS speed
FROM userdata u
INNER JOIN roadstrips rs ON u . road_id = rs . id
INNER JOIN roads r ON rs . road_id = r . id
WHERE r . maxspeed IS NOT NULL AND r . maxspeed * 0.8 > u . speed
GROUP BY Date_Part ( ' dow ' , u . time ) , Date_Part ( ' year ' , u . time ) ,
Date_Part ( ' month ' u . time ) , Date_Part ( ' day ' , u . time ) ,
Date_Part ( ' hour ' , u . time ) , u . road_id , r . maxspeed ;
Listing 5.8:
Löschen ungültiger Datensätze
Die View ermittelt zuerst alle Straÿenzüge, für die Meldungen mit Geschwindigkeitswerten unter 80 % des Tempolimits erfasst wurden. Dann erfolgt eine Gruppierung dieser Datensätze auf
Basis des Meldezeitpunktes. Listing 5.8 zeigt, dass innerhalb der Group By-Klausel fünf Bestandteile des Datumsfeldes
time
verwendet werden, während in der Projektion nur Wochentag und
Stunde genutzt werden. Diese Unterscheidung wird verwendet, um die Ergebnismenge auf die
für die Weiterverarbeitung wesentlichen Informationen zu beschränken, gleichzeitig aber keine
Probleme zu übersehen. Liegen beispielsweise Meldungen vom 1. und vom 8. November 2011 für
den gleichen Zeitraum auf dem gleichen Straÿenabschnitt vor, so hätten beide den identischen
Wochentag und würden bei einer Gruppierung nach diesem Attribut lediglich als ein Datensatz
in der View auftauchen. Dies wäre aber nicht korrekt, da es sich um ein Problem zu handeln
scheint, welches häuger an einem Dienstag zu der vorliegenden Zeit auftaucht.
Um Störungen genau dieser Art zu nden, wird der
FindRecurringProblemsService verwendet.
Dieser erfasst in einem ersten Schritt alle Kombinationen aus Wochentag, Uhrzeit und betroener
Straÿe, die mindestens zweimal in der View vorhanden sind. Alle diese Daten werden dann in
einer Map gespeichert und mit einem Flag versehen, welches kennzeichnet, ob das vorliegende
Problem schon mit anderen verbunden werden konnte.
Um eine solche Zusammenfassung zu erreichen, werden zwei Arten von Gruppierungsmöglichkeiten betrachtet. Bei der ersten handelt es sich um eine räumliche Einordnung der Probleme, was
bedeutet, dass eine Untersuchung bezüglich der geographischen Position der betroenen Straÿenzüge erfolgt. Liegen also Meldungen zum gleichen Zeitpunkt in unmittelbarer Nähe des gerade
betrachteten Datensatzes vor, so werden diese vom Service miteinander verbunden und als ein
Problem behandelt.
Bei der zweiten Überprüfung erfolgt eine Suche nach Störungsmeldungen, die sich im Wochentag unterscheiden, während Straÿenabschnitt und Uhrzeit identisch sind. Auf diese Weise sollen
Engstellen in der Verkehrsführung identiziert werden, die nur zu bestimmten Zeiten auftreten,
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
52
KAPITEL 5. SERVER
wie beispielsweise der Feierabendverkehr.
Da diese Suche erst nach Abschluss des ersten Schrittes erfolgt, ist es möglich, dass einige Datensätze bereits aufgrund ihrer geographischen Nähe zusammengefasst wurden. Um nun eine weitere
Verdichtung der Probleme vornehmen zu können, ist es notwendig, dass die Meldungen für einen
anderen Wochentag auf ähnliche Weise gruppiert vorliegen. Unterscheiden sich die betroenen
Straÿenabschnitte jedoch zu sehr, so werden in der Ergebnismenge zwei zwar sehr ähnliche, aber
nicht identische Probleme vermerkt.
Im letzten Schritt der Verarbeitung wird dann auf Basis der so gesammelten Informationen eine
anzeigbare Meldung generiert. Diese beinhaltet neben dem Namen der Straÿe im Zentrum des
Problems auch die betroenen Wochentage und die Uhrzeit der Erfassung .
Wiederkehrendes Problem ( Kreuzstraÿe ) : Samstags , jeweils ab 16:00 Uhr
Wiederkehrendes Problem ( Bremer Straÿe ) : Montags , Dienstags , Mittwochs ,
Donnerstags , Freitags , jeweils ab 7:00 Uhr
Listing 5.9:
Identizierte Probleme, Stand 13.11.2011
Listing 5.9 zeigt zwei Meldungen, die nach diesem Verfahren identiziert und gespeichert wurden. Eine automatisierte Interpretation bezüglich des Zustandekommens wird allerdings nicht
vorgenommen. Betrachtet man aber die vorliegenden Informationen, lässt sich feststellen, dass
das erste Problem jeweils nach Heimspielen des VfL Osnabrück aufgetreten ist, während es sich
beim zweiten um den morgendlichen Arbeitsverkehr handelt, der sich von Norden in Richtung
Osnabrück bewegt.
5.3.6
Verarbeitung ungültiger Einträge
Um die Datenbasis nicht unnötig mit ungültigen Einträgen zu belasten, wird alle sechzig Minuten
ein
Service
gestartet, der einige Tabellen prüft und gegebenenfalls Datensätze löscht.
int deletedLines = s
. createQuery ( " DELETE UserData u WHERE u . road_id IS NULL " )
. executeUpdate () ;
..
int deletedClients = s
. createQuery ( " DELETE Client c WHERE c . lease < : date " )
. setParameter ( " date " , new Date ( System . currentTimeMillis () ) )
. executeUpdate () ;
..
int deletedRoutes = s
. createQuery ( " DELETE Route r WHERE not exists (
from Client c WHERE c . route = r . id ) " )
. executeUpdate () ;
Listing 5.10:
Löschen ungültiger Datensätze
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
5.3. DATENAGGREGATION UND -ANALYSE
53
Zu den betroenen Tabellen gehört unter anderem die, welche alle Daten zu Position und Geschwindigkeit der Nutzer vorhält. Da das in Kapitel 5.3.1 vorgestellte Verfahren zur Ermittlung
der zugehörigen Straÿenabschnitte nicht immer erfolgreich ist, kann es vorkommen, dass bei
einigen Datensätzen das dementsprechende Attribut einen Null-Wert beinhaltet. Dieses Fehlschlagen bei der Bearbeitung des
Closest Line Problems
kann einerseits den zugrundeliegenden
OpenStreetMap-Daten geschuldet sein oder andererseits von einer Nutzung der Anwendung in
einiger Entfernung von einer Straÿe ausgelöst werden.
Der erste Fall kann hauptsächlich in Regionen auftreten, in denen die OpenStreetMap-Abdeckung
nicht sonderlich hoch ist. Dort sind Straÿen vereinzelt nur teilweise oder überhaupt nicht erfasst
und konnten somit auch nicht beim Erstellen der Datenbasis des Servers von OpenStreetMap
importiert werden. Bewegen sich nun Anwender auf einer solchen Straÿe, werden die Daten zwar
erfasst, können aber keinem bekannten Abschnitt zugeordnet werden und sind im Rahmen der
jetzigen Implementation nutzlos.
Wird die Anwendung in einiger Entfernung zu bekannten Straÿen aktiviert, so erfolgt auch sofort
ein Senden der erfassten Informationen an den Server. Dieser ist aber so eingerichtet, dass er
Werte, die mehr als fünfzig Meter neben einer Straÿe liegen, nicht als Bewegung auf dieser
wertet. Somit kann auch in diesem Fall kein passendes Teilstück einer Straÿe ermittelt werden.
Neben den Daten, die durch die Nutzer erfasst wurden, werden auch noch die angemeldeten
Clients und die aktiven Routen überprüft. Auf diese Weise werden die Datensätze erfasst, die zu
Clients gehören, deren ID bereits abgelaufen ist und nicht erneuert wurde. Nach dem Löschen
der zugehörigen Einträge, muss noch eine abschlieÿende Überprüfung der vermerkten Routen
erfolgen. Solche, die inzwischen gelöschten Clients zugeordnet sind, können nicht mehr abgerufen
werden und werden somit aus der Datenbank gelöscht.
Listing 5.10 zeigt die Fragmente des
CleanUpDBService,
die für das Löschen der jeweiligen Ein-
träge verantwortlich sind. Hier kommt nun die dritte Möglichkeit zum Einsatz, die Hibernate
dem Entwickler bietet um mit der Datenbank zu kommunizieren: Die
ge.
Hibernate Query Langua-
Diese ist dem herkömmlichem SQL sehr ähnlich, erlaubt es aber Anfragen auf Objektbasis
zu stellen und hat Kenntnis von den Beziehungen dieser untereinander.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 6
Android-Client
Die Android-Applikation
TracJamDroid stellt den Client im Gesamtsystem dar und übernimmt
vielseitige Aufgaben. Neben der Visualisierung der vorliegenden Verkehrsussdaten, erfolgt mit
dem Smartphone auch ein Groÿteil der Datenerfassung. Da diese aber nicht immer automatisiert
geschehen kann, wird neben den Hintergrundprozessen auf eine Interaktion der Nutzer gesetzt.
Abbildung 6.1:
Starticon der Android-Applikation TracJamDroid
Dem Anwender stehen innerhalb der Applikation sechs verschiedene Komponenten zur Verfügung, die jeweils für eine spezielle Aufgabe zuständig sind und nur zum Teil eine Nutzerinteraktion erfordern. Die Basis bildet dabei die Straÿenkarte, auf der alle vorliegenden Daten zum
aktuellen Verkehrsgeschehen visualisiert werden. Des Weiteren stehen dem Anwender Oberächen für die Meldung von Störungen, sowie die Erfassung neuer Routen zu Verfügung. Während
diese Komponenten ohne eine Interaktion von Seiten des Nutzers keinerlei Verwendbarkeit aufweisen, haben die Anzeige der serverseitig identizierten Problemstellen in der Verkehrsführung
und die Online-Hilfe lediglich rein informativen Charakter.
Der sechste und letzte Bestandteil der Anwendung muss dagegen separat betrachtet werden.
So stellt die Einstellungsseite zwar auch eine Oberäche zur Nutzerinteraktion zur Verfügung,
ist aber nicht im Rahmen dieser Arbeit erstellt worden, sondern bereits in der Android API
implementiert. Lediglich eine Anpassung auf die anzuzeigenden Optionen zu Privatsphäre und
Umfang der übertragenen Daten muss hier erfolgen.
55
56
KAPITEL 6. ANDROID-CLIENT
6.1 Das Android-Manifest
Bevor auf die einzelnen Komponenten des Clients genauer eingegangen wird, soll an dieser Stelle
zuerst das Manifest der Android-Applikation behandelt werden.
<? xml version = " 1.0 " encoding = " utf -8 " ? >
< manifest xmlns:android = " http: // schemas . android . com / apk / res / android "
android:versionCode = " 1 " android:versionName = " 1.0 " package = " org .
traffic . jamdroid " >
< uses - sdk android:minSdkVersion = " 8 " / >
< application android:icon = " @drawable / icon " android:label = " @string /
app_name " android:theme = " @style / app_theme " >
< activity android:name = " . TrafficJamDroidActivity " android:theme = "
@android:style / Theme . NoTitleBar . Fullscreen "
android:screenOrientation = " landscape " >
< intent - filter >
< action android:name = " android . intent . action . MAIN " / >
< category android:name = " android . intent . category . LAUNCHER " / >
</ intent - filter >
</ activity >
< activity android:name = " . activities . RoutingActivity " android:theme = "
@android:style / Theme . NoTitleBar . Fullscreen "
android:screenOrientation = " landscape " / >
...
</ application >
< uses - permission
< uses - permission
< uses - permission
< uses - permission
</ manifest >
name = " android . permission . ACCESS_FINE_LOCATION " / >
name = " android . permission . INTERNET " / >
name = " android . permission . WRITE_EXTERNAL_STORAGE " / >
name = " android . permission . WAKE_LOCK " / >
Listing 6.1:
Auszug aus der Manifest-Datei der Applikation
Listing 6.1 zeigt einen Auszug der zugehörigen Datei, in der aus Gründen der Übersichtlichkeit
nur zwei der vorhandenen Activities angeführt sind. Die
TrafficJamDroidActivity
dient dabei
als Einsprungspunkt der gesamten Applikation und wird mit den zugehörigen Filtern für interne
Nachrichten versehen. Auÿerdem soll sie den gesamten Bildschirm nutzen und im Querformat
dargestellt werden. Die
RoutingActivity ist beispielhaft für alle weiteren Activities. Sie benötigt
keine Intent-Filter und verfügt nur über die bereits vorgestellten Attribute.
Neben den Activities sind im Manifest auch die Systemberechtigungen vermerkt, die das Programm für seinen Funktionsumfang benötigt. Die Permission
ACCESS_FINE_LOCATION
erlaubt
den Zugri auf Dienste zur exakten Ortsbestimmung, wie beispielsweise das GPS. Schnell ersichtlich ist auch die Notwendigkeit des Zugris auf das Internet, da dieses für die gesamte
Kommunikation mit dem Server benötigt wird. Der schreibende Zugri auf externen Speicher,
wie eine SD-Karte, wird verwendet um die Datenbanken mit den Beschreibungen der einzelnen
Straÿenabschnitte zu speichern (vergleiche Kapitel 5.1.1). Verfügt das Gerät über kein zusätzli-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.2. DATENVERWALTUNG
57
ches Speichermedium, kann die Anwendung aber trotzdem genutzt werden.
TracJamDroid
legt
in diesem Fall die Dateien im internen Speicher ab und kann somit Zugri auf die notwendigen
Informationen erlangen. Die letzte gesetzte Permission ist
WAKE_LOCK. Diese versetzt die Anwen-
dung in die Lage zu verhindern, dass das Gerät zum Stromsparen den Bildschirm abschaltet und
die Anwendung zum Pausieren bringt. Da die Anwendung aber während der Fahrt als eine Art
Navigationssystem verwendet wird und der Stromsparmodus nur durch eine regelmäÿige Aktion
des Benutzers zu verhindern wäre, ist ein solches Verhalten nicht erstrebenswert und kann nun
durch das Setzen dieser Permission und der damit verbundenen Implementation unterbunden
werden.
6.2 Datenverwaltung
Die wichtigsten Klassen im Bereich der Datenverwaltung stellen
LocalData und RemoteData dar.
Sie kapseln nahezu alle Informationen, die zur Laufzeit der Anwendung benötigt werden und
vom Gerät selber erfasst oder vom Server empfangen wurden. Beide Klassen sind als
Singleton
implementiert, was bedeutet, dass von ihnen zur Laufzeit nur maximal eine Instanz existieren
darf. Allerdings gibt es auch Verallgemeinerungen dieses Entwurfsmusters, die einen variablen
Maximalwert erlauben.
Abbildung 6.2:
UML-Klassendiagramm einer üblichen Singleton-Umsetzung
Abbildung 6.2 zeigt, wie eine Umsetzung dieses Konzeptes in Java mittels statischer Methoden
erfolgen kann. Dabei wird die direkte Instanziierung des Objektes über den Standardkonstruktor
verhindert, indem für diesen die Sichtbarkeit auf die eigene Klasse beschränkt wird. Um jetzt
aber auch auÿerhalb der Klasse eine Instanz anfordern zu können, wird in der Regel eine statische
Methode namens
getInstance bereitgestellt, welche die einzige Instanz der Klasse zurückliefert.
private-
Diese wiederum wird als statisches Attribut der Klasse gespeichert und ebenfalls per
modier vor dem Zugri von auÿerhalb der Klasse geschützt.
Für die eigentliche Instanziierung des Objektes stehen zwei Möglichkeiten zur Auswahl. Zum
einen ist dies die
lazy initialization, bei der das Objekt erzeugt wird, wenn es erstmalig angefordert
wird. Der Vorteil einer solchen Umsetzung liegt darin, dass, wenn die Methode
getInstance
niemals aufgerufen wird, auch kein Speicher belegt wird. In Multithreadingumgebungen stöÿt sie
aber schnell an ihre Grenzen, da es passieren kann, dass zwei oder mehr Threads gleichzeitig den
erstmaligen Aufruf der Klasse durchführen.
Die, auch im Rahmen dieser Anwendung verwendete, zweite Möglichkeit begegnet diesem Problem dadurch, dass die Instanz der Klasse bereits beim erstmaligen Zugri durch die JVM erzeugt
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
58
KAPITEL 6. ANDROID-CLIENT
wird. Somit wird zwar unabhängig vom Aufruf der Klasse Speicher belegt, was aber im Rahmen der hier erstellten Applikation zu vernachlässigen ist, da Instanzen beider Klassen zu einem
späteren Zeitpunkt zwangsläug benötigt werden.
Neben der Vorhaltung von erfassten Daten muss der Client auch noch Zugri auf die in Kapitel
5.1.1 erzeugten Datenbanken erhalten. Als problematisch erweist sich hierbei die unbekannte
Zahl von Dateien, welche als potentielle Speicherplätze für den gerade benötigten Straÿenverlauf
in Frage kommen. Um nun auf Basis der vom Server übertragenen Straÿen-ID eine performante
Ermittlung der Daten zu gewährleisten, hält die Klasse
DBWrapper eine Liste vor, in der zu jeder
bekannten Datenbank die minimale und die maximale ID vermerkt sind. Somit wird die komplexe
Suche nach der passenden Datenbank auf eine Bereichssuche reduziert und die benötigte Zeit für
diese Operation wird im Rahmen einer Aktualisierung der GUI vernachlässigbar.
6.2.1
Positionsbestimmung
Um auf androidbasierten Smartphones eine Positionsbestimmung durchzuführen, wird der Sys-
LocationManager verwendet, welcher über den Kontext der Applikation mit der Methode getSystemService(String) und dem Parameter Context.LOCATION_SERVICE erfragt wer-
temdienst
den kann.
LocationManager mLocationManager = ( LocationManager ) ctx .
getSystemService ( Context . LOCATION_SERVICE ) ;
...
for ( final String provider : mLocationManager . getProviders ( true ) ) {
if ( LocationManager . GPS_PROVIDER . equals ( provider ) || LocationManager .
NETWORK_PROVIDER . equals ( provider ) ) {
mLocationManager . requestLocationUpdates ( provider , pUpdateTime ,
pUpdateDistance , this ) ;
}
}
Listing 6.2:
Aktivierung des LocationManagers
In Listing 6.2 sieht man nun, wie mit der Methode
getProviders(boolean) eine Liste aller Pro-
vider für Lokalisierungsdienste ermittelt wird, für die die Anwendung im Manifest ein Nutzungsrecht beantragt hat. Durch das Setzen des Übergabeparameters erfolgt dabei eine Beschränkung
auf aktive Provider.
Anschlieÿend wird die Ergebnismenge auf ein Vorhandensein der Strings
NETWORK_PROVIDER
GPS_PROVIDER
oder
überprüft. Werden sie gefunden, so meldet sich letztendlich die Applikation
mit Hilfe der Methode
equestLocationUpdates(String, long, float, LocationListener)
bei ihnen an. Als Parameter werden dabei der Namen des zu beobachtenden Providers, der minimalen Zeitabstand zwischen zwei Positionsermittlungen in Millisekunden und eine Entfernung in
Metern zwischen der letzten erfassten Position und der aktuellen erwartet. Während das Setzen
der Entfernung lediglich Auswirkungen auf die Häugkeit von Meldungen hat, wirkt sich der
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.2. DATENVERWALTUNG
59
Parameter Zeit direkt darauf aus, in welchem Abstand der Dienst aktiviert wird. Eine hohe Aktualisierungsrate geht dabei auch automatisch mit einer Steigerung des Stromverbrauchs einher
und hat somit zur Folge, dass die Laufzeit des Gerätes abnimmt. Der letzte Parameter erwartet
eine Referenz auf eine Instanz vom Typ
LocationListener, die wiederum die Callback-Methoden
für den Dienst beinhaltet.
Zu dieser Funktionalität gehört unter anderem auch die Methode
onLocationChanged(Location),
mit welcher eine neue Position vom Provider entgegengenommen werden kann. Zu den in der
Klasse
Location gespeicherten Informationen können dabei neben der Geokoordinate der Erfas-
sung auch noch Geschwindigkeit, Zeitpunkt und Bewegungsrichtung gehören.
Im Rahmen dieser Applikation wird ein Groÿteil der vorgestellten Funktionen bereits durch die
OSMDroid-Bibliothek mitgeliefert. So initialisiert beispielsweise die Klasse
MyLocationOverlay
die Anmeldung am Lokalisierungsdienst und stellt auch die benötigten Callback-Methoden zur
Verfügung. Um allerdings die Werte noch zusätzlich in
LocalData bis zur nächsten Serveranfrage
onLocationChanged(Location) um
vorzuhalten, wird die Klasse überschrieben und die Methode
die Funktionen zur Speicherung der Daten ergänzt.
6.2.2
Overlays und Overlay Items
Eigentlich handelt es sich bei
Overlay und OverlayItem um Klassen der OSMDroid-Bibliothek,
die für die Visualisierung von Informationen auf einer Übersichtskarte zur Verfügung stehen. Im
Rahmen dieser Anwendung werden sie aber aus Gründen der Performance und Übersichtlichkeit
auch zur Speicherung von Daten eingesetzt, so dass an dieser Stelle eine kurze Betrachtung des
zugrunde liegenden Konzepts erfolgen soll.
(a) Overlay mit einer Meldung
Abbildung 6.3:
(b) Overlay Items mit jeweils einer Meldung
Unterscheidung von Overlays und Overlay Items
Abbildung 6.3(a) zeigt wie unter Verwendung eines Overlays eine Verkehrsstörung auf die Übersichtskarte gezeichnet wird und dabei auch die komplette freie Fläche überdeckt wird. Weitere
Instanzen dieser Klasse würden sich ebenso verhalten, so dass am Ende die gesamte Karte von
einem Stapel an Overlays abgedeckt wäre. Sobald die reine Anzeige um Nutzerinteraktion erweitert wird, stöÿt dieses Konzept jedoch an seine Grenzen. Soll beispielsweise auf einen Klick
auf eines der Elemente durch die Anzeige eines Pop-up-Fensters mit zusätzlichen Informationen
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
60
KAPITEL 6. ANDROID-CLIENT
reagiert werden, so fühlt sich jedes Overlay für den angeklickten Bereich verantwortlich und kann
erst nach einer genaue Prüfung entscheiden, ob es auf den Klick reagieren darf oder ob es das
Event an das nächste Overlay im Stapel weiterleiten muss.
Instanzen der Klasse
OverlayItem
verhalten sich etwas anders. Wie in Abbildung 6.3(b) zu se-
hen ist, beansprucht ein Objekt nur den Platz, den es auch wirklich für die Darstellung seiner
Informationen benötigt. Allerdings können Overlay Items nicht direkt auf eine Karte gezeichnet
werden, sondern brauchen immer ein umschlieÿendes Overlay, welches wiederum mehrere gleichartige Items parallel verwalten kann. Auch die Nutzerinteraktion wird so erheblich vereinfacht,
da zum einen die Anzahl Elemente, die sich für einen Bereich verantwortlich fühlen, reduziert
wird und zum anderen, weil die einzelnen Overlays nicht mehr aufwendig berechnen müssen, ob
sie an der angeklickten Stelle Informationen zur Verfügung stellen. Diese Aufgabe wird nun an
die Items übertragen, welche aber ihre eigene Position und Gröÿe kennen und somit sofort eine
Aussage darüber treen können, ob sie betroen sind oder nicht.
Im Rahmen dieser Anwendung werden nun beide Ansätze miteinander kombiniert und abhängig von ihrem Einsatzzweck verwendet. Die Entscheidung, für die unterschiedlichen Konzepte ist
dabei davon abhängig, ob es sich um eine reine Anzeige handelt, oder ob Nutzerinteraktion ermöglicht werden soll. Die bereits im vorherigen Abschnitt kurz erwähnte Klasse
MyLocationOverlay
ist dabei ein Beispiel für den Einsatz eines Overlays, während die Informationen zu Straÿenauslastung, Verkehrsstörungen und Routing in von
OverlayItem
abgeleiteten Klassen gekapselt
werden.
6.2.3
Verkehrsinformationen
Grundsätzlich verfügt der Client nur über die von ihm selbst erfassten Informationen. Alle weiteren Daten wurden vom Server gesammelt, einer Aufbereitung unterzogen und allen Clients wieder zur Verfügung gestellt. Da die hierfür notwendigen Schritte aber bereits eingehend behandelt
wurden, soll an dieser Stelle nur auf die Form der Speicherung innerhalb der Client-Anwendung
eingegangen werden.
Der Server schickt bei einer Aktualisierungsanfrage als Antwort ein JSON-Objekt, welches wiederum bis zu drei weitere Objekte kapseln kann. Der einzige feste Bestandteil ist dabei ein Array
mit den Verkehrsussdaten für die Straÿen in der näheren Umgebung des Anwenders. Die Informationen zu Staus, Unfällen oder zum Routing sind dagegen nur optional und werden nur an
die Antwort angehängt, wenn sie auch wirklich existieren.
{
}
" congestions " : [
{ " id " : 38 , " time " : 1321528173122 , " lon " : 8.38755 , " type " : 0 ,
" lat " : 52.328674}] ,
" traffic " : [
{ " id " : 51084 , " speed " : 41 , " quality " : 0 , " maxspeed " : 50}] ,
" routing " : true
Listing 6.3:
JSON-Antwort auf eine Aktualisierungsanfrage
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.3. HINTERGRUNDPROZESSE
61
Die in Listing 6.3 abgebildete Serverantwort beinhaltet alle drei Objekte, aus welchen vom Client
nun die verschiedenen graschen Elemente erzeugt werden können. Dabei zeigt sich schon an
Struktur und Umfang der übermittelten Daten, dass sich die Instanziierungen der jeweiligen
GUI-Klassen stark voneinander unterscheiden müssen, während sie auf der Übersichtskarte alle
durch Overlay Items repräsentiert werden.
Die Elemente des
congestions-Arrays verfügen beispielsweise bereits über alle benötigten Werte
um ein Item zu erstellen. Bei der Auslastungsanzeige für die einzelnen Straÿenabschnitte fehlt
jedoch noch die wesentliche Information zu den Geokoordinaten und beim Routing sind an
dieser Stelle sogar gar keine Daten auÿer einem Flag überliefert worden. Aus diesem Grund
unterscheiden sich auch die Verfahren zur Erzeugung der jeweiligen Overlays voneinander und
eine genauere Betrachtung der jeweiligen Prozesse erfolgt in den Kapiteln zu den zugehörigen
Komponenten. Da es sich aber immer um Unterklassen von
Overlay
OverlayItem handelt,
RemoteData gespeichert
und
können alle erzeugten Instanzen in einer typisierten Liste in der Klasse
werden.
6.3 Hintergrundprozesse
Wie bereits eingangs dieses Kapitels erwähnt, soll ein Groÿteil der Anwendungslogik durch Hintergrundprozesse verarbeitet werden. Dies soll zum einen verhindern, dass der Anwender während
der Fahrt mit dem PKW zu einer Interaktion mit seinem Smartphone gezwungen wird und zum
anderen soll eine Entlastung des Nutzerinterfaces erreicht werden, welches bei einer zu starken
Beanspruchung des zugehörigen Threads immer wieder blockiert wäre.
public void run () {
new RefreshIDTask () . execute ( context ) ;
new UpdateDBTask () . execute ( context ) ;
new UpdateGPSTask () . execute ( context ) ;
...
handler . postDelayed ( this , 30000) ;
}
Listing 6.4:
Arbeitsweise der Klasse DataUpdater
Wie bereits in Kapitel 2.3.6 ausgeführt, gibt es verschiedene Vorgehensweisen um diesem Problem
entgegenzuwirken. Im Rahmen dieser Anwendung wird nun das in [And11b] vorgestellte Konzept
der
die
Background-
oder
Worker-Threads
TrafficJamDroidActivity
in einer leicht abgeänderten Form eingesetzt, bei der
als zentrales Kontrollelement zum Einsatz kommt. Sie besitzt
einen Handler und eine Referenz auf eine Instanz der Klasse
das Interface
onResume
Runnable
DataUpdater,
welche wiederum
implementiert. Wird nun die Activity mittels ihrer Callback-Methode
in den Vordergrund geholt, so wird der Update-Prozess an den Handler übergeben
und mit einer Verzögerung von einer Sekunde gestartet. Dieser neue Prozess steht allerdings
immer noch in Verbindung mit dem UI-Thread und würde diesen auch bei starker Beanspruchung
blockieren.Um dies zu verhindern, werden aus dem Update-Prozess heraus nur asynchrone Tasks
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
62
KAPITEL 6. ANDROID-CLIENT
erzeugt, die dann die eigentlich Arbeit in von der GUI komplett getrennten Prozessen durchführen
und ihre Ergebnisse in den bereits vorgestellten Klassen zur Datenhaltung hinterlegen.
Listing 6.4 zeigt auch, wie nach einem kompletten Durchlauf der gesamten Prozess mit einer
Zeitverzögerung von dreiÿig Sekunden erneut gestartet wird. Würde es sich um normale JavaThreads handeln, wäre eine Umsetzung der
Aufruf von
Thread.sleep(30000)
run-Methode
mit einer Endlosschleife und einem
sicherlich die gängige Vorgehensweise, bei einer Implementa-
tion unter Android würde dies aber bedeuteten, dass die GUI dreiÿig Sekunden lang auf keine
Nutzerinteraktion reagiert.
Um bei der hier gewählten Implementation zu verhindern, dass der Update-Prozess auch noch
nach Beendigung der gesamten Applikation weiterläuft, wird in der
onPause-Methode
der zen-
tralen Activity der Thread wieder vom zugehörigen Handler entfernt (siehe auch Kapitel 2.3.5).
6.3.1
Verwaltung der ID
Wie bereits in den Kapiteln zum Server angeführt, benötigt der Client für die Kommunikation
eine eindeutige ID. Um zu verhindern, dass auf Basis dieses Wertes komplexe Bewegungsprole
der Anwender erstellt werden können, haben die IDs nur eine begrenzte Lebensdauer von maximal
zwölf Stunden und müssen bei einer längeren Nutzung dementsprechend aktualisiert werden.
Für die Verarbeitung der damit zusammenhängenden Serverkommunikation stellt die Anwendung zwei verschiedene Tasks zur Verfügung: den
HandshakeTask
Handshakes
HandshakeTask
und den
RefreshIDTask.
übernimmt dabei die in Kapitel 4.2 dargelegte Funktionalität des
Der
Three-Way-
und wird im Normalfall nur einmal bei der Initialisierung der gesamten Anwen-
dung aufgerufen. Die gesamte Logik für die Aktualisierung der ID bendet sich dagegen im
RefreshIDTask,
welcher, wie in Listing 6.4 dargestellt, ein Teil des ständigen Update-Prozesses
ist. Intern überprüft er dann die Lebensdauer der zugewiesenen ID und reagiert im Bedarfsfall
mit einer Aktualisierungsanfrage an den Server. Da dieser Prozess bereits eine halbe Stunde vor
Ablauf der Gültigkeit einsetzt und so gegebenenfalls ausreichend Zeit für weitere Verbindungsversuche vorhanden ist, wird an dieser Stelle vom Overhead des Handshake-Verfahrens abgesehen.
Ist die ID allerdings bereits abgelaufen, initialisiert der Update-Prozess einen neuen Handshake
und stellt somit sicher, dass alle weiteren ausgehenden Nachrichten eine registrierte Kennung
verwenden können.
6.3.2
Aktualisierung der Daten
Neben der regelmäÿigen Kontrolle der ID initialisiert der Update-Prozess auch alle anderen
Aktualisierungs- und Überwachungsaufgaben. So startet er beispielsweise die Tasks für die Verwaltung der vorhandenen SQLite-Datenbanken und für die Serverkommunikation.
Der
UpdateDBTask
ermittelt dabei zuerst die minimalen und maximalen Werte für Längen- und
Breitengrad auf der angezeigten Übersichtskarte. Anschlieÿend erfolgt eine Prüfung, ob die für
diesen Bereich benötigten SQLite-Datenbanken bereits auf dem Gerät vorliegen. Ist dies nicht
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.3. HINTERGRUNDPROZESSE
63
der Fall, wird für die fehlende Datei ein Downloadvorgang angestoÿen, der sich dann mit einem
Fileserver verbinden und eine GZIP-komprimierte Datei herunterlädt. Diese wird im letzten
Schritt vom laufenden Task entpackt und entweder im lokalen Speicher oder falls vorhanden auf
der SD-Karte abgelegt.
Abbildung 6.4:
Prozessablauf: Bearbeitung eines Update-Requests durch den Client
Die Aktualisierung der Straÿendaten erfolgt in einem vierstugen Prozess und wird durch den
UpdateGPSTask
gesteuert. Zuerst wird hier eine Anfrage, welche Position und Geschwindigkeit
des Clients enthält, an den Server gerichtet und erhält als Antwort ein JSON-Objekt, aus welchem
anschlieÿend in verschiedenen Aufarbeitungsroutinen anzeigbare Elemente erzeugt werden.
Abbildung 6.4 zeigt, dass zuerst eine Kontrolle bezüglich der Verkehrsdaten erfolgt. Da diese
Daten aber fester Bestandteil der Antwort des Servers sein müssen, dient die Überprüfung mehr
zur Kontrolle der Struktur des JSON-Objektes als seinem Vorhandensein. Bei der Betrachtung
der möglichen Verkehrsstörungen sieht es dagegen anders aus. Diese Informationen werden nur
mitgeliefert, wenn Meldungen für einen bestimmten Umkreis um den Anwender herum vorliegen
und auch nur in diesem Fall darf versucht werden, aus den gegebenen JSON-Objekten Overlays
für die Übersichtskarte zu erzeugen.
Der komplexeste Teil, die Aktualisierung des Routings, ist in einen eigenen Task ausgelagert.
Dieser wird ausgeführt, wenn der
UpdateGPSTask in den eingegangenen Daten das Flag routing
identiziert hat, welches ihm mitteilt, dass sich die für diesen Client registrierte Route aufgrund
von vorliegenden Verkehrsproblemen geändert hat. Die eigentliche Aktualisierung der Route besteht dann aus einer neuen Anfrage an den Server, die eine Liste mit Geokoordinaten zurückliefert, aus welchen wiederum ein weiteres Overlay erzeugt wird.
Diese Ausgliederung des Routen-Updates soll verhindern, dass die Bearbeitung einer Aktualisie-
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
64
KAPITEL 6. ANDROID-CLIENT
rungsanfrage noch nicht abgeschlossen ist und bereits in einem zweiten Prozess eine weitere an
den Server gesendet wird. Eine solche Überschneidung könnte nämlich ungewollte Seiteneekte
erzeugen und zu Problemen beim Setzen von serverseitigen Flags und bei der Aktualisierung der
Übersichtskarte führen.
6.4 Streckenauslastung
Die Streckenauslastung bildet das zentrale Element von
TracJamDroid
und besteht aus den in
Abbildung 6.5 gezeigten drei wesentlichen Bestandteilen: der Übersichtskarte, den Informationen
über den aktuellen Abschnitt und den Werten zu Geschwindigkeit und aktuell befahrener Straÿe.
Abbildung 6.5:
Streckenauslastung
Bereits beim Start wird dem Anwender diese Ansicht zur Verfügung gestellt und es benötigt
keine weitere Interaktion um die Applikation während der Fahrt nutzen zu können. Lediglich
für die Verwendung des Routings oder zum Melden von Verkehrsproblemen muss der Nutzer
diese Ansicht verlassen, wird aber nach Abschluss der jeweiligen Aktion sofort wieder zu ihr
zurückgeführt. Diese Umsetzung liegt darin begründet, dass eine Ablenkung des Fahrers durch
die Applikation verhindert werden soll und dass er trotzdem alle wesentlichen Informationen zur
Verfügung gestellt bekommt.
Da auÿerdem nach deutschen Verkehrsrecht die Interaktion mit einem Smartphone oder auch Navigationssystem während der Fahrt verboten ist, können alle anderen Komponenten auch genutzt
werden, wenn das Fahrzeug nicht in Bewegung ist. Lediglich eine bestehende Internetverbindung
wird vorausgesetzt.
Betrachtet man nun die einzelnen Bestandteile dieser Ansicht, zeigt sich, dass in der Kopfzeile nur Informationen bezüglich des Clients angezeigt werden, während Übersichtkarte und die
Betrachtung des aktuellen Straÿenabschnittes auf vom Server bereitgestellten Daten beruhen.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.4. STRECKENAUSLASTUNG
65
Um nun die benötigten Werte von den Sensoren des Smartphones zu ermitteln, stellt die AndroidAPI verschiedene Klassen zur Verfügung. Während jedoch die aktuelle Geschwindigkeit direkt
von der Klasse
Location
bereitgestellt wird, erfordert die Anzeige des Straÿennamens eine vor-
herige Aufbereitung der vorhandenen Daten. Grundsätzlich ist es zwar möglich eine sofortige
Angabe der Position zu machen, da diese dem Gerät aber nur als Geokoordinate vorliegt, wäre
sie für die meisten Anwender ohne Aussagekraft. Aus diesem Grund stellt die Android-API die
Klasse
Geocoder
zur Verfügung, welche verschiedene Methoden sowohl für das Geocoding als
auch das Reverse Geocoding beinhaltet. In diesem konkreten Fall kann nun unter Verwendung
von
getFromLocation
die Ermittlung eines Straÿennamens auf Basis von Längen- und Breiten-
grad erfolgen.
6.4.1
Informationen zum aktuellen Abschnitt
Die Anzeige der vorliegenden Informationen für den aktuell befahrenen Straÿenabschnitt ist
mit drei Graken umgesetzt, welche jeweils einen anderen Teil der vom Server gelieferten Daten
repräsentieren. Die Visualisierung der Geschwindigkeiten erfolgt dabei mittels den in Deutschland
üblichen Verkehrszeichen für Tempolimit und Richtgeschwindigkeit, die mit den vom Server
gelieferten Daten kombiniert werden.
{ " id " : 35125 , " speed " : 48 , " maxspeed " : 50 , " quality " : 2}
Listing 6.5:
Eingehende Daten vom Server für einen Straÿenabschnitt
Listing 6.5 zeigt, dass jeder Datensatz noch zusätzlich über ein Attribut
quality verfügt, welches
verwendet wird, um dem Anwender die Aktualität der angezeigten Geschwindigkeitswerte zu vermitteln. Die Visualisierung der drei möglichen Abstufungen erfolgt ebenfalls über Graken: Eine
Uhr identiziert dabei Werte von sehr hoher Aktualität, während verschiedene Kalenderformen
bei gröÿeren Interpolationszeiträumen verwendet werden.
Werte der letzten
Werte des gleichen
Alle vorhandenen
Stunde
Wochentages
Werte
Tabelle 6.1:
Abstufungen der verwendeten Aktualitätsgrade
Da es sich bei den Werten für die Geschwindigkeitsbegrenzungen gröÿtenteils um von OpenStreetMap importierte Daten handelt, ist nicht immer sichergestellt, dass der Server einen kompletten Datensatz ausliefert. Ähnlich verhält es sich mit den Informationen zu den empfohlenen
Geschwindigkeiten, wo das zugehörige Attribut ebenfalls nicht übergeben werden kann, wenn
eine Straÿe zum ersten Mal befahren wird. Der Client reagiert auf dieses Fehlen von Informationen, indem er für die entsprechenden Werte ein Fragezeichen anzeigt. Auÿerdem kommt dem
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
66
KAPITEL 6. ANDROID-CLIENT
Client noch eine zweite Aufbereitungsfunktion zu, da er sicherstellen muss, dass die angezeigte
Geschwindigkeitsempfehlung nicht über dem gegebenen Tempolimit liegt.
6.4.2
Übersichtskarte und Overlays
Für die Anzeige der Übersichtskarte wird die Klasse
MapView
eingesetzt, welche ein Bestandteil
der OSMDroid-Bibliothek ist und Funktionen zum Zoomen und Scrollen, sowie eine MultitouchUmgebung auf Basis von OpenStreetMap-Daten zur Verfügung stellt. Sie wird analog zu allen
anderen GUI-Komponenten in ein XML-Layout eingebunden und kann dann aus der zugehörigen
Activity mit weiteren Daten, wie beispielsweise Overlays, versorgt werden.
LocationOverlay und das für die einzelLocationOverlay dient zur Anzeige der
eigenen Position, sowie der Fahrtrichtung und ist von der OSMDroid-Klasse MyLocationOverlay
Abbildung 6.5 zeigt zwei der eingesetzten Overlays: das
nen Straÿenabschnitte zuständigen
RoadOverlay.
Das
abgeleitet. Diese Vererbung wird allerdings nur notwendig, um eine Speicherung der ermittelten
Positionsdaten für die nächste Serveranfrage vornehmen zu können. Alle anderen benötigten
Funktionen wie das Zentrieren der Karte auf die aktuelle Position und das Folgen der Bewegung
des Anwenders sind bereits implementiert und können direkt verwendet werden.
Beim
RoadOverlay handelt es sich um ein Overlay, welches der Denition aus Kapitel 6.2.2 folgt
SpeedOverlayItem,
und somit wiederum eine Menge an Overlay Items, hier Instanzen der Klasse
beinhaltet. Jedes dieser Items steht dabei für einen Straÿenabschnitt und erzeugt aus den Informationen zu Tempolimit und errechneter möglicher Geschwindigkeit eine farbige Linie. In
Abbildung 6.5 sieht man nun zum einen das gesamte zur Verfügung stehende Farbspektrum
von Grün über Gelb bis Rot und zum anderen, dass aus den vorliegenden Daten auch noch
ein Pop-up-Fenster, ein sogenannter Toast, generiert werden kann. Die abgebildeten Information
wurden dabei von einem Klick auf den orangen Streckenabschnitt hervorgerufen und zeigen die
zugehörigen Werte.
6.4.3
Beispielimplementation: SpeedOverlayItem und RoadOverlay
In diesem Abschnitt sollen beispielhaft einige Teile der Umsetzung mit Overlay Items und Overlays betrachtet werden, die bei der Umwandlung der eingehenden Daten hinzu graphischen Komponenten eine Rolle spielen.
private static int calculateColor ( final double speed , final double
maxSpeed ) {
if ( speed < 0 || maxSpeed < 0) {
return Color . WHITE ;
}
return Converter . formatHueToRGB (( float ) Math . max ( Math . min ( speed /
maxSpeed * 120 , 120) , 0) ) ;
}
Listing 6.6:
Berechnung der Farbe in der Klasse SpeedOverlayItem
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.4. STRECKENAUSLASTUNG
67
In einem ersten Schritt muss aus den Werten für Tempolimit und Durchschnittsgeschwindigkeit
die Farbe eines Items berechnet werden. Da diese aus dem Farbverlauf Grün-Gelb-Rot stammen
soll, wird für die Umrechnung das HSV-Farbmodell verwendet. Listing 6.6 zeigt, wie die eingehenden Werten zuerst einer Vollständigkeitsprüfung unterzogen werden. Fehlt einer der Werte,
vom Server wurde also ein negativer Wert übertragen, so wird das Overlay Item weiÿ eingefärbt. Andernfalls wird das Verhältnis von idealer zu maximaler Geschwindigkeit berechnet und
auf einen Wertebereich von Null bis Einhundertzwanzig abgebildet, was im HSV-Modell den
Farbtonwerten für Rot (Null), Gelb (Sechzig) und Grün (Einhundertzwanzig) entspricht. In der
Converter-Klasse
wird dann aus dem so ermittelten Farbton, voller Helligkeit und Sättigung
eine RGB-Farbe erzeugt, die später zum Zeichnen der Linie genutzt werden kann.
public List < GeoPoint > fetchPoints ( final int id ) {
final Borders search = new Borders ( id , id ) ;
if ( databases . get ( search ) != null ) {
SQLiteDatabase db = SQLiteDatabase . openOrCreateDatabase ( databases .
get ( search ) , null ) ;
if ( db != null ) {
Cursor c = db . rawQuery ( SELECT_SQL , new String [] { " " + id }) ;
if ( c != null ) {
c . moveToFirst () ;
String linestring = c . getString ( c . getColumnIndex ( " way " ) ) ;
return extractPoints ( linestring ) ;
}
}
}
return new LinkedList < GeoPoint >() ;
}
private List < GeoPoint > extractPoints ( String linestring ) {
final List < GeoPoint > points = new LinkedList < GeoPoint >() ;
linestring = linestring . substring (12 , linestring . length () - 1) ;
String [] strPoints = linestring . split ( " ," ) ;
for ( String text : strPoints ) {
String [] pos = text . trim () . split ( " " ) ;
points . add ( new GeoPoint ( Double . parseDouble ( pos [1]) , Double .
parseDouble ( pos [0]) ) ) ;
}
return points ;
}
Listing 6.7:
Ermittlung der Wegpunkte
Neben der Bestimmung der Farbe ist auch die Festlegung des Verlaufs eines Overlay Items wesentlich. Da die hierfür benötigten Koordinaten aber nicht vom Server übertragen werden, müssen
sie aus den lokalen Datenbanken geladen werden. Listing 6.7 zeigt, wie mittels der Methode
fetchPoints zuerst die passende SQLite-Datei in der Map databases gesucht und, falls vorhanden, geönet wird. Anschlieÿend wird anhand der übergebenen ID der zugehörende LineString
ermittelt. Da dieser jedoch aus Gründen der Speicher- und Zugrisezienz in rein textueller Form
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
68
KAPITEL 6. ANDROID-CLIENT
vorliegt, müssen noch mit der Methode
extractPoints die einzelnen Geokoordinaten extrahiert
werden.
Aus der so erzeugten Liste mit Punkten und der Farbangabe kann nun ein
erzeugt werden, welches anschlieÿend einem Objekt vom Typ
SpeedOverlayItem
RoadOverlay zuwiesen wird. Diese
Klasse kümmert sich neben den Zeichnen der einzelnen Items auch um die Nutzerinteraktion und
stellt hierfür die Methoden
onSingleTapUp
und
onLongPress
zur Verfügung. Erstere reagiert
auf einen einfachen Klick und prüft ob sich ein Item an der angeklickten Stelle bendet. Wird
eines gefunden, so erscheint ein Pop-up-Fenster mit den zugehörigen Daten. Andernfalls wird
das ausgelöste Event an die anderen Overlays weitergereicht. Die Methode
onLongPress reagiert
ebenfalls auf einen Klick, allerdings einen langen. Für die bisher vorgestellten Items verfügt sie
jedoch über keine Implementation, sondern wird lediglich bei der Navigation verwendet um eine
aktive Route zu löschen.
AlertDialog . Builder builder = new AlertDialog . Builder ( context ) ;
builder . setMessage ( context . getResources () . getString ( R . string .
delete_route_question ) )
. setCancelable ( false )
. setPositiveButton ( " Ja " ,
new DialogInterface . OnClickListener () {
public void onClick ( DialogInterface dialog , int id ) {
new DeleteRouteTask () . execute () ;
Toast . makeText ( context , context . getResources () . getString ( R .
string . delete_route ) , Toast . LENGTH_LONG ) . show () ;
}
})
. setNegativeButton ( " Nein " ,
new DialogInterface . OnClickListener () {
public void onClick ( DialogInterface dialog , int id ) {
dialog . cancel () ;
}
}) ;
AlertDialog alert = builder . create () ;
alert . show () ;
Listing 6.8:
Löschen einer Route
Listing 6.8 zeigt, dass der Nutzer vor dem Löschen allerdings noch einen Dialog angezeigt bekommt, in dem er um Bestätigung des Löschauftrags gebeten wird. Erfolgt diese, wird wiederum
über einen Hintergrundprozess eine Nachricht an den Server gesendet um dort die Route ebenfalls
zu löschen und den Client vom Aktualisierungsprozess der Navigation abzumelden.
Betrachtet man nun abschlieÿend noch einmal Abbildung 6.5, stellt man fest, dass es insgesamt
nur zwei Overlays auf der Übersichtskarte gibt: Zum einen die Anzeige der aktuellen Position
und zum anderen das Overlay mit den sechs Items für die Geschwindigkeitsanzeige.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.5. MELDUNG VON VERKEHRSSTÖRUNGEN
6.4.4
69
Wechsel zu anderen Komponenten
Um von der Streckenvorschau zu den anderen fünf Komponenten der Applikation zu wechseln,
steht das Programm-Menü zur Verfügung. Dieses kann mittels der Menü-Taste, die in allen
Android-Smartphones verbaut ist, aufgerufen werden und enthält Querverweise zu den anderen
implementierten Features.
Abbildung 6.6:
Menü der Applikation
Abbildung 6.6 zeigt das dann am unteren Bildschirmrand eingeblendete Menü, welches keinen
Button für die Rückkehr zur Übersichtskarte beinhaltet. Dieses Fehlen liegt darin begründet, dass
das Programm darauf ausgelegt ist, den Anwender von Seiten, die eine Interaktion erfordern,
automatisiert zurückzuleiten, während bei den rein informativen Ansichten die Zurück-Taste des
Smartphones für diese Funktion zur Verfügung steht.
6.5 Meldung von Verkehrsstörungen
Neben der völlig automatisierten Erfassung von gefahrenen Geschwindigkeiten stellt
Droid
TracJam-
auch ein Interface zur Meldung von Verkehrsproblemen zur Verfügung.
(a) Erfassung einer Störung
Abbildung 6.7:
(b) Positionieren einer Störung
Meldung von Verkehrsstörungen
Wird dieses vom Nutzer über das Anwendungsmenü aufgerufen, erhält er die in Abbildung 6.7(a)
gezeigte Oberäche, welche zum einen eine Auswahl mit den sechs verschiedenen Arten an Störungen und zum anderen die Position der Meldung enthält. Da davon ausgegangen wird, dass
der Nutzer sofort bei Erkennung eine Meldung an den Server schickt, wird für die Position initial
die aktuelle gesetzt. Allerdings muss auch hier wieder die Anwendung eine Möglichkeit bieten,
um nachträglich Meldungen vornehmen zu können.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
70
KAPITEL 6. ANDROID-CLIENT
Abbildung 6.7(b) zeigt die hierfür implementierte Ansicht, welche über dem Button neben der
Positionsangabe erreicht werden kann und zwei Möglichkeiten zum Bestimmen einer Position
anbietet. So kann diese zum einen direkt auf der angezeigten Karte durch einen Klick gesetzt
werden oder alternativ anhand einer Adresssuche identiziert werden.
Geocoder gc = new Geocoder ( SearchActivity . this ) ;
List < Address > l = new LinkedList < Address >() ;
final EditText searchfield = ( EditText ) findViewById ( R . id . searchtext ) ;
l = gc . getFromLocationName ( searchfield . getText () . toString () , 5) ;
final CharSequence [] items = new CharSequence [ l . size () ];
int i = 0;
for ( Address a : l ) {
items [ i ] = a . getAddressLine (0) + " , " + a . getAddressLine (1) + " , " + a
. getAddressLine (2) ;
i ++;
}
AlertDialog . Builder builder = new AlertDialog . Builder ( SearchActivity .
this ) ;
builder . setTitle ( R . string . routedialog ) ;
builder . setItems ( items ,
new DialogInterface . OnClickListener () {
public void onClick ( DialogInterface dialog , int item ) {
final Location loc = new Location () ;
loc . setLatitude ( l . get ( item ) . getLatitude () ) ;
loc . setLongitude ( l . get ( item ) . getLongitude () ) ;
SearchData . getInstance () . setPosition ( loc ) ;
addOverlay ( new GeoPoint ( loc ) ) ;
}
}) ;
AlertDialog alert = builder . create () ;
alert . show () ;
Listing 6.9:
Adressuche
Listing 6.9 zeigt die Umsetzung der Adresssuche. Die Klasse
getFromLocationName(String, int)
Geocoder stellt hierfür die Methode
zur Verfügung, welche anhand einer textuellen Beschrei-
bung (z.B. Albrechtstraÿe, Osnabrück) maximal die im zweiten Parameter angegebenen in Frage
kommende Positionen liefert. Diese werden dem Anwender dann in in einer Liste angezeigt, so
dass er den zutreenden Eintrag auswählen kann.
Die ausgewählte Position, egal ob über Adresssuche oder Klick identiziert, wird anschlieÿend
auf der Karte angezeigt und kann beliebig oft korrigiert werden. Sobald aber ein Klick auf
den Übernehmen-Button erfolgt, wird die Ansicht geschlossen und der zuletzt markierte Ort
übernommen.
Beim Abschluss des Meldungsvorganges wird dann eine Anfrage mit den gesetzten Werten für
Position und Typ an den Server geschickt und von diesem mit dem bereits vorgestellten Verfahren
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.5. MELDUNG VON VERKEHRSSTÖRUNGEN
71
aufbereitet. Der Client bekommt die von ihm gemeldete Störung dann beim nächsten Update
ebenfalls auf der Übersichtskarte angezeigt und kann gegebenenfalls durch eine Änderung seines
Fahrverhaltens auf sie reagieren.
6.5.1
Visualisierung und Interaktion
Für die Visualisierung der Verkehrsstörungen wird ein identisches Konzept wie bei den Streckenauslastungen gewählt. Overlay Items zeigen jeweils die einzelnen Probleme an und werden dann
in einem
ItemizedIconOverlay
zusammengefasst. Diese Klasse ist bereits Teil der OSMDroid-
Bibliothek und stellt Funktionen für die Erzeugung und Verwaltung von Overlay Items, die mit
einer Grak versehen werden, zur Verfügung. Welche Grak nun verwendet wird, ist dabei immer
vom Typ der gemeldeten Störung abhängig und kann auch innerhalb eines Overlays variieren.
(a) Anzeigen der Informationen
Abbildung 6.8:
(b) Löschen einer Meldung
Interaktion mit den Overlay Items
Der Nutzer bekommt auch hier wieder zwei Interaktionsmöglichkeiten. So kann er sich zum einen
eine textuelle Beschreibung des vorliegenden Problems durch einen einfachen Klick auf das jeweilige Item anzeigen lassen oder zum anderen durch einen langen Klick die Störung als behoben
kennzeichnen. Abbildung 6.8(b) zeigt, dass vom Anwender vor dem Löschen wieder eine Bestätigung verlangt wird, um so das versehentliche Entfernen einer Meldung zu verhindern. Wird diese
jedoch gegeben, schickt der Client eine Meldung an den Server, wo dann der eigentliche Löschvorgang erfolgt und mit den eingehenden Aktualisierungsanfragen an alle registrierten Clients
verteilt wird.
Abbildung 6.8(a) zeigt, dass neben der Visualisierung durch Overlays auch noch eine weitere
Grak in der Übersichtsleiste auf der rechten Seite auftaucht. Diese stellt jedoch keine weiteren
Interaktionsmöglichkeiten zur Verfügung, sondern soll dem Anwender lediglich das Vorhandensein von Verkehrsstörungen, die eventuell auch auÿerhalb des gezeigten Kartenausschnitts liegen,
in seiner Umgebung mitteilen.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
72
KAPITEL 6. ANDROID-CLIENT
6.6 Routing
Die Navigations-Komponente von
TracJamDroid
ermöglicht es dem Anwender sich automati-
siert um alle bekannten Verkehrsstörungen und stark befahrene Straÿen herumführen zu lassen.
Dafür steht ihm ein durch das Menü erreichbares Interface zur Verfügung, welches anhand angegebener Adressen die ideale Route vom Server berechnen lässt.
Abbildung 6.9:
Interface zur Erstellung einer Route
Abbildung 6.9 zeigt, dass die Oberäche im Wesentlichen aus einer Liste von Zielen besteht,
welche über dasselbe Interface erfasst werden wie die Positionen von Verkehrsstörungen. Allerdings dürfte die Adresssuche hier von gröÿerer Bedeutung sein, da sie ein fester Bestandteil aller
Navigationssysteme ist und somit den meisten Anwendern bekannt sein sollte.
Neben der reinen Suche nach Adressen ist es hier aber auch möglich, nach Sehenswürdigkeiten
oder anderen Zielen zu suchen. Diese werden, sofern bekannt, im Hintergrund zu einer Geokoordinate aufgelöst und können dann vom Server und später von CloudMade verarbeitet werden.
Als zusätzliche Funktionen stehen noch das Setzen der aktuellen Position als Beginn der Route,
sowie das Vertauschen der Ziele zur Verfügung. Besonders von der Möglichkeit die Reihenfolge der
Ziele zu verändern, sollte der Anwender dabei Gebrauch machen, da zum jetzigen Zeitpunkt die
Navigations-API von CloudMade strikt einen Punkt nach dem anderen ansteuert und keinerlei
Optimierungen vornimmt.
Für die Visualisierung der Route wird eine leicht modizierte Form der bereits vorgestellten
Klasse
SpeedOverlayItem
verwendet: Das
RouteOverlayItem.
Dieses zeichnet den Verlauf der
berechneten Strecke in einem leicht transparenten Schwarzton über die bereits bestehenden Overlays und erhält an Start und Ziel Markierungen, die sich vom Rest der verwendeten graphischen
Komponenten deutlich abheben. Des Weiteren stellt das
RouteOverlayItem
wieder die bereits
bekannten Interaktionsmöglichkeiten zur Verfügung. So wird bei einem kurzen Klick ein Informationstext zur Route angezeigt und ein langer Klick ermöglicht es die aktive Route zu löschen.
Auÿerdem gibt es noch zwei weitere Möglichkeiten, die zur Beendigung der Navigation führen.
Dies ist zum einen die Erstellung einer neuen Route auf dem dafür zur Verfügung stehenden
Interface und zum anderen das Erreichen des Zielpunktes der grade aktiven Route. Die hierfür notwendigen Überprüfungen erfolgen dabei komplett im Hintergrund und werden bei jeder
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.7. ANZEIGE ERKANNTER PROBLEMSTELLEN
73
Meldung einer Positionsänderung aktiv. Da aufgrund von GPS-Ungenauigkeit und möglichen
Abweichungen bei der Zielbestimmung durch den Nutzer ein genaues Erreichen der Zielposition nicht gewährleistet ist, wird die Navigation beendet, wenn eine Annäherung auf mindestens
fünfzig Meter erfolgt ist. Der Anwender wird dann über diesen Fakt informiert und das Overlay
von der Übersichtskarte entfernt.
6.6.1
Hintergrundaktualisierung
Wie bereits beschrieben, prüft der Server in regelmäÿigen Abständen alle registrierten Routen
auf ihre Gültigkeit. Erkennt er dabei, dass aufgrund vorliegender Probleme eine andere Streckenführung günstiger wäre, so speichert er diese in der Datenbank und informiert den Client bei der
nächsten Anfrage darüber.
Auch das Nachladen der neuen Route erfolgt komplett im Hintergrund ohne dass der Nutzer
davon etwas mitbekommt. Somit ist es möglich, je nach eingestellter Aktualisierungshäugkeit
des Clients und Intervall des serverseitigen Services, zeitnah Änderungen in der Navigation zu
übermitteln. Allerdings kann zum jetzigen Zeitpunkt noch nicht entschieden werden, ob sich die
Anpassung des Streckenverlaufs auf dem kommenden oder bereits abgefahrenen Teil der Route
bendet und es entsteht ein minimaler Overhead.
(a) Route zu Beginn der Navigation
Abbildung 6.10:
(b) Geänderte Route
Änderung im Routing aufgrund vorliegender Meldungen
Abbildung 6.10 zeigt beispielhaft, wie sich eine registrierte Route durch die Meldung der Vereisung einer Kanalbrücke verändern kann und dem Anwender somit in aktualisierter Form angezeigt wird.
6.7 Anzeige erkannter Problemstellen
Für die Anzeige der erkannten Problemstellen stellt
TracJamDroid
die beiden in Abbildung
6.11 gezeigten Ansichten zur Verfügung.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
74
KAPITEL 6. ANDROID-CLIENT
(a) Textuelle Information
Abbildung 6.11:
(b) Visualisierung des zweiten Eintrags
Anzeige von erkannten Problemen
Die rein textuelle Information wird dabei zuerst geladen und bietet eine Übersicht über alle vom
Server identizierten Probleme. Will der Anwender sich diese dann auch noch visualisieren lassen, kann ein Eintrag in der
ListView angeklickt werden und die zugehörigen Straÿenabschnitte
werden ermittelt und auf einer Übersichtskarte dargestellt. Da sich das für die Umsetzung verwendete Verfahren allerdings nicht von der Visualisierung der Streckenauslastung unterscheidet,
soll an dieser Stelle auf eine weitere Betrachtung der Implementation verzichtet werden.
Allerdings muss noch erwähnt werden, dass die für diesen Teil der Applikation benötigten Daten
nicht zum normalen Umfang der vom Server zur Verfügung gestellten Informationen gehören.
Sie müssen vielmehr in einer separaten Anfrage ermittelt werden und benötigen somit etwas Zeit
um für die Visualisierung aufbereitet zu werden. Um dies dem Benutzer zu vermitteln, wird ihm
ein
ProgressDialog
angezeigt, welcher durch die in Abbildung 6.11 gezeigten Ansichten ersetzt
wird, sobald alle Komponenten im Hintergrund geladen wurden.
6.8 Einstellungen
Um dem Benutzer die Möglichkeit zu geben, spezische Einstellungen zu Datenschutz und übertragener Datenmenge vornehmen zu können, stellt die Anwendung eine weitere Oberäche zu
Verfügung.
Da die Einbindung einer solchen
PreferenceActivity
jedoch bereits in der Android-API spezi-
ziert ist, muss hierfür kein groÿer Implementationsaufwand erfolgen. Lediglich eine XML-Datei
mit einer Auistung aller möglichen Einstellungen wird benötigt.
In
TracJamDroid
lassen sich die Optionen dabei in zwei Kategorien unterteilen. In einem
Block bendet sich die Einstellung zu Verbindungsart und -häugkeit, während im anderen das
serverseitige Speichern der eigenen Daten verhindert werden kann und die Möglichkeit besteht,
den Radius um die eigene Position für Updates zu erhöhen oder zu verringern.
Die gesamte Implementation von Eingabefeldern, Buttons und Listenern wird komplett gestellt
und durch einen Aufruf der Activity verwendet. Auch das Speichern der eingegebenen Werte in
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
6.9. ONLINE-HILFE
75
den Shared Preferences geschieht automatisiert.
6.9 Online-Hilfe
Bei der Online-Hilfe handelt es sich um eine kontextsensitive
WebView,
welche abhängig von
der zuletzt genutzten Komponente eine HTML-Datei mit Informationen über diese von einem
Webserver anfordert und anzeigt.
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
setContentView ( R . layout . help ) ;
}
Bundle extras = getIntent () . getExtras () ;
String anchor = extras . getString ( " param " ) ;
WebView webView = ( WebView ) findViewById ( R . id . helpview ) ;
webView . loadUrl ( " SERVERPATH / index . php ? param = " + anchor + " & lang = " +
Locale . getDefault () . getLanguage () ) ;
Listing 6.10:
Aufruf der Online-Hilfe
Listing 6.10 zeigt, wie die zugehörige Activity neben dem String, der die Komponente identiziert,
auch noch die aktuell eingestellte Sprache des Gerätes an die anzuzeigende URL anhängt. Auf
dem Webserver wird dann anhand dieser Parameter eine HTML-Datei geladen und an den Client
zur Anzeige ausgeliefert.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Kapitel 7
Weiterführende Überlegungen, Ausblick
und Fazit
Abschlieÿend lässt sich sagen, dass die zu Beginn formulierten Ziele mit den gegebenen Mitteln
umgesetzt werden konnten. Die Anwendung erkennt vorliegende Probleme und visualisiert sie auf
dem Client in einer eindeutigen Farbgebung. Auch ein grundlegendes Routing auf Basis dieser
Daten ist implementiert und funktionsfähig.
Einige Schwächen weist jedoch die vorhandene Hardware auf. So ist die Laufzeit des Testgerätes,
ein HTC Desire mit Android 2.2, stark von der Nutzungsintensität abhängig und beträgt bei
ununterbrochener Aktivität der erstellten Applikation etwa drei bis vier Stunden. Hierbei sind
insbesondere die Verwendung des GPS-Sensors und der ständige Betrieb des Displays für einen
erhöhten Energieverbrauch verantwortlich.
Auch die Verfügbarkeit der benötigten Dienste wie GPS und mobiles Netz schwanken je nach
Aufenthaltsort stark. So ist es innerhalb von Gebäuden kaum möglich ein auswertbares GPSSignal zu erhalten, während es im Freien in der Regel auf den Meter genau ist. Das mobile Netz
stellt jedoch ein gröÿeres Problem dar. Ist dieses sehr schwach, so leidet die Kommunikation mit
dem Server darunter und es kann passieren, dass eine Aktualisierung der angezeigten Daten nicht
mehr erfolgen kann.
7.1 Probleme
Das Hauptproblem der hier erfolgten Implementation liegt in der geringen Anzahl der Anwender
und damit verbunden auch in der Aktualität der Daten. So ist es mit circa zehn Testnutzern
zwar durchaus möglich wiederkehrende Probleme im Straÿenverkehr zu identizieren oder auch
in einem engen Rahmen Störungen zu erfassen, jedoch liegen für kaum einen Straÿenzug aktuelle Geschwindigkeitsmessungen vor. Damit verbunden nimmt die Aussagekraft der angezeigten
Werte stark ab und auch die Routingfunktionalität ist nur noch eingeschränkt nutzbar.
77
78
KAPITEL 7. WEITERFÜHRENDE ÜBERLEGUNGEN, AUSBLICK UND FAZIT
Auch die im Rahmen dieser Arbeit genutzten Grenzwerte für die Erkennung der maximal erlaubten Geschwindigkeiten sind auf Basis der vorhandenen Daten festgelegt worden und müssten bei
einer verstärkten Nutzung gegebenenfalls überprüft und angepasst werden.
Ein weiteres Problem liegt in der Anzahl der frei zur Verfügung stehenden Quellen für Verkehrsdaten. Während es beispielsweise, wie in [LTA10] beschrieben, in Singapur möglich ist, von
einer zentralen Stelle Informationen aus Park- und Verkehrsleitsystemen, Induktionsschleifen
oder Webcams zu erhalten, unterstehen diese in Deutschland verschiedenen Institutionen und
Behörden, die unterschiedliche Interessen verfolgen und teilweise auch eigene Applikationen zum
Verkauf anbieten. So ist die Bundesrepublik auch eines der wenigen Länder, in denen das Eingangs erwähnte
Trac Message Channel
System wirklich nur über das Radiosignal empfangen
werden darf. Die kommerzielle Alternative Navteq Trac, ursprünglich als TMCpro bezeichnet,
stellt dagegen auch andere Dienste, wie einen Webservice, zur Verfügung, jedoch sind diese nur
mit lizensierten Navigationsgeräten zu nutzen.
7.2 Vergleich mit proprietären Systemen
Vergleicht man nun
TracJamDroid
mit proprietären Systemen, zeigt sich, dass der Unterschied
weniger im angebotenen Funktionsumfang als in Straÿenabdeckung, Aktualität und zur Verfügung stehenden Datenlieferanten liegt.
So bietet Google Maps für Deutschland noch keinen Navigationsdienst auf Basis der Verkehrsdaten an, sondern lediglich ein kostenloses Overlay für ihre Kartensoftware, das die Verkehrsbedingungen farblich anzeigt. Für die Erfassung der hierfür benötigten Werte sind allein die
Nutzer verantwortlich, die bei einem Start der Anwendung ihre Bewegungsdaten an die Server
von Google schicken.
Um nun einen eingehenderen Vergleich bezüglich der Qualität mit Google Maps vornehmen zu
können, sind zum gegenwärtigen Zeitpunkt die Nutzerzahlen von
TracJamDroid
viel zu gering.
Allerdings wird deutlich, dass beide Systeme in gleichem Maÿe von diesen abhängig sind.
Im Gegensatz dazu verfolgt Navteq ein anderes Konzept. Nach der Übernahme der T-Systems
Trac GmbH verfügen sie über ein dichtes Netz von Datensensoren an Autobahnbrücken und
Sensorschleifen in Fahrbahnen, welche den Grundbestand ihrer Daten liefern. Des Weiteren senden alle mit entsprechender Software ausgestattete Navigationssysteme ihre Bewegungsinformationen an eine zentrale Sammelstelle, so dass auf Datenzulieferungen durch Polizei, Staumelder
oder ADAC komplett verzichtet wird. Die Finanzierung dieser umfangreichen Ausstattung erfolgt dabei durch Lizenzgebühren, welche beim Kauf eines jeden Navigationssystems an Navteq
weitergeleitet werden.
Allein aufgrund der verwendeten Hardware für die Erfassung sind die Daten von Navteq als
qualitativ hochwertiger anzusehen. Da es sich allerdings auch um ein kommerzielles System
handelt, sind die gegebenen Voraussetzungen ganz andere.
Neben Google Maps und Navteq Trac gibt es noch weitere Systeme. Diese sind jedoch in der
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
7.3. AUSBLICK
79
Regel an eine spezielle Navigationssoftware gebunden (TomTom) oder als produktspezischer
Aufsatz der Navteq Anwendung (BMW) entstanden und somit nicht unbedingt mit
Droid
TracJam-
zu vergleichen.
7.3 Ausblick
Neben der erfolgten Implementation gibt es noch einige interessante Erweiterungsideen, die aber
im Rahmen dieser Arbeit nicht mehr umzusetzen waren.
Eine sinnvolle Ergänzung wäre die Steuerung per Spracheingabe. Dies würde es dem Anwender
erlauben, während der Fahrt mit dem System zu interagieren ohne dabei gegen geltendes Recht
zu verstoÿen. Dass eine Sprachsteuerung unter Android generell überhaupt möglich ist, zeigt
die Vielzahl solcher Anwendungen im Market. Wie zuverlässig diese jedoch arbeiten und ob ein
Einsatz für Navigation und Störungsmeldungen erfolgsversprechend wäre, müsste zuerst einer
genauen Evaluation unterzogen werden.
Ebenfalls mit Schnittstellen zum Bereich Sprachsteuerung versehen sind die Erweiterungsmöglichkeiten der Navigationskomponente. So ist diese bisher bewusst einfach gehalten und verfügt
nur über eine grundlegende Funktionalität, könnte aber aufgrund der Kapselung der einzelnen
Einheiten von
TracJamDroid
durch ein vollwertiges Navigationssystem mit Sprachausgabe er-
setzt werden. Vor allem eine Anzeige von Pfeilen zur Richtungsangabe wäre hier erstrebenswert
und könnte mit den bereits beim Server eingehenden CloudMade-Daten kombiniert werden.
Da die Applikation unter einer Open-Source-Lizenz veröentlicht wird und der Quellcode sowohl
vom Client als auch vom Server somit frei verfügbar ist, können diese Erweiterungen gröÿtenteils
problemlos zu einem späteren Zeitpunkt in die bestehende Implementation integriert werden.
Jeder Programmierer, der also an der Weiterentwicklung von
TracJamDroid
mitwirken will,
kann sich also den gesamten Quellcode von der zum Projekt gehörigen Google Code Seite herunterladen und damit arbeiten.
7.4 Fazit
Bei der bisher sehr geringen Anzahl von Testnutzern liefert die erstellte Anwendung stimmige
Geschwindigkeitswerte, die aber nur selten in der besten der vorgestellten Aktualitätsstufen zur
Verfügung stehen. Auch die bewusst einfach gehaltene Navigationskomponente konnte in den
Tests ihre Aufgaben erfüllen und zeitnah auf erkannte Verkehrsstörungen reagieren.
Für eine Verbesserung der vorhandene Datenbasis ist allerdings eine enorme Steigerung der
Nutzerzahlen unerlässlich. In diesem Fall müsste aber sowohl eine Überprüfung der Hard- als
auch der Software erfolgen. So sind aller Voraussicht nach weder die aktuell verwendete Serverhardware, noch das Datenbank-Managementsystem für eine Vervielfachung der Anfragen und
einer damit einhergehenden Steigerung des Datenvolumens ausgelegt. Auÿerdem müssten einige
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
80
KAPITEL 7. WEITERFÜHRENDE ÜBERLEGUNGEN, AUSBLICK UND FAZIT
der serverseitigen Parameter für die Identikation von Problemstellen oder Geschwindigkeitsbegrenzungen einer Überprüfung unterzogen werden.
Allerdings lässt sich zum jetzigen Zeitpunkt noch keine Aussage über die weitere Entwicklung
der Nutzerzahlen treen. Jedoch hat laut [Gue11] die Applikation Beat the Trac mit einer
Zahl von einer Million neuer Nutzer innerhalb von zwölf Monaten gezeigt, dass Anwendungen
in diesem Bereich auf hohes Interesse stoÿen und sich allein durch Mund-zu-Mund-Propaganda
verbreiten können.
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Literaturverzeichnis
[And11a]
guide/index.html.
[And11b]
[And11c]
The Developer's Guide. http://developer.android.com/
Android Developers:
Version: Oktober 2011
Developers:
Painless Threading.
http://developer.android.com/
resources/articles/painless-threading.html. Version: Oktober 2011
Android
Platform Versions.
http://developer.android.com/
resources/dashboard/platform-versions.html. Version: November 2011
Android
Developers:
+
[BGK 11] Bieber, Robert ; Gerlach, Patrick ; Klinke, Randolf ; Scheibner, Katharina ;
Schulze, Michael ; Ziegler, Sascha ; Kluge, Mario: Fuÿgängerbezogene Daten-
aufbereitung in OpenStreetMap / Universität Potsdam. 2011. Forschungsbericht
[BIT11]
Bundesverband Informationswirtschaft, Telekommunikation und neue Medien e.V.:
Echtzeitdienste revolutionieren Staumeldungen für Autofahrer. http://www.bitkom.
org/64765_64761.aspx.
[BK04]
[BP10]
Version: November 2011
Hibernate in Action: Practical Object/Relational
Bauer, Christian ; King, Gavin:
Mapping.
Manning, 2004. 408 S. ISBN 193239415X
Becker, Arno ; Pant, Marcus:
Android 2: Grundlagen und Programmierung. 2., ak-
tualisierte und erweiterte Auage. Dpunkt Verlag, 2010. 427 S. ISBN 3898646777
[CA04]
[Chr05]
Cave-Ayland, Mark (Hrsg.) ; Sirius Corporation (Veranst.):
with PostGIS.
Integrating Map Data
2004
Christl, Arnulf:
Introduction to Spatial Data Management with Postgis.
November
2005
[Deg11]
Degusta,
vice
Michael:
D-Day.
October
20,
2011:
Android's
1
Million
De-
http://theunderstatement.com/post/10977941562/
october-20-2011-androids-1-million-device-d-day. Version: Oktober 2011
[GIS11]
Berkeley - University of California:
berkeley.edu/.
The GiST Indexing Project. http://gist.cs.
Version: Oktober 2011
81
82
LITERATURVERZEICHNIS
[Gol08]
Goldsberry, Kirk: GeoVisualization of Automobile Congestion / Michigan State
University. 2008. Forschungsbericht. An abstract for the AGILE Workshop on
GeoVisualization of Dynamics, Movement and Change
[Gra11]
Gramlich, Nicolas:
OSMDroid - OpenStreetMap-Tools for Android. http://code.
google.com/p/osmdroid/.
[Gue11]
Gueziec, Andre:
Version: Oktober 2011
R Celebrates One Million Mobile App Downloads.
Beat the Trac
März 2011
+
[H 08]
Herrera, Juan-Carlos et al.: Mobile Century - Using GPS Mobile Phones as Trac
15th World Congress on Intelligent Transportation
Systems November 16-20, New York, 2008
Sensors: A Field Experiment. In:
[Her09]
Assessment of GPS-enabled smartphone data and its use in
trac state estimation for highways, Berkeley - University of California, Diss., 2009
Herrera, Juan-Carlos:
+
[KBA 11] King, Gavin ; Bauer, Christian ; Andersen, Max R. ; Bernard, Emmanuel ;
Ebersole, Steve ; Ferentschik, Hardy:
Hibernate Reference Documentation. 2011.
394 S.
+
[L 03]
Lorkowski, Stefan et al.: Erste Mobilitätsdienste auf Basis von Floating Car Data
/ Deutsches Zentrum für Luft- und Raumfahrt DLR - Institut für Verkehrsforschung.
2003. Forschungsbericht
[Lin05]
Generierung streckenbezogener Verkehrsdaten als Basis für den
Einsatz in Verkehrstelematiksystemen, Universität für Bodenkultur in Wien, Diss.,
Linauer, Martin:
2005
[LTA10]
Land Transport Authority:
Real-Time Trac Information.
10 Ubi Avenue 3, Singa-
pore 408865, November 2010
[Mar11]
Marterer,
Alexander:
als "Navi".
Handyverbot am Steuer gilt auch bei Nutzung
http://www.verkehrsrecht-rechtsanwalt.biz/Nutzung_eines_
Mobiltelefons.html. Version: November 2011
[Mei10]
Meier, Reto:
Professional Android 2 Application Development.
2. Auage.
John
Wiley & Sons, 2010. 576 S. ISBN 0470565527
[Ope99]
[osm11]
Open GIS Consortium, Inc. (Hrsg.):
SQL.
OpenGIS Simple Features Specication For
Revision 1.1. : Open GIS Consortium, Inc., Mai 1999
Osm2pgsql. http://wiki.openstreetmap.org/wiki/Osm2pgsql.
Version: Oktober
2011
[PGD11]
The PostgreSQL Global Development Group:
PostgreSQL 9.0.5 Documentation. Sep-
tember 2011
[Pos11]
PostgreSQL
Global
Development
postgresql.org/about/.
Group:
About PostgreSQL.
http://www.
Version: Oktober 2011
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
LITERATURVERZEICHNIS
[PT11]
83
Gartner Says Android to Become No. 2 Worldwide
Mobile Operating System in 2010 and Challenge Symbian for No. 1 Position by 2014.
Pettey, Christy ; Tudor, Ben:
http://www.gartner.com/it/page.jsp?id=1434613.
[Ref11]
Refractions
PostGIS 2.0.0 Manual.
Research:
refractions.net/documentation/manual-svn/.
[RLMM]
Version: Oktober 2011
http://http://postgis.
Version: Oktober 2011
Rogers, Rick ; Lombardo, John ; Mednieks, Zigurd R. ; Meike, G. B.:
Application Development: Programming with the Google SDK.
Android
O'Reilly Media, Inc..
352 S. ISBN 0596521472
[RT10]
Ramm, Frederik ; Topf, Jochen:
OpenStreetMap.
3., überarbeitete und erweiterte
Auage. Lehmanns Media-Lob.de, 2010. 369 S. ISBN 3865413757
[SBD11]
Statistisches
ge
und
Bundesamt
Deutschland:
Schienenbestand.
Fahrzeugbestand
-
Kraftfahrzeu-
http://www.destatis.de/jetspeed/portal/
cms/Sites/destatis/Internet/DE/Content/Statistiken/Verkehr/
VerkehrsmittelbestandInfrastruktur/Tabellen/Content75/Fahrzeugbestand,
templateId=renderPrint.psml. Version: Oktober 2011
[SQL11]
The SQLite Consortium:
different.html.
[Ste11]
Stegers, Fiete:
iphone116.html.
[whe11]
[Wik11a]
Version: Oktober 2011
Das iPhone als Spitzel. http://www.tagesschau.de/inland/
Version: Oktober 2011
SOZIALHELDEN e.V.:
wheelmap.org/.
Wikipedia:
Distinctive features of sqlite. http://www.sqlite.org/
wheelmap.org - Rollstuhlgerechte Orte nden. http://
Version: Oktober 2011
Comparison of Android devices.
Comparison_of_Android_devices.
[Wik11b]
Wikipedia:
Verkehrslagedienst.
Verkehrslagedienst.
http://en.wikipedia.org/wiki/
Version: November 2011
http://de.wikipedia.org/wiki/
Version: Oktober 2011
Erfassung und Visualisierung von Echtzeitverkehrsdaten mit Smartphones
Erklärung
Hiermit versichere ich, dass ich die vorliegende Arbeit selbständig verfasst und keine anderen als
die angegebenen Quellen und Hilfsmittel benutzt sowie Zitate kenntlich gemacht habe.
Osnabrück, Dezember 2011