Dynamisch generierte Google Maps Marker

Lukas [php, Tricks und Tools, Pimcore]

Für eine Google-Karte benötigen wir Marker, der eine Zahl beinhaltet. Diese Zahl kann man im CMS ändern. Als Marker kann man allerdings nur ein Bild einsetzen. Anstatt für jeden möglichen Wert das Marker-Bild im Voraus zu generieren, erzeugen wir dieses dynamisch.

Damit nun das Bild nicht jedes mal berechnet werden muss, legen wir das erzeugte Bild ab. Dies machen wir so, dass das Bild direkt aufgerufen wird, sofern es denn schon vorhanden ist. Wenn es noch nicht existiert, wird es automatisch generiert und gespeichert.

In pimcore gibt es statische Routen. Diese kommen zum Einsatz, wenn die aufgerufene URL nicht existiert. Damit fangen wir Aufrufe auf Marker-Bilder ab, die noch nicht generiert wurden.

Die URL zum Marker-Icon wird wie folgt gemäss der Google Maps APIv3 verwendet:

var image = {
  url: "/website/var/tmp/marker/" + num + ".png",
  size: new google.maps.Size(40, 53),
  origin: new google.maps.Point(0, 0),
  anchor: new google.maps.Point(20, 53)
};
 
var marker = new google.maps.Marker({
  position: myLatlng,
  map: map,
  icon: image
});

Wenn denn ein Bild aufgerufen wird, dass es noch nicht gibt, kommt der Request dank der Route in der marker Action an. Dort erzeugen wir das Bild und leiten den Aufruf darauf weiter:

public function markerAction() {
    $number = $this->getParam("number");
    $markerdir = PIMCORE_DOCUMENT_ROOT."/website/var/tmp/marker";
    if (!is_dir($markerdir)) {
        mkdir($markerdir);
    }

    $filename = $markerdir."/".$number.".png";
    $source = PIMCORE_DOCUMENT_ROOT."/website/static/img/marker.png";

    $image = imagecreatefrompng($source);
    imageAlphaBlending($image, true);
    imageSaveAlpha($image, true);

    if (strlen($number) == 3) {
        $fontsize = 8;
        $x = 10;
        $y = 26;
    } elseif (strlen($number) == 2) {
        $fontsize = 12;
        $x = 10;
        $y = 26;
    } else {
        $fontsize = 12;
        $x = 14;
        $y = 26;
    }

    imagettftext($image, $fontsize, 0, $x, $y, 0, "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf", $number);
    imagepng($image, $filename);
    imagedestroy($image);

    $this->redirect("/website/var/tmp/marker/".$number.".png");
}

Damit erhöhen wir die Ladezeit der Seite, wenn denn die Bilder schon existieren. Das Ergebnis sieht dann so aus:

zurück