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