Contao & MetaModels & dlh_googlemaps: Einer Google Maps-Karte dynamisch einen Marker zuweisen
Für dieses Vorhaben gibt es bereits eine hervorragende Artikelserie von René Aye auf http://pyropixel.de/articles.html. Dort beschreibt er in mittlerweile neun Artikeln die Verwendung von MetaModels. Allerdings geht sein Tutorial davon aus, dass die Datensätze im Backend angelegt und gespeichert werden.
Wie das Ganze funktionieren kann, wenn ein Formular zum Befüllen des MetaModels eingesetzt wird, möchte ich hier aufzeigen. Die Anforderungen für die Ausgabe sind recht überschaubar. Auf der Detailseite des Datensatzes werden neben den einzelnen Feldern, zu denen auch die Adresse gehört, noch eine Karte mit einem Marker der Adresse angezeigt.
Vorarbeiten
Wie in Renés Artikel "Creating Dynamic Google Map Markers" bereits ausführlich beschrieben, so installiert man sich die Erweiterung dlh_googlemaps und legt sich anschließend eine Karte an. In den Karteneinstellungen legt man die grundlegenden Werte wie Breite, Höhe, Zoom-Level usw. fest. In das Feld Geo-Koordinaten kommt ein beliebiger - aber gültiger - Wert. Dieser wird später durch die dynamisch ermittelten Daten ersetzt.
Als Zweites sollte das MetaModel bereits fertig angelegt und konfiguriert sein. Das bedeutet, ein Template für die Detailausgabe des Datensatzes, welches von metamodels_prerendered.html5 respektive .xhtml stammt, ist vorhanden. Dieses wird für den Marker noch benötigt.
Die Einbindung und Ausgabe des MetaModels samt der Karte erfolgt über eine beliebige Seite.
Geokoordinaten ermitteln
Mit der Erweiterung dlh_googlemaps
kommt eine weitere Erweiterung von Christian de la Haye namens dlh_geocode
in die Contao-Installation, welche aber auch einzeln verfügbar ist. Dank dem Artikel "Automatic Address to Geocoordinate Conversion" aus Renés Sammlung ist es ein leichtes, eine Adresse in Geokoordinaten umzuwandeln.
Kern der Umwandlung ist die Methode GeoCode::getCoordinates()
aus dlh_geocode
. Jetzt kommt es darauf an, wie die Adressdaten erfasst werden. Am einfachsten ist es, wenn die gesamte Adresse aus einem Feld kommt. Dann könnte der Code zur Erzeugung der Geokoordinaten so aussehen:
function GetGeoCode($address) {
$strAddress = preg_replace("/\r|\n/", ", ", $address);
return \delahaye\GeoCode::getCoordinates($strAddress);
}
Der reguläre Ausdruck in Verbindung mit preg_replace dient hier dazu, Zeilen- und Umbrüche herauszufiltern.
Wenn die aus der Adresse bestehenden Felder einzeln vorliegen, dann müssen sie noch zusammengefügt und mit einem Leerzeichen verknüpft werden:
function GetGeoCode($street, $zip, $city) {
return \delahaye\GeoCode::getCoordinates($street . " " . $zip . " " . $city);
}
Die Funktion gibt ein Koordinatenpaar für den Breiten- und den Längengrad zurück, welches anschließend für die Erzeugung des Markers benötigt wird. Der Code kommt einfach in das für die Ausgabe angepasste Template.
Einen Marker erstellen
In das gleiche Template kommt schließlich noch das JavaScript zur Erzeugung eines Markers. Eine geeignete Position im Template ist innerhalb der Abfrage:
<?php if (count($this->data)): ?>
// JS-Code für den Marker
<?php else: ?>
<p class="info"><?php echo $this->noItemsMsg; ?></p>
<?php endif; ?>
Die Karte und alle Marker werden per JavaScript erzeugt. Dafür stellt Google eine umfangreiche API zur Verfügung. Um nun den Marker zu erzeugen, braucht es folgende Zeilen:
<script>
function gmap1_dynmap(gmap1) {
// Marker
new google.maps.Marker({
position: new google.maps.LatLng(<?php echo GetGeoCode($arrItem['raw']['address']); ?>),
map: gmap1
});
}
</script>
Die hier verwendete Zahl 1 ist die ID der angelegten Karte. Am schnellsten herausfinden lässt sich die ID, indem man im Contao-Backend zu Google Maps geht und dort mit der Mouse über das Bearbeiten-Symbol der Karte fährt.
Im obigen Beispiel wird lediglich ein Adressenfeld (Zeile 5) übergeben. Wenn sich die Adresse aus mehreren Feldern zusammensetzt, so muss der Code entsprechend angepasst werden.
Die Karte manipulieren
Wie oben bereits erwähnt, ist es ebenfalls möglich, die Karte dynamisch anzupassen. Im folgenden Beispiel wird der Kartenausschnitt und das Zoom-Level angepasst:
gmap1.center = new google.maps.LatLng(<?php echo GetGeoCode($arrItem['raw']['address']); ?>);
gmap1.zoom = 14;
Zusammenfassung
Der JavaScript-Code für das Erstellen eines Markers und das Anpassen der Karte sieht letztendlich so aus:
<script>
function gmap1_dynmap(gmap1) {
// Karte
gmap1.center = new google.maps.LatLng(<?php echo getGeoCode($arrItem['raw']['address']); ?>);
gmap1.zoom = 14;
// Marker
new google.maps.Marker({
position: new google.maps.LatLng(<?php echo getGeoCode($arrItem['raw']['address']); ?>),
map: gmap1
});
}
</script>
Kartenmittelpunkt und Marker entsprechen den gleichen Koordinaten. Über die Methode new google.maps.Marker()
lassen sich noch weitere Marker hinzufügen. Man ist mitnichten auf Einen begrenzt.