• Keine Ergebnisse gefunden

1.3. Aufbau der Arbeit

N/A
N/A
Protected

Academic year: 2022

Aktie "1.3. Aufbau der Arbeit"

Copied!
71
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Android in dezentralen Netzen

Abschlussarbeit

zur Erlangung des akademischen Grades:

Bachelor of Science (B.Sc.)

an der

Hochschule für Technik und Wirtschaft (HTW) Berlin Fachbereich 4: Informatik, Kommunikation und Wirtschaft

Studiengang:Angewandte Informatik

1. Gutachter: Prof. Dr.-Ing. Thomas Schwotzer 2. Gutachter: Prof. Dr. Alexander Huhn

Eingereicht von: Lukas Ludwig [564263]

Berlin, den 09.04.2021

(2)

Abbildungsverzeichnis iii

Abkürzungsverzeichnis iv

Listings vi

1. Einleitung 1

1.1. Motivation . . . 1

1.2. Ziele und Abgrenzung . . . 1

1.3. Aufbau der Arbeit . . . 2

2. Grundlagen 3 2.1. Satellitenortungssysteme . . . 3

2.2. GPS . . . 5

2.3. OpenStreetMap . . . 6

2.4. Tracks . . . 7

2.5. Design Patterns . . . 10

2.5.1. MVC und MVP . . . 10

2.5.2. Singleton . . . 10

2.5.3. Command Pattern . . . 11

2.5.4. Template Method Pattern . . . 11

2.6. Bibliotheken und Frameworks . . . 12

2.6.1. JPX . . . 12

2.6.2. Osmdroid . . . 13

3. Analyse 21 3.1. Zielgruppe . . . 21

3.2. Anforderungen . . . 21

3.2.1. Funktionale Anforderungen . . . 21

(3)

3.2.2. Nichtfunktionale Anforderungen . . . 22

4. Entwurf und Implementierung 24 4.1. GeoModel und Track . . . 24

4.2. Location Service . . . 25

4.3. Verwaltung . . . 29

4.4. Serialisierung . . . 30

4.5. Import und Export . . . 32

4.6. Visualisierung . . . 36

4.7. Verteilung der Funktionen auf Activities . . . 40

4.8. GeoModelListActivity . . . 40

4.9. TrackRecordingMapActivity . . . 43

4.9.1. Permissions . . . 43

4.9.2. Aufzeichnen von Tracks . . . 43

4.9.3. TrackRecordingPresenter . . . 46

4.10. Kachel-Funktionen . . . 47

4.10.1. Tile Source Einstellungen . . . 47

4.10.2. Download . . . 47

5. Testen des Projektes 51 5.1. Unit-Tests . . . 51

5.2. Integrationstests . . . 52

6. Fazit 55 6.1. Umsetzung der Funktionalen Anforderungen . . . 55

6.2. Umsetzung der Nichtfunktionalen Anforderungen . . . 55

6.3. Allgemeines Fazit . . . 55

7. Ausblick 57 7.1. Hinweise zur Integration in SN2 . . . 57

7.2. Zukunft der Komponente . . . 57

Literaturverzeichnis i

A. Appendix v

(4)

2.1. Satellitenortung durch Entfernungsmessung, angelehnt an Abbildung 2.14

in [3] . . . 4

2.2. Command Pattern, angelehnt an Abb. 4.1 aus [24, S. 52] . . . 12

2.3. Grundsätzliche Tile Provider Struktur in Osmdroid . . . 15

2.4. Vereinfachtes Klassendiagramm zu Tile Sources und verwandten Klassen . 17 4.1. Vereinfachtes Klassendiagramm für GeoModel und Track . . . 25

4.2. Zwei Tracks aufgenommen mit unterschiedlichen Parametern im Locati- onService . . . 28

4.3. Klassendiagramm zur Veranschaulichung des LocationReceiver und seinen Beziehungen zu anderen Klassen . . . 29

4.4. Vereinfachtes Klassendiagramm für TrackModelManager ohne Methoden . 30 4.5. Klassendiagramm zu TrackModelManager ergänzt um GeoModelStorage . 31 4.6. Klassendiagramm zu Dateiformaten . . . 33

4.7. Klassendiagramm mit den relevanten Methoden zu TrackOverlay und sei- nen Beziehungen . . . 36

4.8. Vereinfachtes Sequenzdiagramm für die Visualisierung von Tracks . . . 39

4.9. Darstellung von GeoModels im RecyclerView am Beispiel der Display- TracksActivity . . . 42

4.10. Vereinfachtes Klassendiagramm zum TrackRecorder . . . 44

4.11. Vereinfachtes Sequenzdiagramm für die Aufnahme von Tracks . . . 45

4.12. Dialog zum Herunterladen der Kacheln in ein Archiv . . . 50

5.1. Track aus Abbildung 4.2 (b) exportiert als KML und importiert in Google Earth Pro . . . 53

(5)

App, Applikation OSM, OpenStreetMap

GPS, Global Positioning System

NAVSTAR-GPS, Navigational Satellite Timing and Ranging Global Positioning System GNSS, Globales Navigationssatellitensystem

GIS, Geographic Information System XML, eXtensible Markup Language GPX, GPS Exchange Format KML, Keyhole Markup Language GML, Geography Markup Language

FIT, Flexible and Interoperable Data Transfer TCX, Training Center XML

DGPS, Differential GPS A-GPS, Assisted GPS

MVC, Model View Controller MVP, Model View Presenter SN2, SharkNet2

UML, Unified Modeling Language API, Application Programming Interface

ASAP, Asynchronous Semantic Ad-hoc Protocol

(6)

2.1. Laden der SharedPreferences . . . 19

2.2. UserAgent für die Anwendung setzen . . . 20

4.1. Methode onStartCommand in LocationService, welche aufgerufen wird, wenn der Service gestartet wird . . . 26

4.2. GpsLocationListener in LocationService . . . 26

4.3. Laden der Tracks aus dem Speicher . . . 31

4.4. Methode zum Mergen von Tracks . . . 32

4.5. Registrieren von neuen Dateiformaten im FormatManager . . . 34

4.6. Export eines Document, welches die Baumstruktur einer KML-Datei in Java abbildet . . . 35

4.7. Aufruf der Methode in der Activity zum Hinzufügen weiterer Overlays in ConfiguredMapFragment . . . 37

4.8. Erzeugung eines GeoModelListContentAdapter . . . 41

4.9. Aufbau eines RequestTracksCommand zum Abfragen von Tracks aus ei- nem Manager . . . 41

4.10. Erzeugung eines TrackRecordingPresenter in onCreate() der TrackRecor- dingMapActivity . . . 46

4.11. Aktualisierung der TrackOverlays durch den TrackRecordingPresenter . . 46

4.12. Erzeugung eines ConfiguredMapFragment, das zum herunterladen von Kartenkacheln verwendet werden kann . . . 48

4.13. Erstellen des benötigten MapView im ConfiguredMapFragment . . . 48

5.1. Erzeugen eines TrackRecordingPresenter, der getestet werden soll . . . 51

5.2. Simulation einer Auswahl von Tracks durch einen Nutzer und Aufrufen der Lifecycle-Methoden des Presenter . . . 52

5.3. Setup und Start der EditGeoModelActivity . . . 53

(7)

5.4. Nutzereingabe und Drücken des Buttons zum Speichern durch Espresso . 54

(8)

1.1. Motivation

In der heutigen Zeit sind beinahe alle mobilen Anwendungen, welche eine Interaktion mehrerer Geräte untereinander ermöglichen, auf das Internet als Kommunikationsnetz- werk angewiesen. Dabei wird meist auf eine Client-Server Architektur zurückgegriffen.

Sollte die Infrastruktur jedoch fehlen sind die in den Apps eingebauten Funktionen oft gar nicht mehr oder nur noch sehr stark eingeschränkt nutzbar. Das gilt auch für vie- le Anwendungen, welche GPS verwenden, obwohl die Technologie komplett unabhängig vom Internet funktioniert. Selbst wenn das Erfassen der Position möglich ist, so ist es der Austausch von Standortdaten zwischen Geräten ohne eine Internetverbindung in der Regel nicht, da solche Daten meist über die Server von Unternehmen synchronisiert werden um die Verwaltung der Nutzerdaten einfacher zu machen.

Ein weiterer Vorteil in der zentralen Haltung von GPS-Daten für Unternehmen ist, dass dadurch Personenprofile erstellt werden können. Besonders in Kombination mit weiteren Datensätzen, die durch andere Technologien wie Gesichtserkennung gewonnen werden, können genaue Rückschlüsse auf die Lebensweise der Betroffenen gezogen wer- den, was die persönliche Freiheit mitunter sehr stark einschränken kann und Nutzern die Kontrolle ihrer persönlichen Daten entzieht [1, S. 339]. Zum Schutz der Privatsphäre ist es empfehlenswert so wenige Daten wie möglich zentral zu lagern, die Aufschluss über die geografische Position bieten. Dies ist jedoch nicht im Interesse großer Unternehmen, da diese mit Standortdaten große Geschäfte machen können.

1.2. Ziele und Abgrenzung

Diese Arbeit soll eine Grundlage darstellen für die Arbeit mit GPS-Daten und Tracks in dezentralen Netzen, unabhängig von Client-Server Strukturen. Das Resultat dieses Pro- jektes wird eine neue Komponente für SharkNet2 sein, eine App für Mobilgeräte, die in

(9)

