3.4 Technische Untersuchung von OpenLayers
An dieser Stelle wird die Funktionsweise von OpenLayers genauer
betrachtet. Diese Analyse dient zum besseren Verständnis der Anwendung
und ist Voraussetzung für die nachfolgende Konzeptplanung und
Realisierung.
OpenLayers ist eine reine JavaScript-API zum Erstellen von
WebMapping-Anwendungen und bietet Unterstützung zum Anzeigen
zahlreicher (standardisierter) Formate
(OGC WMS, OGC WFS, GeoRSS, ka-Map, WorldWind u. v. m.),
die als Ebenen in OpenLayers eingebunden werden.
Darüber hinaus bietet OpenLayers ein Verschieben und Zoomen
von Karten, clientseitiges Tiling, Markers, »Popup-Blasen«, verschiedene anpassbare
Steuerelemente, Tastatursteuerungsbefehle, einen robusten
Event-Handling-Mechanismus u. a. m. Jeder Teil von OpenLayers
ist konfigurierbar [OpenLayers d].
Ein Python/Shell-basiertes Skript ermöglicht das automatische Bauen
einer lite-Version von OpenLayers, wodurch nur
gewünschten Klassen in eine einzige JavaScript-Datei
integriert werden können [OpenLayers a].
Dies ist das Ergebnis einer Diskussion auf der FOSS4G-Konferenz im
September 2006, wonach eine solche Lösung unter dem Namen
webmap.js gefordert wurde [OSGeo 2006a][OSGeo 2006b].
Die Zielgruppe von OpenLayers sind alle Anwender oder
Entwickler, die eine Karte im Internet darstellen oder eine
kartenbasierte Internetanwendung aufbauen möchten [OpenLayers d].
Die Veröffentlichung von Google Maps im Februar 2005
bewirkte große Aufmerksamkeit. Aufgrund zahlreicher
reverse engineerings des Google Maps Codes
(u. a. von Phil
Lindsay25) antwortete Google kurz darauf, im Juni 2005,
mit einer ersten Google Maps
API26.
Es fehlte jedoch die Möglichkeit, diese kommerziell einzusetzen
[Ramsey 2006][OpenLayers f].
Das US-Unternehmen MetaCarta nahm sich dieses Mangels an und
entwickelte, unter der Mitwirkung von Phil Lindsay, einen ersten
Prototypen des späteren OpenLayers, der auf der
Where 2.0 Konferenz Ende Juni 2005 in San Francisco präsentiert
wurde27. Ein Jahr später, kurz nach der Where 2.0 im
Juni 2006 in San Jose, veröffentlichte das Team um die
Hauptentwickler Schuyler Erle,
Christopher Schmidt und Erik Uzureau am 5. Juli 2006 die erste
offizielle Version (1.0) von OpenLayers.
Im August 2006 erschien das Projekt bereits unter der Versionsnummer
2.0 [OpenLayers d][OpenLayers f].
Aktuell befindet sich OpenLayers im
Inkubationsprozess der Open Source
Geospatial Foundation (OSGeo), mit dem Ziel, im Sommer 2007
als Softwareprojekt in diese unabhängige Organisation aufgenommen zu
werden. Parallel laufen ernsthafte Bestrebungen, Kern- funktionalitäten
von OpenLayers in andere Freie WebMapping-Anwendungen
zu integrieren [OpenLayers d] - aktuelle Diskussionen werden derzeit
bei ka-Map28,29,
Mapbuilder30 und
Mapbender31 geführt.
Die OpenLayers-API gliedert sich durch die objektorientierte
Programmierweise in eine Vielzahl von Klassen. Die wichtigsten werden
nachfolgend kurz beschrieben.
Auf die restlichen Klassen soll hier nicht weiter eingegangen werden,
da sie für das grundlegende Verständnis der API nicht von Bedeutung sind.
Für detailliertere Informationen wird auf die
JSDoc-Dokumentation32
verwiesen. Ein vollständiges Klassendiagramm von OpenLayers
(Version 2.4 RC5; Stand: 25.5.2007) befindet sich
im Anhang 6.3.
- OpenLayers.Map
- ist die zentrale Klasse der
OpenLayers-API.
Sie erstellt
die Hauptkarte der Anwendung und stellt zahlreiche Methoden
zum Verwalten der Kartenanzeige zur Verfügung. Dazu zählen
u. a. das Darstellen von Ebenen und Bedienelementen,
das Verändern der Zoomstufen und das Verschieben
der Karte.
Zusätzlich ermöglicht die Klasse, über zahlreiche
get-Methoden, den aktuellen Kartenstatus abzufragen.
- OpenLayers.Layer:
- Die Ebenen repräsentieren den wichtigsten
Bestandteil von OpenLayers. Alle
Kartendarstellungen basieren auf der Layer-Klasse.
Layer.js erzeugt einzelne
Ebenen, setzt deren Sichtbarkeit und Auflösung und stellt
grundlegende get-Methoden zur Verfügung.
OpenLayers.Layer dient als Basisklasse
für eine Vielzahl von speziellen Unterklassen.
In der OpenLayers-Version 2.4 RC5 werden folgende
Ebenentypen unterstützt:
Freie kachelbasierte Ebenen (WMS, MapServer, KaMap,
TMS, WorldWind), Freie ungekachelte Ebenen (WMSUntiled,
MapServerUntiled), Ebenen von proprietären Drittanbietern
(Google, VirtualEarth, Yahoo, MultiMap)
sowie die Ebenen
Image (zum Darstellen einer Rastergrafik)
und Canvas (zum Zeichnen von farbigen Linien, nur
Overlay-Darstellung möglich).
Nachfolgend werden vier Ebenenklassen genauer beschrieben:
OpenLayers.Layer.Grid
Abgeleitet von der HTTPRequest-Klasse steht Grid
als eine wichtige Basisklasse für die o. g. Freien kachelbasierten
Ebenen zur Verfügung. Grid.js unterteilt die Ebenen
in Kacheln, verwaltet diese in einem Array und lädt sie in
spiralförmiger Reihenfolge, beginnend in der Mitte.
OpenLayers.Layer.WMS
Als Unterklasse von Grid bekommt WMS die URL
des WMS-Servers übermittelt und ist zuständig
für die Generierung der einzelnen Kachel-WMS-URLs anhand der
gewünschten Kachelbegrenzung (bounds).
OpenLayers.Layer.WMS.Untiled
Die Untiled-Klasse bildet den gesamten
Kartenausschnitt in einer WMS-Kachel-URL ab.
Zu beachten ist dabei die von vielen WMS-Servern in der Regel
vordefinierte maximale Kachelgröße von 2048 Pixeln;
fordert OpenLayers einen größeren Kartenausschnitt
an, gibt der WMS-Server eine Fehlermeldung zurück und die
Karte bleibt leer.
OpenLayers.Layer.Image
Abgeleitet von Layer erlaubt die
Image-Klasse das Darstellen einer einzelnen
Bitmap-Grafik als Kartenebene. Gefordert sind neben der URL
der Grafik die Pixelgröße sowie die geografische Ausdehnung
des zu verwendenden Bildes.
- OpenLayers.Control:
- Bedienelemente in OpenLayers
sind Elemente zur Kartennavigation sowie
zur Darstellung von Karteninformationen (z. B. Maßstab).
Die Control-Klasse dient als Basisklasse für alle
Bedienelemente. Nachfolgend eine Auswahl:
OpenLayers.Control.PanZoom
erstellt eine Pan-Zoom-Navigation mit einem
Pan-Steuerkreuz (4 Pfeil-Buttons) sowie jeweils einem
ZoomIn-, ZoomOut- und ZoomReset-Button.
Der slideFactor-Parameter definiert die Anzahl der
Pixel, um die die Karte beim Benutzen der Pan-Steuerbuttons
verschoben wird.
OpenLayers.Control.PanZoomBar
erstellt eine Pan-Zoom-Navigationsleiste mit einem
Pan-Steuerkreuz sowie einer Zoombar mit einem Zoomslider und
jeweils einem ZoomIn- und ZoomOut-Button an den Enden der
Leiste (vgl. Abb. 2.3.4).
Die Zoombar ist für die Entwicklung des animated
zooming Features wesentlich. Aus diesem Grund wird ihre
Funktionsweise hier im Detail erläutert.
Der Nutzer hat drei
Möglichkeiten die Zoombar zu benutzen:
- Mausklick auf den + oder - Button am jeweiligen Ende
der Zoombar.
Damit vergrößert bzw. verkleinert sich der
Kartenausschnitt sprunghaft um jeweils eine Zoomstufe.
- Mausklick auf eine beliebige Stelle der Zoombar.
Der Slider bewegt sich zur nächstliegenden vordefinierten
Zoomstufe. Der Kartenausschnitt aktualisiert sich
sprunghaft auf die entsprechende Zoomstufe.
- Mittels
Drag&Drop den Zoomslider stufenlos über die
Zoombar bewegen.
Sobald der Nutzer die gedrückte linke
Maustaste loslässt, rastet der Slider auf der
nächstliegenden vordefinierten Zoomstufe ein. Der
Kartenausschnitt aktualisiert sich sprunghaft auf die
entsprechende Zoomstufe.
OpenLayers.Control.OverviewMap
stellt eine kleine Übersichtskarte dar
(vgl. Abb. 2.3.4). Sie zeigt den aktuellen
Kartenausschnitt der Hauptkarte und dient als Positions- und
Navigationshilfe für den Anwender. Die Übersichtskarte liegt
standardmäßig im Bereich der unteren rechten Ecke der Karte
und lässt sich durch einen Button am Kartenrand minimieren.
Die Klasse stellt u. a. Funktionen
zum Abfragen und Setzen des Markierungsrahmens bereit, der
mittels definierter Maus-Events verschoben werden kann.
OpenLayers.Control.KeyboardDefaults
definiert auf welche Tastaturbefehle wie reagiert werden soll.
OpenLayers.Control.MouseDefaults
definiert das Verhalten der Karte bei Maus-Events.
Dazu gehören Klick-, Doppelklick-, Mausrad- und
Mausbewegungs-Events.
- OpenLayers.Tile:
- Wird eine Karte in Kacheln unterteilt,
ist jede Kachel durch ein Tile-Objekt definiert. Zu
deren Erzeugung muss die zugehörige Ebene, die Pixelposition,
die geografische Kachelausdehnung, die URL und die Pixelgröße
der Kachel angegeben werden. Die Standardkachelgröße beträgt
256 Pixel. Über eine Option beim Initialisieren
der Karte lässt sich diese Größe ändern.
OpenLayers.Tile.Image
Abgeleitet von der Tile-Klasse hält das
Tile.Image-Objekt die eigentliche Kachelgrafik vor
und legt beim Zeichnen der Karte ein img-Div-HTML-Element für
jede Kachel an.
- OpenLayers.Events
-
übernimmt das Event-Handling von OpenLayers.
- OpenLayers.Pixel
-
repräsentiert ein Bildschirmkoordinatenpaar in x- und
y-Pixelwerten.
- OpenLayers.Size
-
repräsentiert ein Pixelgrößenwertepaar in Breite und Höhe.
- OpenLayers.LonLat
-
repräsentiert ein geografisches Koordinatenpaar in
geografischer Länge (longitude) und Breite
(latitude).
- OpenLayers.Bounds
-
repräsentiert einen rechteckigen Bereich
(bounding box), dessen vier Grenzen (links, unten,
rechts, oben) mit geografischen Koordinaten im
float-Format angegeben werden. Die
Bounds-Klasse stellt verschiedene get-Funktionen
(z. B. Mittelpunkt und Pixelausdehung der bounding box)
und Vergleichsfunktionen (z. B. ob sich ein Pixel innerhalb der
definierten bounding box befindet) bereit.
- OpenLayers.Util
-
beinhaltet unterschiedliche Funktionen und Einstellungen,
die keiner anderen Klasse von OpenLayers zuzuordnen sind.
OpenLayers benutzt das Test.AnotherWay33 Framework für
Komponententests (engl. unit tests). In der Version 2.4 RC5
(vom 25.5.2007) stellt OpenLayers knapp 1500 Unittests
bereit, die
sich über ein zentrales Webinterface34 steuern lassen.
Das Framework bietet die Möglichkeit, HTML- und
JavaScript-Quellcode zu testen und die Ergebnisse anzuzeigen.
Jede HTML-Testseite enthält eine oder mehrere
JavaScript-Testfunktionen, die mit
test_ beginnen und ein Testobjekt t als
Übergabeparameter definieren müssen
[Test.AnotherWay][OpenLayers g].
Listing: Eine einfache Beispieltestseite mit einer Testfunktion
<html>
<head>
<script src = "../lib/OpenLayers.js"></script>
<script type = "text/javascript">
function test_Map_Zoom(t)
t.plan(1);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer.WMS("ABC",
"http://example.com/123",
'layers':'test');
map.addLayer(layer);
map.zoomTo(0);
t.eq(map.zoom, 0, "Map zoomed to level 0 correctly.");
</script>
</head>
<body>
<div id="map" style="width: 512px; height: 512px;"/>
</body>
</html>
Listing 3.4.3 zeigt eine Beispieltestseite, wie sie
für einen einfachen Test einer OpenLayers-Funktion eingesetzt werden
kann.
In Zeile 6 definiert die Testfunktion die Anzahl der geplanten Tests
(hier: einer), von denen erwartet wird, dass sie erfolgreich
durchlaufen werden. Stimmt die Anzahl nicht mit der tatsächlichen
Anzahl von Tests überein, schlägt die ganze Testfunktion fehl.
Die Zeilen 7 bis 12 erzeugen eine Karte mit einer WMS-Ebene und
setzen die Zoomstufe auf 0.
Zeile 13 testet die Aussage,
dass sich die Karte tatsächlich in der Zoomstufe 0 befindet.
Das Test-Framework stellt fünf Testmethoden zur Verfügung, um
selbstdefinierte Aussagen (engl. assertions) zu testen:
- t.ok(boolean, "String for output")
Der Test ist erfolgreich, wenn die Aussage
boolean wahr ist.
- t.eq(value1, value2, "String for output")
Der Test ist erfolgreich, wenn value1 dem erwarteten
Wert value2 entspricht.
- t.like(string, regEx, "String for output")
Der Test ist erfolgreich, wenn string dem regulären
Ausdruck regEx
entspricht.
- t.html_eq(HTML1, HTML2, "String for
output")
Der Test ist erfolgreich, wenn HTML1 dem erwarteten
Wert HTML2 entspricht; jeder HTML-Wert kann als
DOM Element oder HTML-String angegeben werden.
- t.fail("String for output")
Für explizites Fehlschlagenlassen eines Tests; erwartet nur
Ausgabestring.
Beispiele und weiterführende Informationen zur Funktionsweise des
Frameworks sind in der Dokumentation [Test.AnotherWay] zu finden.
© 1. Juni 2007,
Emanuel Schütze,
some rights reserved.
Diese Arbeit ist unter der Creative Commons Lizenz
Namensnennung-Weitergabe unter gleichen Bedingungen 2.0 Deutschland lizensiert.