Automatisches Erzeugen und Speichern von Koordinaten
Einleitung
Diese Anleitung beschreibt, wie in einer MetaModels-Installation automatisch Koordinaten aus Adressdaten erzeugt und gespeichert werden können.
Voraussetzungen
Contao 5.3 mit MetaModels 2.4, ebenfalls erfolgreich mit Contao 4.13 und MetaModels 2.3 getestet
Google Maps API-Key für Koordinaten-Erstellung →
API_KEY_SERVER(Anwendung: IP-Adressen; API: Geocoding API)Felder im MetaModel:
strasse,plz,ort,latitude,longitudeDie Felder
latitudeundlongitudesind vom Typ „Dezimal“ (metamodels/attribute_decimal)
Schritt 1: Anlegen des EventListeners
Zum automatischen ermitteln und Speichern der Koordinaten aus den Adressdaten wird ein Listener für den PrePersistModelEvent erstellt. Der Event wird ausgeführt, bevor das Model in die Datenbank geschrieben wird.
Man erstellt dazu eine Datei src/EventListener/PrePersistModelEventListener.php mit folgendem Inhalt.
Achtung: API_KEY_SERVER muss durch den entsprechenden API-Schlüssel ersetzt werden.
<?php
// src/EventListener/PrePersistModelEventListener.php
namespace App\EventListener;
use ContaoCommunityAlliance\DcGeneral\Event\PrePersistModelEvent;
use App\Service\GoogleMaps;
class PrePersistModelEventListener
{
public function __invoke(PrePersistModelEvent $event) {
$model = $event->getModel();
if (!$model->getProperty('latitude') || !$model->getProperty('longitude')) {
$strasse = $model->getProperty('strasse');
$plz = $model->getProperty('plz');
$ort = $model->getProperty('ort');
$address = $strasse . ', ' . $plz . ' ' . $ort;
$googleMaps = new GoogleMaps();
$apiToken = ‚API_KEY_SERVER‘;
$coordinates = $googleMaps->getCoordinates($address, $apiToken);
if (null !== $coordinates) {
$model->setProperty('latitude', $coordinates->getLatitude());
$model->setProperty('longitude', $coordinates->getLongitude());
}
}
}
}
Schritt 2: Anlegen der GoogleMaps-Klasse
Erstellen der Datei src/Service/GoogleMaps.php mit folgendem Inhalt:
<?php
// src/Service/GoogleMaps.php
namespace App\Service;
use App\Service\Coordinates;
class GoogleMaps
{
public function getCoordinates($address, $apiKey) {
$url = \sprintf('https://maps.googleapis.com/maps/api/geocode/json?address=%s&key=%s', urlencode($address), $apiKey);
$response = file_get_contents($url);
$data = json_decode($response);
if ($data->status === 'OK') {
$loc = $data->results[0]->geometry->location;
return new Coordinates($loc->lat, $loc->lng);
}
return null;
}
}
Schritt 3: Anlegen der Coordinates-Klasse
Erstellen der Datei src/Service/Coordinates.php mit folgendem Inhalt:
<?php
// src/Service/Coordinates.php
namespace App\Service;
class Coordinates
{
private $lat;
private $lng;
public function __construct($lat, $lng) {
$this->lat = $lat;
$this->lng = $lng;
}
public function getLatitude() {
return $this->lat;
}
public function getLongitude() {
return $this->lng;
}
}
Schritt 4: Registrieren des EventListeners
Erstellen oder bearbeiten der Datei src/Resources/config/service.yml:
# src/Resources/config/service.yml
services:
App\EventListener\PrePersistModelEventListener:
public: true
tags:
- { name: kernel.event_listener, event: dc-general.model.pre-persist }
Sicherstellen, dass diese Datei in die Hauptkonfiguration eingebunden ist, z. B. in config/services.yaml:
# config/services.yaml
imports:
- { resource: '../src/Resources/config/service.yml' }
Testen
Einen bestehenden Datensatz im Back-End bearbeiten, die Felder strasse, plz und ort ausfüllen und
die Felder latitude und longitude leer lassen. Beim Speichern erfolgt die automatische Generierung der
Koordinaten.
Hinweise
Der
PrePersistModelEventwird nur bei geänderten Datensätzen ausgelöst.Wie die gespeicherten Koordinaten auf einer Karte als Marker angezeigt werden können, ist unter „Standorte als Marker auf einer Google-Map ausgeben“ beschrieben.
Sofern der Filter Umkreissuche (metamodels/filter_perimetersearch) implementiert ist, kann zur Ermittlung der Koordinaten auch eines der implementierten Services verwendet werden.
Der EventListener kann auch über PHP-Annotation bzw. -Attribute eingebunden werden - siehe Registrierung von Services
Dank
Dank an Nicole Weiß - Webstylisten.de für den Artikel.