dezentralen Netzwerken unabhängig vom Internet arbeiten kann. SharkNet2 wird damit auch um eine Funktion zum Erfassen, Serialisieren und Visualisieren von GPS-Tracks auf einer Karte erweitert. Weiterhin soll das Projekt in Zukunft um die Möglichkeit ei- nes Austausches dieser Tracks zwischen Peers im dezentralen Netz erweitert werden. Der Einbau der Funktion zur eigentlichen Übertragung der Daten zwischen den Teilnehmern ist nicht Teil dieser Arbeit, soll aber als Erweiterung implementierbar sein ohne dass am existierenden Code dafür etwas geändert werden muss.

Das Speichern im lokalen Dateisystem soll in mehreren Formaten möglich sein. Das Projekt soll um weitere Datenformate für die Tracks erweitert werden können. Deren Visualisierung wird in Open Street Maps (OSM) stattfinden. Zur Verwendung von OSM in Android wird das Framework Osmdroid als Kartenprovider eingebaut. Die Recherche und anschließende Umsetzung der Erkenntnisse zum Umgang mit diesem Framework ist ein zentraler Bestandteil der Arbeit. Die Dokumentation der Ergebnisse soll als Basis für zukünftige Projekte dienen können, in denen dieses Framework ebenfalls eingebaut werden soll.

1.3. Aufbau der Arbeit

Zunächst werden Hintergrundinformationen zum besseren Verständnis der Arbeit ver- mittelt. Anschließend werden die Anforderungen an die Anwendung erhoben und basie- rend darauf wird ein Entwurf erstellt. Dieser bietet die Grundlage für die Implementie- rung der Komponente für SN2. Auf das Testen einzelner Funktionen und Programmteile wird in dem darauffolgenden Kapitel eingegangen. Das Fazit wertet die Arbeit aus.

Abschließend wird ein Blick auf mögliche Erweiterungen und Verbesserungen der Kom- ponente geworfen.

(10)

Dieses Kapitel soll die grundlegende Funktionsweise von satellitengestützten Navigati- onssystemen erläutern mit einem Fokus auf das bekannteste, meistgenutzte und auch in die App zu integrierende globale Navigationssatellitensystem, das NAVSTAR GPS.

Grundlegende Begriffe werden geklärt und es werden ergänzende Verfahren zur Positions- bestimmung erläutert und wie diese bei GPS eingesetzt werden. Weiterhin wird OSM vor- gestellt und kurz erläutert wie das Kartenmaterial entsteht und eingesetzt wird. Es folgt eine Beschreibung was Tracks sind und wie sie in unterschiedlichen GIS-Datenformaten dargestellt werden können. Die während der Implementierung verwendeten Design Pat- terns werden darauffolgend erklärt. Frameworks und Bibliotheken werden anschließend vorgestellt mit einem besonderen Fokus auf Osmdroid. An dieser Stelle sollen nur einige grundlegende Komponenten und Prinzipien des Frameworks behandelt werden. Weite- re Besonderheiten lassen sich besser in den darauffolgenden Kapiteln an praktischen Beispielen erläutern.

2.1. Satellitenortungssysteme

Satellitenortungssysteme spielen mittlerweile eine wichtige Rolle im Alltag der Men- schen. Besonders die globalen Navigationssatellitensysteme, zu denen GPS, GLONASS, Galileo und Beidou zählen, werden für viele unterschiedliche Zwecke verwendet, da sie eine Vielzahl an Funktionalitäten wie Bestimmung von Position und Geschwindigkeit sowie Navigation in Echtzeit ermöglichen und ihr Wirkungsbereich die gesamte Erde umspannt. GNSS sind satellitengestützte Systeme, das heißt sie verwenden außer der Satellitenortung noch weitere Verfahren zur genaueren Standortbestimmung.

Die Positionsbestimmung des Empfängers folgt bei der GNSS-Ortung einem Grund- prinzip. Es wird das Signal von mindestens vier Satelliten zur Standortermittlung be- nötigt. Diese bewegen sich in fest definierten Bahnen um die Erde. Jedes mal wenn die Satelliten ihre Abfolge von Signalen zu fest definierten Zeitpunkten abschicken, senden

(11)

sie dabei auch ihre momentane Position mit. Der Abstand zwischen Sender und Emp- fänger kann durch die Zeitversetzung mit der die Signale ankommen berechnet werden, weil die Laufgeschwindigkeit der Signale bekannt ist. Abbildung 2.1a) bis c) soll ver- deutlichen, wie die Positionsbestimmung mit drei Satelliten bereits auf zwei mögliche Punkte einschränkt. Einer dieser Punkte kann meist durch die Kenntnis der ungefähren Position oder ergänzende Ortungsmethoden ausgeschlossen werden [2, S. 5].

Abbildung 2.1.: Satellitenortung durch Entfernungsmessung, angelehnt an Abbildung 2.14 in [3]

Da die Uhren in den Satelliten und den Empfangsgeräten nicht genau synchron lau- fen, wäre eine Lösung mit nur drei Satelliten zu ungenau. Aus diesem Grund und um das Ergebnis auf eine mögliche Position des Empfängers zu beschränken wird ein vier- ter Satellit benötigt (siehe Abbildung 2.1d)). Dieser wird genutzt um die Zeitdifferenz zwischen Satelliten und dem Empfänger (Empfängeruhrenfehler) als vierte Unbekannte neben den drei Empfängerkoordinaten zu bestimmen. Unter Verwendung des räumlichen Pythagoras kann damit ein Gleichungssystem der folgenden Form aufgebaut werden [4, S. 53]:

(∆Ti·v+ ∆t·v)2=(XiXE)2+ (YiYE)2+ (ZiZE)2 ;i=1,2,3,4. Dabei sind

(12)

∆Ti: die gemessene Laufzeiten der Satellitensignale,

t: unbekannter Uhrenfehler,

v: die Ausbreitungsgeschwindigkeit der Satellitensignale, Xi, Yi, Zi: die bekannten Satellitenkoordinaten,

XE, YE, ZE: die unbekannten Empfängerkoordinaten.

Der Fakt, dass das zu ortende Objekt (der Empfänger) dabei nicht selbst Daten ver- senden muss, macht es zu einem passiven System [4, S. 51]. Dies hat mehrere Vorteile gegenüber Systemen mit aktiver Positionsbestimmung [5, S. 9]:

• Empfangsgeräte können sehr leichtgewichtig und damit portabel sein und haben nur einen vergleichsweise niedrigen Energieverbrauch während des Lokalisierungs- verfahrens.

• Die Nutzeranzahl ist unbegrenzt und hat keinen Einfluss auf die Leistungsfähigkeit des Systems.

• Dadurch dass keine Daten vom Empfänger verschickt werden kann dieser nicht so einfach entdeckt werden, was besonders für militärische Zwecke von großem Vorteil ist.

Die ersten beiden Punkte haben eine große Bedeutung für die zivile Nutzung der GNSS, da sie die Nutzung in Mobilgeräten im heutigen Ausmaß überhaupt erst möglich machen.

2.2. GPS

Das NAVSTAR-GPS ist das meistverwendete GNSS und wurde in den USA ab 1973 vom Department of Defence entwickelt. Es ging aus dem 1967 zur zivilen Nutzung frei- gegebenen Ortungssystem TRANSIT hervor, welches vorher unter dem Namen Navy Navigation Satellite System in U-Booten der US-Flotte eingesetzt wurde [2, S. 98].

GPS verwendet 24 Satelliten, von denen zu jeder Zeit mindestens vier auf der Erdober- fläche sichtbar sind [6, S. 9]. Das Verteidigungsministerium der USA hat vor der Ent- wicklung eine Reihe von Anforderungen an GPS gestellt, zu denen u. a. eine Positions- und Geschwindigkeitsbestimmung von ruhenden und bewegten Objekten auf der Erde und in Erdnähe, eine Zeitübermittlung und eine bestmögliche Resistenz gegenüber un- gewollten Einflüssen gehörten. Das System sollte in Echtzeit arbeiten und eine weltweite Navigation ermöglichen. Eine umfassendere Liste der erarbeiteten Anforderungen fin- det sich in Mansfeld [2, S. 106]. Die Lokalisierungsgenauigkeit von GPS liegt bei etwa

(13)

drei bis zehn Metern im Optimalfall. Unter schlechten Bedingungen können jedoch auch Abweichungen von mehreren 100m auftreten [6, S. 9]. Aus diesem Grund wurden er- gänzende Technologien wie DGPS und A-GPS entwickelt, welche einigen Nachteilen von GPS entgegenwirken sollen.1.

2.3. OpenStreetMap

OpenStreetMap ist ein Projekt, das 2004 in Großbritannien gestartet wurde und das Ziel hat eine freie Weltkarte zu erschaffen [8, S. 3]. Die Karte kann dabei von jeder Per- son mit Hilfe unterschiedlicher Editoren bearbeitet und ergänzt werden. Luftbilder oder aufgezeichnete Tracks, welche genauer im Kapitel 2.4 behandelt werden, können dabei im Hintergrund abgebildet werden [9]. Die Daten werden nachgezeichnet, mit Zusatz- informationen versehen und zentral gespeichert. Die Kartendaten liegen als Vektoren vor und werden für die Anzeige als Bitmap-Grafiken vorgerechnet. Diese Kacheln (Ti- les) sind meist 256x256 Pixel groß und lassen sich zu einer quadratischen Weltkarte zusammensetzen. Mit jeder Steigerung der Zoomstufe um 1 auf der Karte werden alle vorher sichtbaren Kacheln in vier Kacheln untergliedert, die jeweils wieder die gleiche Auflösung besitzen [8, S. 175 f.]. Die Kacheln werden von Tile-Servern geladen, von de- nen es verschiedene Anbieter gibt. Diese verwenden meist die Geodatenbank von OSM als Grundlage und verarbeiten das Kartenmaterial unterschiedlich weiter. OSM verwen- det standardmäßig hauptsächlich die open-source Software Mapnik um ihre sogenannte

