Auf Drupalseiten tritt oft die Anforderung auf, bestimmte Inhalte mit Adressen zu versehen und diese dann auch auf einer Karte (z.B. Google Map) darzustellen. Hierzu gibt es mehrere Module die versuchen diese Einbindung zu bewerkstelligen. In den meisten Anwendungen reicht es hier allerdings nicht, nur auf ein einzelnes Modul zu setzen, da gerade durch die Kombination mächtigere Tools entstehen. Ich bin hierbei stets Freund eines möglichst generischen Ansatzes. So kommen für die folgende Umsetzung die Module Openlayers und Geo zum Einsatz, die diesen generischen Charakter tragen, und somit flexibel erweiter- und anpassbar sind.
Die Anforderung für die Umsetzung ist eigentlich eine relativ einfache, allerdings beißen sich viele Ansätze daran schon die Zähne aus: ein User soll einen Node erstellen können, in dem er ein einfaches Textfeld mit seiner Adresse befüllt. Im Kontext der Nodeansicht soll dann diese Adresse auf einer Karte dargestellt werden.
Eingabe der Adresse
Die Eingabe der Adresse über ein Textfeld ist hierbei der kleinste Aufwand. Dazu wird einfach ein CCK Textfeld angelegt (z.B. field_adresse). Der User kann somit eine beliebige Adresse eingeben.
Allerdings haben wir hier bislang nur eine einfache Textinformation, die nicht einmal eine valide Adresse sein muss. Zudem enthält sie noch keine Geo-Daten, die man zur Darstellung auf einer Karte benötigt. Also weiter zu Schritt 2.
Geocoding
Mit dem Modul Geocode wird es nun möglich die Informationen des Textfeldes per Geocoding in Geo-Daten umzuwandeln und diese dann als Geo-Koordination zu speichern.
Hierzu wird das oben erwähnte Geo benötigt mit dem beinhalteten Modul Geo Field. Vom Geocode-Project müssen die Module Geocode und Geocoded Value aktiviert werden.
Hiernach steht einem der CCK Field-Typ Geospatial Data mit dem Widget Gecoded value from another field zur Verfügung. Ein solches Feld legen wir nun an (field_adressgeo). In den Einstellungen kann das vorher definierte Textfeld ausgewählt werden, das mit dem Geocode Handler 'geocode_google' und dem Return Value 'point' versehen ist.
Nun wird beim Speichern des Nodes die Adresse des Textfeldes in Geodaten umgerechnet und im Geo Field gespeichert. Durch das Geocoding wird die Adresse automatisch validiert. Sollte ein ungültige Adresse -eine für die der Google-Geocoder keine Geokoordinaten finden kann- eingegeben worden sein, wird das Feld entsprechend negativ validiert.
Jetzt sind für unseren Node also Geodaten vorhanden. Wir können uns somit an die Darstellung in einer Karte wagen.
Darstellung auf einer Karte
Für die Darstellung der Geodaten auf einer Karte kann man zum einen das bekannte GMap Modul benutzen. Wenn man jedoch nicht auf die GMaps setzen will, sondern auf andere Dienste wie Bing oder OpenStreeMap kommt man hierbei nicht weiter. Hier empfiehlt sich vor allem Openlayers. Durch den generischen Ansatz lassen sich nicht nur verschiedene Mapservices einbinden, sondern diese auch beliebig zusammenstellen und stylen.
In beiden Fällen muss man zur Zeit noch einen Umweg gehen um die GeoDaten des Geo Fields in einer Karte darzustellen, da bislang noch kein Formatter für das GeoField hierzu besteht. Dieser Umweg führt über Views, denn Openlayers bietet mit dem beinhalteten Modul Openlayers Views natürlich eine Integration hierzu.
Das Konzept um Geodaten auf eine Openlayers-Karte zu bringen ist nicht trivial, jedoch, nachdem man sich mit der Grundstruktur von Openlayers auseinandergestzt hat, logisch:
- Auslesen der Daten mit Views in ein "Openlayers Data" Layer
- Einbinden des Data Layers in ein "Openlayers Preset"
- Darstellung des Preset in einer "Openlayers Map" mit Views in einem Block
Die Karte wollen wir kontextbezogen in einen Block auf der Nodeseite darstellen.
- Hierzu legen wir erst einmal einen View vom Typ Node an.
- Mit dem Argument "Node: Beitrags-ID" beschränken wir die Nodes auf einen, den aktuellen Node (Standargument: Beitrags-ID aus der URL).
- Unter den Feldern wählen wir mindestens das GeoField (field_adressgeo) aus, mit der Darstellungsart "Well-Known-Text". Mit weiteren Feldern wie Node:Titel oder Node:Body können später eventuelle Tooltips auf der Karte gefüllt werden.
- Hiernach wählen erstellen wir einen neu Anzeige vom Typ Openlayers Data - über das Dropdown links und den Button "Anzeige hinzufügen".
- Wir übersteuern den Anzeige-Einstellung Design - das ist wichtig um Daten und später die Map in einem View abhandeln zu können. In der Anzeige "Standards" (engl. Default) bleibt das bisherige Design (meist "unformatiert") bestehen.
- Als übersteuerndes Design wählen wir in 'Openlayers Data' nun Openlayers Data. In den weiteren Einstellungen ist unter 'Map Data Sources' Openlayers WKT auszuwählen. Das daraufhin erscheinende WKT-Field ist dann mit field_adressgeo zu besetzen. Optional können hier dann auch noch Felder für Titel und Body der Tooltips ausgewählt werden.
- Speichern.
Mit Speichern des Views steht uns nun ein Openlayers Data Layer zur Verfügung. Bei aktiviertem Modul Openlayers UI können wir nun unter admin/build/openlayers/presets, das benötigte Openlayers Preset anlegen, die Vorlage für eine Kartendarstellung. In dieser werden alle Informationen zu einer Karte, von Höhe, Breite, Kartentypen, Steuerungsmöglichkeiten bis hin zu den zu verwendeten Daten definiert. Dies alles nun einzeln anzupassen würde den Rahmen sprengen. Deshalb duplizieren wir dort einfach die "Default Map". Neben der Eingabe des neuen Namens gibt es hier nun zwei wichtige Schritte die zur Funktion notwendig sind.
- Unter "Layers & Styles" wählen wir bei den 'Overlay layers' die OpenLayers Data unseres zuvor definierten Views aus. Die Spalten 'enabled' und 'activated' sollten beide ausgewählt werden. Danach speichern wir das neue Preset erst einmal um Einstellung 2 durchführen zu können.
- Wir editieren das neue Preset, und können dort nun unter 'Behaviors'->'Zoom to Layer' den Data-Layer als Grundlage für das automatische Zoomen der Karte wählen. Da es sich bei unseren Daten nur um Punkte handelt, sollte man den Wert 'Point Zoom Level' auch auf einen gewünschten Standardwert setzen.
In diesem Preset können noch weiter Optionen gesetzt oder entfernt werden - z.B. anpassen von Höhe und Breite oder anzeigen bestimmter Navigationselemente.
Nun wollen wir aber nun endlich die Karte zu unserem Node anzeigen. Dazu gehen wir nochmal zum View zurück und bearbeiten diesen:
- Wir fügen eine neue Anzeige vom Typ "Block" hinzu.
- Als Design wählen wir "Openlayers Map" aus. Eine Übersteuerung ist in diesem Fall nicht notwendig, da der View bislang neben dem bereits übersteuertem Openlayers Data, keine anderen funktionellen Anzeigen hat.
- In den Map Settings wählen wir nun das eben erstellte Preset aus.
- Speichern.
Den neu erstellen Views Block können wir nun über die Block-Adminstration in eine Region packen. So zeigt dieser, durch das im View eingebundene Argument, kontextbezogen die Adresse auf der Karte an.
Ausblick
Gerade Openlayers ist ein ziemlich vielschichtiges Modul, in einem kurzen Blogpost kann man hier bei weitem nicht die Vorzüge und Möglichkeiten des Moduls präsentieren. Ich empfehle daher jedem, der sich Geodaten in der Darstellung widmet, sich das Modul anzusehen. In naher Zukunft werde ich dazu sicher nochmal etwas weiter, aber auch konkreter, ausholen und euch mit der Umsetzung zu einem eigenen Projekt ein Beispiel zeigen können. Falls euch das Thema interessiert, werdet ihr dazu bald etwas im undpaul Blog zu lesen und zu sehen haben.
Verwendete Module mit ihren Versionen:
openlayers - 6.x-2.0-alpha8 (Openlayers, OpenLayers UI, Openlayers Views)
geo - 6.x-1.0-alpha5 (Geo, Geo Field)
geocode - 6.x-1.0-alpha2 (Geocode, Geocoded Value)
cck - 6.x-2.7 (content, text)
und natürlich die entsprechenden dependencies.
