"Slippy Map"zu rendern [10]. In diesem Projekt sollen heruntergeladene Kartenabschnitte auch offline visualisiert werden können. Dafür sollten Kartendaten von Anbietern ver- wendet werden können, die Kacheln in mehreren Zoomleveln anbieten und deren Karte regelmäßig aktualisiert wird. Das Kartenmaterial von OSM selbst ist unter Berücksich- tigung der Open Data Commons Open Database Lizenz (ODbL)2 benutzbar [11]. Die Bestimmungen zu den Tile-Servern von Mapnik und anderen ausgewählten Anbietern werden in Kapitel 2.6.2 betrachtet.

1In Mansfeld [2, S. 283 ff.] ist DGPS im Detail beschrieben. Die Funktionsweise und den Einsatz von A-GPS in Mobilgeräten hat Dhein [7] zusammengefasst.

2https://opendatacommons.org/licenses/odbl/

(14)

2.4. Tracks

Ein Track ist eine Aufzeichnung eines zurückgelegten Weges. Er besteht aus Track- Segmenten, die wiederum in Trackpoints unterteilt werden. Trackpoints sind geographi- sche Punkte, die mindestens durch ihren Längen- und Breitengrad definiert sind. Sie können je nach Anwendungsfall noch weitere Informationen wie Datum, Uhrzeit, Ge- schwindigkeit, Höhe und Werte zur Genauigkeit bzw. Streuung der ermittelten Punkte enthalten [8, S.35]. Um Tracks zwischen Geräten auszutauschen müssen sie in ein den Geräten bekanntes Format gebracht werden. Von diesen GIS-Datenformaten sollen im Folgenden einige häufig zum Austausch von GPS-Daten genutzte genauer betrachtet werden, um herauszufinden inwiefern sie die Speicherung von Tracks unterstützen und wofür sie eingesetzt werden.

GPX

Das GPS Exchange Format (GPX) ist ein auf XML basierendes Datenformat zum Aus- tausch von GPS Daten zwischen Anwendungen und Webservices. Es wurde im Jahr 2002 mit der Version 1.0 eingeführt und hat sich seit der Einführung der Version 1.1 im Jahr 2004 nicht verändert. Für den Austausch von kleineren Datenmengen aus GPS- Daten ist GPX sehr gut geeignet und wird deshalb weitreichend eingesetzt [12]. Auch OSM lässt seine Nutzer Tracks in GPX-Format als Hilfe für das manuelle Editieren der Karte hochladen [13]. Da das Format auf XML basiert ist es beliebig erweiterbar und damit anpassbar. Ein Beispiel für eine solche Erweiterung ist die GPX-Extension der Firma Garmin, die auf GPX 1.1 basiert. Sie bietet unter anderem die Möglichkeit den Tracks eine Farbeigenschaft zur Visualisierung, sowie den Trackpoints die Eigenschaften Temperatur und Tiefe (Depth) hinzuzufügen [14].

In GPX können Tracks untergliedert werden in Track-Segmente, welche nach Zeit- punkt der Aufnahme sortierte Trackpoints enthalten. Tracks werden durch<trk>, Track- Segmente durch<trkseg> und Trackpoints durch <trkpt> gekennzeichnet. Tracks wer- den in Segmente eingeteilt, um darzustellen, dass der Empfang des GPS Signals unter- brochen oder der GPS-Empfänger ausgeschaltet wurde. Trackpoints müssen mindestens geografische Länge und Breite durch die Attribute lat und lon definieren und können optional weitere Informationen wie Aufnahmezeitpunkt<time>, Höhe<ele>und einige

(15)

Weitere enthalten [15].

KML

Die Keyhole Markup Language (KML) ist ein ebenfalls auf XML basierendes Format zur Visualisierung von geografischen Informationen in einem Earth-Browser wie Google Earth oder ArcGIS Earth. Die Version 2.2 wurde durch das Open Geospatial Consortium als Standard aufgenommen [16][17].

Für das Datenformat KML existiert eine Erweiterung, welche es unter anderem erlaubt Tracks zu definieren. Tracks werden durch<gx:Track>definiert und sind in KML nicht weiter zerlegbar. Sie bilden das Äquivalent zu den Track-Segmenten in GPX. Mehrere Tracks können dafür in einem MultiTrack als<gx:MultiTrack>zusammengefasst werden.

Unterbrechungen in der Aufnahme von Tracks werden also auch hier berücksichtigt.

So können beispielsweise mehrere mit Unterbrechungen aufgenommene Tracks in einem Objekt mit eigenen Eigenschaften (z.B. einer ID oder weiteren Informationen zur Anzeige in einem Programm wie einem Icon) zusammengefasst werden. Die einzelnen Punkte werden als Koordinaten durch<gx:coord>mit Längengrad, Breitengrad und Höhe durch Leerzeichen getrennt gekennzeichnet. Der Aufnahmezeitpunkt dieser Punkte wird durch

<when> beschrieben. Die Anzahl der <when> und <gx:coord> Elemente muss gleich sein, da automatisch jeweils ein Zeitpunkt und eine Koordinate einander basierend auf ihrer Reihenfolge im Track zugeordnet werden [18]

GML

Die Geography Markup Language (GML) basiert wie GPX und KML auch auf XML.

Das Format wird verwendet um reale geografische Gegebenheiten zu repräsentieren [19]. GML stellt das Element <gml:track> zur Verfügung, welches entworfen wurde um sich bewegende Objekte zu beschreiben. Dieser kann weiter unterteilt werden in

<gml:MovingObjectStatus> Elemente, die wiederum Eigenschaften wie Position, Zeit und Geschwindigkeit kapseln können und damit eine Art Trackpoint darstellen [20, Ver- sion 3.0, Document 02-023r4, S. 153f.]. Allerdings bietet das Format keine Unterteilung in Segmente. Seit Version 3.2.1 ist das Track-Element zudem deprecated. Stattdessen soll das <gml:history> Element verwendet werden, das eine Abfolge von Ereignissen darstellt, welche die Evolution des Objekts beschreiben [20, Version 3.2.1, Document 07-036, S. 171 f., S. 406]. GML ist also nur bedingt dazu geeignet von Nutzern zurück-

(16)

gelegte Tracks abzubilden, da das Format nicht für die Bewegung von Nutzern ausgelegt ist, sondern rein auf die Beschreibung von geografischen Objekten.

GeoJSON

Im Gegensatz zu den bereits behandelten Datenformaten baut GeoJSON auf JavaScript Object Notation (JSON) auf. Geografische Daten können als Geometrie, Feature oder FeatureCollection Objekt definiert werden [21, S. 3]. Geometrien sind vorgegebene Ob- jekte eines Typs wie unter anderem Punkt, Linie oder Polygon, die geografisch durch Koordinaten gebunden sind [21, S. 7ff.]. Ein Feature beschreibt ein reales, geografisch fixiertes Objekt. Dieses enthält immer eine der vordefinierten Geometrien oder einen null Wert wenn das Feature nicht durch Koordinaten beschrieben werden soll [21, S. 11].

Eine FeatureCollection fasst Features in einer Sammlung zusammen [21, S. 12]. Keines dieser Objekte ist geeignet um Tracks zu speichern. Ein Track könnte zwar optisch als einLineString (Geometrie für eine Linie) umgesetzt werden, der Koordinaten beinhaltet und der wiederum mit anderen LineStrings in einemMultiLineString zusammengefasst werden kann, was der Unterteilung des KML Format entsprechen würde. Jedoch ist keine Möglichkeit gegeben Zeitstempel für die Punkte anzugeben. Dies schließt GeoJ- SON als geeignetes Format für die Speicherung von Tracks aus, da die Verknüpfung von Koordinaten und Zeitpunkten einen Track ausmacht.

Fitness-Formate

Formate wie FIT und TCX sollen nicht näher betrachtet werden, da sie vor allem für den Austausch von Daten über sportliche Aktivitäten entwickelt wurden und diese nicht Teil dieses Projektes sind. Um das FIT-Datenformat nutzen zu können müsste sogar die Integration des FIT SDK3 vorgenommen werden und Lizenzbedingungen berücksichtigt werden4. Die Implementierung dieser Formate für den Import oder Export von Tracks bedeutet in der Regel sehr viel Aufwand, da es meist keine entsprechende open source Bibliothek gibt, die diese Konvertierung vereinfachen würde. In Zukunft könnten solche Formate jedoch auch eingebaut werden, besonders wenn die Komponente irgendwann

3Eine Übersicht zum FIT Protokoll und der FIT SDK ist unter dieser und den darauffolgenden Seiten zu finden:https://developer.garmin.com/fit/overview/

4Die Lizenzbedingungen sind unter folgenden Link nachzulesen:https://developer.garmin.com/fit/

download/

(17)

mit Fitness-Daten arbeiten sollte.

2.5. Design Patterns

Im Folgenden werden im Projekt verwendete Design-Patterns und ihr Nutzen genauer erläutert.

2.5.1. MVC und MVP

Das MVC-Pattern teilt eine Anwendung in drei Verantwortlichkeiten. Eine Klasse gehört immer zum Datenmodell (Model) oder zur Benutzeroberfläche (View) oder fungiert als ein Vermittler (Controller). In Android wird die Aufgabe des Controllers meist von einer Activity oder einem Fragment übernommen. Activities tendieren jedoch dazu mehrere Verantwortlichkeiten zu übernehmen und sehr umfangreich zu werden. In der Regel rea- gieren sie wie ein Controller im MVC-Pattern auf Nutzerinteraktionen und vermitteln zwischen View und Model, jedoch verwalten sie auch die Oberfläche, was sie zu einer Art erweitertem View macht. Um die Aufgaben besser zu entkoppeln und die Activity aufzuteilen kann das MVP-Pattern umgesetzt werden. Der Presenter übernimmt dabei die Aufgaben eines Controllers, indem die ihn implementierende Activity in ihrem Life- cycle die äquivalenten Methoden des Presenters aufruft. Im Optimalfall greift nur der Presenter auf das Model zu und sorgt dafür, dass der View angepasst wird. Die Activity übernimmt vor allem die Aufgaben einer Art Erweiterung des Views und enthält den Code, der direkt an die Android-API gekoppelt ist. Beispielsweise sollte Code, welcher Methoden der Activity-Klasse oder des Context enthält, nicht in den Presenter ausge- lagert werden. Aufgaben, die im MVC-Pattern in den Bereich eines Controllers fallen, reicht die Activity an den Presenter weiter. Der Presenter sollte möglichst wenig mit der Android-API arbeiten. Dies verbessert auch die Testbarkeit der Methoden im Presenter [22].

2.5.2. Singleton

Das Singleton Entwurfsmuster gehört zu den Erzeugungsmustern. Es wird eingesetzt, um eine Klasse auf eine Instanz zu beschränken. Wenn bereits eine Instanz existiert wird im weiteren Verlauf auch nur diese Instanz verwendet und keine neue erstellt [23,

(18)

S. 3]. Es ist einfach zu implementieren, indem ein privater Konstruktor eingesetzt wird und auf die Instanz durch eine statische Methode zugegriffen wird. In verteilten oder multi-threaded Anwendungen kann das Pattern jedoch zu Problemen führen [24, S. 40].

2.5.3. Command Pattern

Im Gegensatz zu Singleton ist das Command Pattern ein Verhaltensmuster. Ein Befehl wird dabei in einem Objekt gekapselt. Abbildung 2.2 zeigt eine Übersicht des Musters zu Verdeutlichung. Beim klassischen Command Pattern können vier Rollen formuliert werden: Invoker, Command, Client und Receiver [23, S. 263]. Der Invoker führt den Com- mand aus, indem er die in der Abbildung execute() genannte Methode des Commands aufruft. Da der Command jedoch nur ein Interface oder wahlweise eine abstrakte Klasse ist bestimmt die konkrete Implementierung von Command, in der AbbildungComman- dImpl genannt, was genau beim Aufruf der Methode geschieht. Diese Implementierung des Commands wird vom Client erzeugt. Die Command-Methode arbeitet, falls sie den Befehl nicht selbst implementieren kann, mit einem weiteren Objekt, dem Receiver. Er weiß wie der Befehl auszuführen ist [24, S. 51 f.].

Diese Entkopplung von Befehl und seiner Ausführung ermöglicht es, dass die aufrufende Klasse nicht wissen muss mit welchen Objekten sie genau arbeitet und wie die Aus- führung des Befehls konkret aussieht. Weiterhin ist der Invoker nicht an eine konkrete Klasse gebunden, was Wartbarkeit und Flexibilität verbessert [24, S. 52].

2.5.4. Template Method Pattern

Wie das Command Pattern ist auch das Template Method Entwurfsmuster ein Ver- haltensmuster. Es besteht aus einer abstrakten Klasse, dem Template, das in seiner Template-Methode eine oder mehrere seiner meist abstrakten Methoden aufruft. Die konkrete Klasse, die von dieser abstrakten Klasse erbt, überschreibt diese Methoden und entscheidet dadurch einen Teil der Funktionsweise der Template Method. Verschie- dene Unterklassen können so den Ablauf der Template Method verändern. Ein Vorteil ist, dass die Oberklasse so einen Teil der Funktionalität auslagert. Außerdem können Code-Redundanzen vermieden werden, da beispielsweise der Code, der von der Tem- plate Method in der Oberklasse implementiert ist, nicht in den Unterklassen jedes mal implementiert werden muss [24, S. 68 ff.]. Falls Vererbung nicht möglich wäre, müss- te jede Klasse den vollständigen Code selbst implementieren, der so stattdessen in der

(19)

Abbildung 2.2.: Command Pattern, angelehnt an Abb. 4.1 aus [24, S. 52]

Oberklasse einmal existiert. Das Command Pattern und das Template Method Pattern lassen sich gut in Kombination verwenden. Dies wird in Kapitel 4.8 umgesetzt.

2.6. Bibliotheken und Frameworks

Für die Integration der Frameworks wird in Android das Gradle Build Tool verwendet.

2.6.1. JPX

JPX ist eine Java Bibliothek zum Überführen von GPS-Daten in das GPX-Format und umgekehrt. Die Versionen 1.7.0 und älter erfordern Java 8, da die Bibliothek mit der Java Stream API arbeitet5. Ab Version 2.0.0 und aufwärts wird Java 11 benötigt. JPX

5Da in JPX unter anderem mit Klassen aus demjavax.xml.streampackage gearbeitet wird und dieses nicht in Android enthalten ist muss eine Bibliothek importiert werden, die diese mitbringt. Dafür wurde die Streaming API for XML (StAX) verwendet.

(20)

unterstützt sowohl Version 1.0 als auch 1.1 von GPX [25].

2.6.2. Osmdroid

Osmdroid ist ein open-source Framework zur Integration von OSM in Android, das kontinuierlich erweitert und verbessert wird. Der Code ist im entsprechenden Repository in GitHub zu finden [26]. Es werden viele hilfreiche, wenn auch oft veraltete Code- Beispiele zur Verfügung gestellt, von denen viele auch im GitHub Wiki erläutert werden.

Für die App wurde Version 6.1.6 des Frameworks genutzt. Neuere Versionen führten oft zu einigen Problemen, für die auch bereits entsprechende Issues in GitHub von anderen Benutzern erstellt wurden. Die Versionen 6.1.7 und 6.1.8 führen ab dem zweiten Start der Applikation zu Abstürzen, wenn beim ersten Start der App kein Zugriff auf den externen Speicher gewährt wurde6. In Version 6.1.10 kommt es zu Problemen mit dem Zugriff auf die SQLite-Datenbank, die zum Cachen der Kacheln verwendet wird7. An dieser Stelle sollen nur einige der wichtigsten Klassen vorgestellt werden, mit einem Fokus auf Teile des Frameworks, die für die Entwicklung der App relevant waren.

Die Karte

Um eine Karte darzustellen stellt das Osmdroid-Framework die Klasse MapView zur Verfügung. Diese kann sowohl in XML, als auch direkt im Code (Java oder Kotlin) hinzugefügt werden. Osmdroid empfiehlt die Integration über XML, da es sonst vorkom- men kann, dass bei unvorsichtiger Handhabung Memory Leaks auftreten. Jedoch bietet die Integration im Code mehr Kontrolle über das Element [27]. Dieser Karte können Overlays hinzugefügt werden, die den eigentlichen Inhalt der Karte definieren. Es bietet sich an einen MapView nochmal in ein Fragment zu integrieren und erst dieses dann in Activities einzubauen. Das Fragment kann besser wiederverwendet werden und zur Aktualisierung einiger Overlays sollte inonResume() und onPause() der den MapView implementierenden Activity oder des Fragments dieonResume()bzw.onPause()Metho- de des MapView aufgerufen werden. Falls der MapView in einem Fragment gekapselt ist, kann dies direkt im Fragment umgesetzt werden und die Overlays werden korrekt aktua- lisiert. Eigenschaften und Funktionen, die allen MapViews zur Verfügung stehen sollen,

6https://github.com/osmdroid/osmdroid/issues/1621

7Der vorgeschlagene Lösungsansatz hat für das Problem nicht geholfen. https://github.com/

osmdroid/osmdroid/issues/1313

(21)

können im Fragment untergebracht werden. Außerdem sind generelle Vorteile durch den Einsatz von Fragments wie Wiederverwendbarkeit, ein eigener Lifecycle und die selbst- ständige Verwaltung des Layouts weitere Punkte, die für ihren Einsatz zur Kapselung des MapView sprechen [28].

Immer gegeben in einem MapView ist einTilesOverlay, welches aus den Kartenkacheln die grundsätzliche Karte zusammensetzt. Einer Karte können auch weitere TilesOverlays hinzugefügt werden. Alle Overlays erben von der abstrakten KlasseOverlayund werden in einem DefaultOverlayManager des MapView verwaltet. Der DefaultOverlayManager ist im Grunde eine Implementation einer Liste von Overlays mit zusätzlichen Methoden zum Zugriff auf Overlays. Auf ihn kann durch eine entsprechende Getter-Methode des MapView zugegriffen werden. Osmdroid bietet eine ganze Reihe von Overlay-Klassen an, um welche die Karte erweitert werden kann8. Einige dieser Overlays werden an unter- schiedlichen Stellen dieser Arbeit noch genauer betrachtet. Ein MapView, oder genauer das von ihm genutzte TilesOverlay, benötigt immer einen Tile Provider um Kacheln zur Anzeige zu bringen.

Tile Provider

Der Tile Provider definiert wie die Kacheln geladen werden sollen. Tiles können grund- sätzlich aus Assets, Archiven im Dateisystem (z.B. ZIP und SQLite), dem Tile Cache oder durch Downloads von einem Webserver geladen werden. Diese Möglichkeiten las- sen sich beliebig kombinieren. Ein Tile Provider erbt immer von MapTileProviderBase. Standardmäßig wird durch den MapView ein Tile Provider der Klasse MapTileProvi- derBasic, einer Unterklasse von MapTileProviderArray erzeugt. MapTileProviderArray durchsucht den Tile Cache synchron nach dem angeforderten Tile (oder mehreren) und wenn dies fehlschlägt wird die Anfrage an die asynchron arbeitenden modularen Tile Provider der implementierenden Klasse weitergeleitet. Im Fall von MapTileProviderBa- sic wird also erst der Cache synchron durchsucht und, falls das Tile nicht gefunden wurde, die Suche in Archiven und durch den Downloader asychron fortgesetzt [29]. Dies wird durch weitere in MapTileProviderBasic erzeugte Tile Provider Klassen ermöglicht. Um die Struktur besser nachvollziehen zu können wird an dieser Stelle ein stark vereinfachtes Klassendiagramm mit Abbildung 2.3 bereitgestellt. Tiefer soll hier in die Tile Provider

8Die direkten Unterklassen sind hier aufgeführt: https://osmdroid.github.io/osmdroid/

javadocAll/org/osmdroid/views/overlay/Overlay.html

(22)

Abbildung 2.3.: Grundsätzliche Tile Provider Struktur in Osmdroid

Klassen nicht eingegangen werden. Ausführlichere Informationen zu Tile Providern sind unter [29] zu finden. Es sei darauf hingewiesen, dass die genannten Klassen nur einen kleinen Teil der möglichen Provider bilden. Die hier vorgestellten Provider-Klassen sind jedoch die gängigsten und auch vom MapView standardmäßig genutzten. Da es viele Anbieter für Tiles gibt, deren Kacheln sich beispielsweise in Format oder Aussehen un- terscheiden können, wird im Tile Provider noch eine Tile Source definiert, die für alle Anfragen nach neuen Tiles verwendet wird [29].

Tile Source

Die Tile Source definiert den Typ der Kachel und stellt die Funktionalität zum er- stellen von gerenderten Drawables zur Verfügung. Alle Tile Source Klassen nutzen das

(23)

Interface ITileSource. Die abstrakte Klasse BitmapTileSourceBase implementiert dieses Interface und kann für alle Formen von Rastergrafiken verwendet werden. Um diese Rastergrafiken von einem Webserver abrufen zu können, kann die Klasse OnlineTile- SourceBase verwendet werden. Ihr können eine beliebige Anzahl von URLs hinzugefügt werden, von denen die Kacheln abgefragt werden sollen. Ob mit dieser Klasse auch Ka- cheln für die spätere Nutzung (preventiv) heruntergeladen werden können und ob auch große Datenmengen (bulk data) heruntergeladen werden dürfen wird über dieTileSour- cePolicy geregelt. Wenn eine Tile Source keine TileSourcePolicy hat, dann existieren auch keine durch Osmdroid eingeführten Restriktionen für sie. Eine XYTileSource ist eine besondere Form der OnlineTileSourceBase, bei der die URL die Form BasisUR- L/Z/X/Y.Dateiendung annimmt. Z ist dabei die Zoomstufe und X und Y die Indizes in x- bzw. y-Richtung. Abbildung 2.4 zeigt ein Klassendiagramm zur Veranschaulichung der Beziehungen zwischen den Klassen.

In der TileSourceFactory werden Tile Sources erzeugt und zur Verwendung in der Karte zur Verfügung gestellt. Alle Quellen für Kacheln, die über die statischen Methode getTileSources()dieser Klasse zurückgegeben werden, erfordern keine Registrierung, sind kostenfrei nutzbar und können als standalone Karte verwendet werden, ohne dass sie, wie einige andere Overlays, nur in Kombination mit einem anderen Kartenoverlay angezeigt werden können. Es wurde sich in der App auf diese Auswahl beschränkt, auch wenn in der Factory und anderen separaten Klassen noch weitere Tile Sources vorgefertigt sind.

Wenn eine der vorgefertigten Tile Sources oder eine nicht von Osmdroid angebotene Tile Source ebenfalls genutzt werden können soll, dann kann diese der TileSourceFactory hinzugefügt werden9.

Das Caching oder Rehosting von Kacheln sowie die Nutzung von heruntergeladenen Kartendaten im Allgemeinen wird von vielen Anbietern von Kartenkacheln verboten oder an Bedingungen geknüpft. Besonders sehr starke Beanspruchung der Tile-Server durch Downloads der Kacheln ist oft ausdrücklich untersagt. Für Verletzungen der Policies der Anbieter übernimmt Osmdroid keine Haftung, weshalb sich nicht voll auf die durch das Framework durchgesetzten TileSourcePolicies verlassen werden sollte [30]. Bei vielen Anbietern sind diese Bestimmungen sehr schwer zu finden. Die folgende Liste gibt eine Übersicht über die frei verfügbaren Tile Sources, auf die sich in der App beschränkt wird

9Mehr Informationen zu Tile Sources allgemein können unter https://github.com/osmdroid/

osmdroid/wiki/Map-Sourceserlangt werden.

(24)

Abbildung 2.4.: Vereinfachtes Klassendiagramm zu Tile Sources und verwandten Klassen

und klärt über ihre Restriktionen auf:

Mapnik ist das Toolkit, das OSM standardmäßig verwendet und es wird auch hier angeboten. Die OSMFoundation verbietet jedoch größere Downloads der Tiles von den Servern von OSM, um eine noch höhere Auslastung zu vermeiden. Einen Bereich mit über 250 Kacheln auf Zoom-Stufe 13 oder höher für offline-Nutzung oder generelle spätere Nutzung herunterzuladen ist verboten [31]. Auch andere Anbieter haben Restriktionen bezüglich der Downloads von Tiles.

Openptmap, bzw. in Osmdroid OSMPublicTransport genannt, stellt den öf-

(25)

fentlichen Transportverkehr in einer Art Liniennetz in verschiedenen Farben dar [32]. Zu den Tile Servern und möglichen Restriktionen bezüglich Downloads von Kacheln konnten keine Informationen gefunden werden. Allerdings arbeiten die Server zum Laden der Openptmap gar nicht mehr oder nur sehr unzuverlässig.

• DieHibe & Bike Mapoder kurzHikeBikeMapist gut geeignet zum Wandern und Fahrradfahren, da sie auch kleinere Wege und Pfade anzeigt10. Sie wird auf Wikimedia Labs gehostet und es wird darum gebeten die gleiche Policy in Bezug auf Kartenkacheln zu berücksichtigen wie für OSM [33].

• Der United States Geological Survey, kurz USGS, stellt Kacheln für eine topologi- sche Karte (USGSTopo) und eine Karte aus Satellitensicht (USGSImageryTopo bzw.USGSSat) zur Verfügung. Auch bei diesem Anbieter ist es schwer weitere In- formationen zu Bestimmungen bezüglich der Kacheln und Kachelserver zu finden.

Im FAQ wird jedoch zumindest erwähnt, dass es keine Restriktionen bezüglich her- untergeladenem Material gibt [34]. Beide Anbieter des USGS lieferten im Zeitraum der Anfertigung dieser Arbeit nur Kartenkacheln für die Zoomstufen 8 oder nied- riger. Für alle Zoomstufen, die weiter hereingezoomt sind, wird der Status-Code Not Found zurückgegeben11.

• Drei aeronatische Karten der USA stehen ebenfalls zur Auswahl. Diese werden in Osmdroid als ChartbundleWAC (World Aeronautical Chart12), Chartbund- leENRH (Enroute High für Flüge in größerer Höhe) und ChartbundleENRL (Enroute Low für Flüge in niedrigerer Höhe) bezeichnet. Für den Rest der Welt sind nur die Ländergrenzen eingetragen. Zu diesen Karten konnten keine Bestim- mungen zu den Kachelservern gefunden werden.

Opentopomap ist ein weiterer Anbieter von Kacheln. Das Kartenmaterial von OpenTopoMap steht unter der "Attribution-ShareAlike 3.0 Unported"-Lizenz zur Verfügung13. Allerdings sollen auch hier Massendownloads vermieden werden [35].

10Eine verkürzte Legende von Markierungen ist im Reiter "Info"unter http://hikebikemap.net/ be- schrieben.

11Dies kann auch auf den entsprechenden Internetseiten der beiden Server nachgeprüft wer- den, indem für die verschiedenen Zoomstufen auf Start Tile oder End Tile unter folgen- den Links gedrückt wird: USGS Topografisch: https://basemap.nationalmap.gov/arcgis/rest/

services/USGSTopo/MapServer und USGS Satellit: https://basemap.nationalmap.gov/arcgis/

rest/services/USGSImageryTopo/MapServer

12https://www.faa.gov/air_traffic/flight_info/aeronav/productcatalog/vfrcharts/world/

13https://creativecommons.org/licenses/by-sa/3.0/

(26)

Es wurde jedoch keine genaue Begrenzung wie bei OSM festgelegt. Eine E-Mail an die Betreiber von OpenTopoMap, mit der Schilderung des Projektes, in wel- ches OpenTopoMap eingebaut werden soll und einer Nachfrage bezüglich eines Download-Limits für Kacheln, blieb unbeantwortet.

Die Restriktionen für die Anbieter von Tiles können sich jederzeit ändern. Von den aufgeführten Kachelanbietern wurden bezüglich Verlässlichkeit und Ladezeiten mit Map- nik, Hikebikemap, den aeronautischen Karten und überwiegend auch mit Opentopomap positive Erfahrungen gemacht. Dennoch kann sich nicht darauf verlassen werden, dass diese Anbieter zu jeder Zeit zur Verfügung stehen.

Konfiguration

Die Singleton-KlasseConfiguration in Osmdroid nutzt einenIConfigurationProvider, der alle wichtigen Einstellungen verwaltet. Geladen werden können diese Einstellungen durch die folgenden Zeilen [27].

1 I C o n f i g u r a t i o n P r o v i d e r conf = C o nf i gur ati o n . g e t I n s t a n c e ( ) ;

2 conf . load ( ctx , PreferenceManager . g e t D e f a u l t S h a r e d P r e f e r e n c e s ( ctx ) ) ; Listing 2.1: Laden der SharedPreferences

Alternativ können auch für die App spezifische Präferenzen geladen werden. Dabei wird auch das Basisverzeichnis und das Tile Cache Verzeichnis gesetzt und initialisiert.

Es wird der größte schreibbare Einhängepunkt (mount point) verwendet, wenn dies nicht anders in den Präferenzen festgelegt ist [36]. Der OsmdroidBasePath wird dabei standardmäßig auf ein Verzeichnis /osmdroid gesetzt, das erzeugt wird, falls es noch nicht existiert hat. Hier werden beispielsweise alle Arten von Archiven und offline Tile Sources abgelegt. DerOsmdroidTileCache wird standardmäßig als/osmdroid/tiles fest- gelegt. Hier wird die Cache Datenbank abgelegt. Beide Werte können auch später noch durch entsprechende Setter des IConfigurationProvider gesetzt werden. Der Tile Cache besitzt im Gegensatz zu Tile Archiven ein Expirationsdatum. Auf diese beiden Arten von Speicher kann über einen CacheManager zugegriffen werden [37]. Auf diesen wird in Kapitel 4.10.2 nochmal Bezug genommen.

Es wird empfohlen beim Start der App den User-Agent Wert auf den Namen der App festzulegen, damit bei Missbrauch der Tile Server nur die Nutzer dieser App gebannt werden und nicht alle Osmdroid Nutzer. Dafür reicht es

(27)

1 conf . setUserAgentValue ( BuildConfig .APPLICATION_ID) ;

Listing 2.2: UserAgent für die Anwendung setzen

aufzurufen. In jeder Anfrage an einen Tile Server wird dann dieser Wert im User-Agent Header mitgeschickt und die Anwendung kann dadurch identifiziert werden [36].

Auch Debug-Optionen für allgemeines Debugging und speziell für Tile Provider, Tile Downloader und den MapView können über den IConfigurationProvider eingeschaltet werden.

(28)

In diesem Kapitel sollen die Anforderungen an die zu entwickelnde App herausgearbeitet werden.

3.1. Zielgruppe

Da es bei diesem Projekt um die Entwicklung einer Komponente für die bereits existie- rende und sich stetig weiterentwickelnde SharkNet2 App handelt, ist die Zielgruppe vor allem die der Entwickler, die ebenfalls die Anwendung weiterentwickeln. Dennoch soll das Endprodukt auch von Personen genutzt werden können, die keine Entwickler sind.

Wie jede Komponente sollte auch diese darum einfach erweiterbar sein. Weiterhin ist es wichtig eine enge Kopplung von Klassen weitestgehend zu vermeiden, um Wieder- verwendbarkeit und Testbarkeit zu fördern. Zur Unterstützung von Modularität sollen wenn möglich abstrakte Klassen und Interfaces eingesetzt werden.

Es soll bei der Entwicklung darum gehen, eine gute Grundlage für die Weiterentwicklung der Komponente zu schaffen. Osmdroid ist sehr umfangreich und bietet sehr viele Mög- lichkeiten mit Kartendaten zu arbeiten. Wenn die Komponente weiterentwickelt wird, dann soll dafür möglichst wenig Bestehendes geändert werden müssen und stattdessen die im Rahmen dieses Projektes definierten Objekte und Schnittstellen weiter flexibel genutzt werden können. Es soll nicht darum gehen so viele Funktionen wie möglich in die App zu integrieren.

3.2. Anforderungen

3.2.1. Funktionale Anforderungen

• Eine Reihe von Funktionen für Tracks soll dem Benutzer zur Auswahl stehen.

Dazu gehören als Mindestanforderungen das Aufnehmen, Visualisieren, Speichern

(29)

und Laden, sowie das Exportieren und Importieren in ausgewählten Dateiformaten.

Für bereits bestehende Tracks sollten ihre Metadaten (z.B. der Name des Objekts) editierbar sein und sie sollten auch wieder gelöscht werden können. Eine weitere Funktionalität ist das Verschmelzen von mehreren Tracks zu einem. Dazu muss ein neuer Track erstellt werden können, der alle Segmente und ihre Trackpunkte erhält. Weitere Methoden für Tracks sollen hinzukommen können.

• Es ist auch möglich, dass diese Komponente nicht immer nur mit Tracks arbeiten wird, sondern auch mit anderen Objekten ähnliche Operationen ausgeführt können sollen wie mit Tracks. Aus diesem Grund soll eine Abstraktion für Objekte, die mit geografischen Informationen arbeiten, entwickelt werden, von der Tracks eine Implementierung darstellen. Beispiele für solche Objekte sind Points of Interest oder Routen, die beide im OSMBonusPack1 implementiert sind. Diese Bibliothek wird für diese Arbeit zwar nicht verwendet, in Zukunft könnte sie jedoch dieser Komponente hinzugefügt werden. Im Kapitel 4.5 wird auf diese Erweiterung von Osmdroid nochmal Bezug genommen.

• Dem User soll es möglich sein Kartendaten auch offline nutzen zu können. Dazu soll direkt in der App ein kleiner Teil der Karte bei bestehender Internetverbindung heruntergeladen werden und offline genutzt werden können.

• Es soll möglich sein den Anbieter des Kartenmaterials zu wechseln und neue An- bieter hinzuzufügen. Das Format und die Art der Kartenkacheln sollen variabel bleiben.

• Um die Entwicklung von weiteren Komponenten für SharkNet2 zu unterstützen, sollen auch andere Komponenten von dieser Komponente profitieren können, indem sie die Funktionalität zur Ortung, die zum Tracking gebraucht wird, ebenfalls nutzen können sollen.

3.2.2. Nichtfunktionale Anforderungen

• Die App soll robust gegenüber Benutzereingaben sein.

• Die Oberfläche soll möglichst intuitiv sein und Hinweise sollen helfen an Stellen, an denen die Nutzung komplexer ist.

• Da die Komponente letztlich in SN2 integriert werden soll, sollte dies ohne große Umstände möglich sein. Dies kann durch Versionsabweichungen etwas erschwert

1https://github.com/MKergall/osmbonuspack

(30)

werden. Die zu Beginn der Entwicklung dieses Projektes in SharkNet2 aktuellen Sdk-Versionen werden während der Entwicklung nicht verändert (compileSdkVer- sion: 27, minSdkVersion: 23 und targetSdkVersion: 27). Der Aufbau und die Optik sollten wenn möglich nicht zu stark von anderen Komponenten in SN2 abweichen.

(31)

In diesem Abschnitt sollen die zur Erfüllung der Funktionen nötigen Klassen entworfen werden. Der auf dieses Kapitel folgende Abschnitt der Implementierung beschreibt wie diese Teile letztlich zu einer App zusammengesetzt wurden. Das GitHub Repository, in dem der Code für diese App liegt, ist unter https://github.com/runnninggag/

GPSTrackerzugänglich.

4.1. GeoModel und Track

Damit die Komponente neben Tracks in Zukunft um weitere Objekte zur Visualisie- rung ergänzt werden kann, muss wurde eine abstrakte Oberklasse für Tracks entworfen, die gemeinsame Eigenschaften aller solcher Objekte in sich vereint. Diese Klasse wurde GeoModel genannt und soll folgende Eigenschaften erhalten:

• Eine ID, die einzigartig ist und von der App vergeben wird. Sie soll auch dann einzigartig sein, wenn das GeoModel ursprünglich von einem anderen Nutzer der App erstellt wurde. Dies wird über eine zufällig generierte UUID erreicht.

• Einen Objektnamen, der vom User selbst gewählt werden kann.

• Den Namen des Erstellers.

• Den Zeitpunkt der Erstellung des Objekts.

Wie in Kapitel 2.4 bereits ausgeführt, gibt es Unterschiede in der Definition eines Tracks in verschiedenen Datenformaten. Für dieses Projekt wird die Struktur eines Track Objekts ähnlich wie die Struktur der Tracks in GPX sein. Tracks werden dafür in Seg- mente unterteilt und diese Segmente enthalten die Trackpunkte. Trackpunkte sollen den Zeitpunkt ihrer Aufnahme und die geografische Position in Längen- und Breitengrad enthalten. Für die Speicherung einer geografischen Position stellt Osmdroid die Klasse GeoPointzur Verfügung. In einem GeoPoint können Längengrad, Breitengrad und Höhe gespeichert werden. Abbildung 4.1 zeigt das zugehörige Klassendiagramm.

(32)

Abbildung 4.1.:Vereinfachtes Klassendiagramm für GeoModel und Track

4.2. Location Service

Um Tracks aufzeichnen zu können, muss eine Klasse existieren, die Positionsupdates empfängt. Eine auf diese Art erhaltene Position muss daraufhin dem aufgenommenen Track hinzugefügt werden können. Die Aufnahme soll nicht unterbrochen werden müs- sen, wenn das Gerät in den Schlafmodus (Doze Mode) übergeht. Es soll zusätzlich eine Möglichkeit für weitere Objekte geben die Positionsupdates zu empfangen und unter- schiedlich zu nutzen, auch in anderen Komponenten in SN2.

Um diese Anforderungen zu erfüllen wird einLocationService entworfen. Listing 14 zeigt die MethodeonStartCommand des LocationService, die immer aufgerufen wird wenn er gestartet wird. Der Service nutzt einenLocationManager1um auf den durch Android be- reitgestellten Location Service zuzugreifen. Dem LocationManager wird ein GPS Provi- der und ein Netzwerk Provider hinzugefügt, mit deren Hilfe Positionsupdates empfangen werden können. Diesen können auch eine Mindestzeit in Millisekunden (updateMinTi- me) und eine Mindestdistanz in Metern (updateMinDistance) als Mindestdifferenz zum letzten Positionsupdate vorgeschrieben werden, damit nicht ständig Updates der Positi-

1https://developer.android.com/reference/android/location/LocationManager

(33)

on geliefert werden, die sich kaum von der vorangegangenen unterscheiden. Sollte keine Berechtigung zum Zugriff auf die Position durch den Nutzer gegeben worden sein, so wird der Service zwar gestartet, liefert jedoch keine Positionsupdates.

1 @Override

2 p u b l i c i n t onStartCommand ( I n t e n t intent , i n t f l a g s , i n t s t a r t I d ) {

3 super. onStartCommand ( intent , f l a g s , s t a r t I d ) ;

4 locationManager = ( LocationManager ) getSystemService ( Context . LOCATION_SERVICE) ;

5 l o c a t i o n L i s t e n e r = new GpsLocationListener ( ) ;

6 try {

7 locationManager . requestLocationUpdates ( LocationManager .GPS_PROVIDER, updateMinTime , updateMinDistance , l o c a t i o n L i s t e n e r ) ;

8 locationManager . requestLocationUpdates ( LocationManager .NETWORK_PROVIDER , updateMinTime , updateMinDistance , l o c a t i o n L i s t e n e r ) ;

9 } catch ( SecurityException e ) {

10 Log . e ( getLogStart ( ) , " Cannot r e q u e s t l o c a t i o n updates . I s l o c a t i o n permission granted ? ") ;

11 }

12 return START_STICKY;

13 }

Listing 4.1: Methode onStartCommand in LocationService, welche aufgerufen wird, wenn der Service gestartet wird

Der als Parameter übergebene LocationListener2 ist eine Instanz der inneren Klasse GpsLocationListener im LocationService. Alle Positionsupdates rufen die Methode on- LocationChanged(Location location)des LocationListener auf. Es wird ein Broadcast mit dem übergebenen Location-Objekt gesendet, sodass alle Klassen, welche die Positions- updates nutzen sollen, diese empfangen können. Der Broadcast soll jedoch nur gesendet werden, wenn die horizontale Genauigkeit des Location-Objekts unter einem festgeleg- ten Wert (maxHorizontalAccuracy) liegt. Die Genauigkeit (accuracy) ist definiert als der Radius um die Position herum, in der sich das Gerät mit einer 68%-igen Wahrschein- lichkeit tatsächlich befindet [38]. Es gibt also keine Garantie, dass das Gerät tatsächlich in diesem Radius liegt.

1 p u b l i c c l a s s GpsLocationListener implements L o c a t i o n L i s t e n e r {

2 @Override

3 p u b l i c void onLocationChanged ( Location l o c a t i o n ) {

2https://developer.android.com/reference/android/location/LocationListener

(34)

4 i f ( l o c a t i o n . getAccuracy ( ) <= maxHorizontalAccuracy ) {

5 I n t e n t i n t e n t = new I n t e n t ("LOCATION UPDATE") ;

6 i n t e n t . putExtra (" l o c a t i o n ", l o c a t i o n ) ;

7 sendBroadcast ( i n t e n t ) ;

8 }

9 }

10 @Override

11 p u b l i c void onStatusChanged ( S t r i n g provider , i n t status , Bundle e x t r a s ) {}

12

13 @Override

14 p u b l i c void onProviderEnabled ( S t r i n g p r o v i d e r ) {}

15

16 @Override

17 p u b l i c void onProviderDisabled ( S t r i n g p r o v i d e r ) {}

18 }

Listing 4.2:GpsLocationListener in LocationService

Abbildung 4.2 zeigt welchen Einfluss vor allem die Einschränkung der Genauigkeit auf das Erscheinungsbild eines auf diese Weise aufgenommenen Tracks haben kann. Die Werte sind so geblieben wie sie zum Zeitpunkt der Aufnahme des Tracks im rechten Bild (b) waren. Gut zu erkennen im linken Bild (a) ist, dass die Genauigkeit der Werte sehr stark schwanken kann. Werden sehr ungenaue Werte Location Objekte jedoch verworfen, ist das Ergebnis bezogen auf den absolvierten Weg deutlich realistischer.

Um die Broadcasts des GPSLocationListeners zu erhalten kann die abstrakte Klas- se BroadcastReceiver3 verwendet werden, die eine Methode onReceive(Context context, Intent intent)besitzt, die immer aufgerufen wird, wenn ein Broadcast empfangen wird.

Statt jedoch jedes Objekt, das die Positionsupdates verwenden soll, BroadcastReceiver erweitern zu lassen, sollen diese Objekte stattdessen das Interface ILocationConsumer implementieren, das zu diesem Zweck eine Methode onLocationChanged(Location loca- tion) zur Verfügung stellt. An dieser Stelle fehlt noch eine Klasse, die BroadcastRecei- ver erweitert und eine Liste von Objekten der Klasse ILocationConsumer enthält. Diese Klasse wurdeLocationReceiver genannt. Sie ruft bei jedem Empfang einer neuen Position für jeden dieser Consumer die onLocationChanged()-Methode auf. Durch die Verwen- dung dieses Interfaces ist LocationReceiver nicht an eine spezifische Art von Objekten

3https://developer.android.com/reference/android/content/BroadcastReceiver

(35)

(a)Werte: updateMinTime = 0, updateMinDi- stance = 0 und maxHorizontalAccuracy = 100

(b)Werte: updateMinTime = 3000, update- MinDistance = 5 und maxHorizontalAccu- racy = 30

Abbildung 4.2.: Zwei Tracks aufgenommen mit unterschiedlichen Parametern im LocationS- ervice

gebunden und kann so beliebig viele Objekte, die das Interface implementieren, über Po- sitionsupdates informieren. Track implementiert nun ILocationConsumer und fügt beim Empfang einer Location diese seinem zuletzt erstellten Tracksegment hinzu. Abbildung 4.3 soll die Beziehungen veranschaulichen.

(36)

Abbildung 4.3.: Klassendiagramm zur Veranschaulichung des LocationReceiver und seinen Be- ziehungen zu anderen Klassen

4.3. Verwaltung

Da die Grundvoraussetzungen zum Aufnehmen von Tracks damit gegeben sind, muss es noch ein Objekt geben, das alle Instanzen verwaltet. Auch auf andere Arten von GeoModels soll über ein solches Objekt zugegriffen werden können. GeoModels können jedoch in Zukunft sehr verschieden ausfallen. Es ist anzunehmen, dass einige Funktionen nur für spezifische Typen von GeoModels verfügbar sein sollen. Es lässt sich als Anfor- derung festhalten, dass für jeden Typ von GeoModel eine Sammlung aller GeoModels dieses Typs überall im Programm abgefragt werden können soll. DieserGeoModelMana- ger soll folglich typgebunden sein. Dies lässt sich in Java durch Generics umsetzen. Ein GeoModelManager sollte abstrakt sein und alle Methoden enthalten, die auf alle Typen von GeoModel angewendet werden können sollen. Für jeden Typ von GeoModel, der in einem Manager verwaltet werden soll, wird dann eine von GeoModelManager ableiten- de Klasse definiert, die als Typparameter den Typ des GeoModels erhält und ebenfalls die für diesen Typ spezifischen Methoden implementiert. Abbildung 4.4 zeigt wie dies umgesetzt wurde.

Neben einem Set von GeoModels des spezifischen Typs hält der GeoModelManager auch ein Set aller in der App existierenden GeoModels. Für beide Listen existieren Me- thoden zum Hinzufügen und Entfernen von GeoModels, zum Abfragen einzelner oder aller GeoModels und zum zählen der Elemente. Da GeoModels durch ihre UUID eindeu-

(37)

Abbildung 4.4.: Vereinfachtes Klassendiagramm für TrackModelManager ohne Methoden

tig identifiziert werden können, besteht auch nicht die Gefahr dass es zu Kollisionen bei Abfragen kommt.

4.4. Serialisierung

Die Speicherung der Tracks ist eine weitere Anforderung. Der erste Schritt zu ihrer Umsetzung ist es festzulegen wo und wie Tracks gespeichert werden sollen. Da durch diese App gespeicherte Tracks für andere Anwendungen keinen Nutzen haben und auch nicht durch andere Anwendungen manipuliert werden können sollen, können sie im internen Speicher der App gespeichert werden. Android empfiehlt dies besonders dann, wenn der Zugriff auf die Daten besonders verlässlich sein soll, wie es beim Laden von Daten beim Starten der App der Fall ist. Solange der benötigte Speicherplatz für die Objekte nicht zu groß wird ist der interne Speicher eine gute Wahl. Alternativ könnte auch eine Datenbank genutzt werden [39]. Das gleiche gilt für andere Arten von GeoModels, weshalb diese ebenfalls auf diese Art gespeichert werden können sollen. Um dies zu erreichen sollten alle Typen von GeoModels, die speicherbar sein sollen, sowie auch deren Unterklassen, dasSerializable Interface implementieren und jeweils eine serialVersionUID verwenden.

Außer der Speicherung soll auch das Laden der Objekte bei Programmstart in den für sie zuständigen Manager und das Löschen möglich sein. Ein InterfaceGeoModelStoragewird

(38)

genutzt, um die benötigten Methoden vorzugeben. Dieses ist wie der GeoModelManager auch typgebunden, weil jede Storage-Klasse die Speicherung, Löschung und das Laden seiner GeoModels selbst vornehmen soll. Manager und Storage lassen sich in einer Klasse kombinieren, wie in Abbildung 4.5 für den TrackModelManager dargestellt.

Abbildung 4.5.: Klassendiagramm zu TrackModelManager ergänzt um GeoModelStorage

Auf alle Tracks soll zu jeder Zeit von überall in der Komponente zugegriffen wer- den können. Aus diesem Grund wird bereits bei der Initialisierung der Komponente ein TrackModelManager erzeugt. Durch das Singeleton-Pattern ist sichergestellt, dass der TrackModelManager nur einmal existiert. Im privaten Konstruktor der Komponente werden bereits die Tracks aus den Dateien geladen.

1 p r i v a t e GPSComponent( ASAPApplication asapApplication ) {

2 t h i s. asapComponentHelper = new ASAPApplicationComponentHelper ( ) ;

3 t h i s. asapComponentHelper . setASAPApplication ( asapApplication ) ;

4 getTrackModelManager ( ) . loadAllGeoModelsFromFiles ( getASAPApplication ( ) . g e t A c t i v i t y ( ) ) ;

5 }

Listing 4.3:Laden der Tracks aus dem Speicher

Dazu wird für jedes Element in einem bestimmten Unterverzeichnis im internen Spei- cher der App geprüft, ob es sich um eine Datei handelt und wenn ja wird versucht diese als Track zu laden und dem TrackModelManager hinzuzufügen. Der TrackModelMa- nager nutzt das Unterverzeichnis/tracks. Für jede Art von GeoModel sollte ein eigenes

(39)

Unterverzeichnis im internen Speicher der App angelegt werden. Als Dateiname kann die UUID des Objekts verwendet werden, da sie einzigartig ist und keine Zeichen enthalten kann, die für Dateinamen nicht zulässig sind. Die Methode getFilesDir() der Context- Klasse wird genutzt, um den Pfad zum Verzeichnis im internen Speicher zu erhalten und ein InputStream für das Laden, bzw. ein OutputStream für das Speichern erstellt.

Dadurch dass die Dateien die IDs des gespeicherten GeoModels als Dateinamen besit- zen, können auch einfach spezifische GeoModel Dateien ausfindig gemacht werden. Dies wird sich beim Löschen zunutze gemacht. Es wird ein Objekt vom Typ File mit der ID des GeoModels als Dateinamen an der Stelle erstellt, an der es existieren müsste.

Auf diesem File-Objekte wird die Methodedelete()ausgeführt. Wenn die Datei existiert hat, dann wird sie gelöscht und true zurückgegeben. Wenn sie nicht existiert hat, dann gibt die Methode nur false zurück. Zusätzlich zu den genannten Methoden bekommt der TrackModelManager noch eine Methode zum Mergen von Tracks. Diese ist wie folgt implementiert.

1 p u b l i c void mergeTracks ( Set<Track> tracksToMerge , S t r i n g newTrackName , S t r i n g ownerName ) {

2 List <TrackSegment> trackSegments = tracksToMerge . stream ( )

3 . flatMap ( track −> track . getTrackSegments ( ) . stream ( ) )

4 . c o l l e c t ( C o l l e c t o r s . t o L i s t ( ) ) ;

5 Track track = new Track (null , newTrackName , ownerName , LocalDateTime . now ( ) , trackSegments ) ;

6 addGeoModel ( track ) ;

7 }

Listing 4.4: Methode zum Mergen von Tracks

Dadurch können mehrere aufgenommene Tracks, die nach ihrer Aufnahme immer nur ein Segment enthalten zu einem Track mit mehreren Segmenten kombiniert werden. Der neu generierte Track wird dem Manager hinzugefügt. Die zum Verschmelzen verwendeten Tracks werden dabei nicht gelöscht.

4.5. Import und Export

In Kapitel 2.4 wurde bereits behandelt, inwiefern ausgewählte GIS-Datenformate Tracks unterstützen und wofür sie eingesetzt werden. Von den betrachteten Dateiformaten bie-

(40)

ten nur GPX und KML eine Unterteilung in Segmente. Auch wenn die Definition von Tracks etwas verschieden ist, sind sich die beiden Formate sehr ähnlich in ihrem Auf- bau. GPX soll für Import und Export verwendet werden können, da es ein sehr häufig genutztes Austauschformat für Tracks ist. KML hingegen ist besonders zum Darstellen in anderen Anwendungen geeignet. Es ist unwahrscheinlich, dass ein Nutzer einen Track in KML-Format in die App importieren möchte und wenn doch gibt es für diesen Fall zahlreiche Anwendungen, wie beispielsweise GPSBabel4, zur Konvertierung der Daten in ein anderes Format. Der Export von KML ist dagegen sehr praktisch um Tracks, die in der App aufgenommen wurden, in einer Anwendung wie Google Earth Pro in einer dreidimensionalen Umgebung zu betrachten. Die Grundstruktur zur Implementierung des Imports und Exports wurde wie in Abbildung 4.6 entworfen.

Abbildung 4.6.: Klassendiagramm zu Dateiformaten

4https://www.gpsbabel.org/

(41)

Jedes Format ist durch einen Media Type5definiert und besitzt eine Dateiendung. Um ein solchesFileFormat zum Importieren verwenden zu können, muss esImportFileFor- matimplementieren. Für den Export mussExportFileFormat implementiert werden. Der FormatManager verwaltet die zwei statischen Maps importFormats und exportFormats. Der Key ist dabei immer die Dateiendung und der Value das entsprechende Format. Der FormatManager enthält weitere statische Methoden zum Zugriff auf die Werte in den Maps, die in der Abbildung zur besseren Übersicht nicht dargestellt sind. Dateiformate werden in einem statischen Block dem FormatManager wie folgt hinzugefügt.

1 s t a t i c {

2 r eg iste rFor mat (new KMLFileFormat ( ) ) ;

3 r eg iste rFor mat (new GPXFileFormat (GPSComponent . getTrackModelManager ( ) ) ) ;

4 }

5

6 p r i v a t e s t a t i c void reg iste rFor ma t ( FileFormat f i l e F o r m a t ) {

7 i f ( f i l e F o r m a t i n s t a n c e o f ImportFileFormat ) {

8 importFormats . put ( f i l e F o r m a t . g e t F i l e E x t e n s i o n S t r i n g ( ) , ( ImportFileFormat ) f i l e F o r m a t ) ;

9 }

10 i f ( f i l e F o r m a t i n s t a n c e o f ExportFileFormat ) {

11 exportFormats . put ( f i l e F o r m a t . g e t F i l e E x t e n s i o n S t r i n g ( ) , ( ExportFileFormat ) f i l e F o r m a t ) ;

12 }

13 }

Listing 4.5: Registrieren von neuen Dateiformaten im FormatManager

Für das GPXFileFormat wurde die Bibliothek JPX verwendet, die schon kurz in Ka- pitel 2.6.1 behandelt wurde. Alle Elemente und Knoten in GPX sind durch eine entspre- chende Klasse oder ein Attribut in JPX in Java abgebildet. Die oberste Klasse in dieser Struktur ist dabei die KlasseGPX selbst. Die beiden durch die Bibliothek bereitgestell- ten statischen Methoden read(InputStream input), sowie write(GPX gpx, OutputStream output), können verwendet werden, um die Daten aus einer Datei zu lesen oder in eine Datei zu schreiben.

Für KML wurde keine geeignete open source Bibliothek gefunden. Ursprünglich sollte das schon in Kapitel 3.2.1 kurz angesprochene OSMBonusPack verwendet werden, um

5Eine Übersicht aller definierten Media Types ist hier zu finden:https://www.iana.org/assignments/

media-types/media-types.xhtml

Referenzen

ÄHNLICHE DOKUMENTE

Als Beispiel für die mit dem vorgestellten Prüfstand erzielbaren Ergebnisse zeigt Abbildung 3 den RSSI einer Ohrmarke mit dem Transpondertyp B3-4 im gesamten

Additionally, because of its folded dipole structure it features a symmetrical directional characteristic (d eTlefSen and S iarT 2009, upm rfid 2011), that offers advantages for

4 Für die Ge- sprächsanalyse etwa konstatiert Kotthoff (2012: 292), dass die beschriebenen In- teraktionen „im deutschsprachigen Kontext eine […] bislang nicht beachtete

Op-Art  ist  “Kunst  für  alle”,  denn  zum  Betrachten  der  Bilder  sind  keine  Vorkenntnisse  aus  Kunst,  Kultur  oder  Geschichte  erforderlich.  Nur 

Die Schüler schlagen vor, dass es schön wäre, auch in der Schule einen Adventskalender zu

Unter Einsatz von verschiedenartigen Bildern (auch Luftbilder) und Karten (angewandte Karten) sollen die Schüler erkennen, daß Räume durch das Überwiegen von Landwirtschaft,

Schülerinnen und Schüler von Ludwigshafener Schulen, die noch ausgeliehene Schulbücher zurückgeben müssen, können dies in der Zeit von Montag, 28.. Juli 2014 jeweils von 9 bis 16

Dokumente als Ausgangspunkt zur Annäherung an das System Nationalsozialismus und nicht als Illustration einer