Generating Dynamic Icons for Google Maps with PHP

Google Maps provides a standard Marker marker image that looks like this and whilst I do not intend to offend Ji Lee, this icon can be replaced with an image of your choice. By using PHP to create an image dynamically on the fly you can have images that provide much more information.

I have written a web app that shows the locations of all the fire appliances in the county. By using a dynamic icon I can show the name of the appliance and colour the icon to represent the current status.

The complete code for generating the icon is shown at the bottom of this post. Lets go through it chunk by chunk.

To display a dynamic icon in our browser we want to be able to use http://www.mywebsite.com/icon.php?text=NORW&status=1

First of all we read the parameters passed in through the url to set the text to be displayed and the colours to be used.

if (isset($_GET['text'])) $text = $_GET['text']; else $text = 'NoText';
if (isset($_GET['status'])) $status = $_GET['status']; else $status = 0;

Next we create a unique filename to store a cached copy of the image we are requesting. Here I am using an MD5 hash of the text and status concatenated together.

$hash = 'img/'.md5($text.$status).'.png';

Then we check if the file exists and if it doesn’t we start by creating an image the required size for the icon, in this case 40 pixels wide and 16 pixels high. In my particular application all vehicles have a name the same length, but you could dynamically create an image based on the length of the text.

if (!file_exists($hash)) {
$icon = imagecreate(40,16);

I then look at the status passed in the url and select the desired colors to be used for the background and foreground.

switch ($status) {
case 1:
$background = imagecolorallocate($icon, 0, 128, 0);
$textcolour = imagecolorallocate($icon, 255,255,255);
break;

I would like the text to be centered within the icon, so I find the rough length and subtract half the length from the width of the icon to find my x offset for the text.

$text_width = 6*strlen($text);
$x = 20-(ceil($text_width/2))+1;

We now have all the information we need, so render a border around the icon in the same colour as the text, then add the text at the x offset also in the same colour and then output the image as a PNG file to the filename we calculated earlier.

imagerectangle( $icon, 0, 0, 39, 15, $textcolour);
imagestring( $icon, 2, $x, 1, $text, $textcolour );
imagepng($icon, $hash);

Don’t forget to clean-up after ourselves 🙂

imagecolordeallocate($icon, $background);
imagecolordeallocate($icon, $textcolour);
imagedestroy($icon);

If the image already existed in the cache folder we would have skipped all the icon generation, otherwise we have generated the image, so either way the cache folder now contains our dynamically generated image. We output a header to tell the browser what sort of data we are sending, in this case a PNG image, then output the contents of the image file.

header("Content-type: image/png");
echo file_get_contents($hash);

And that’s all there is to it!

When the cache is used it is ten times quicker than generating the image, so well worth the extra few lines.

Complete Code

if (isset($_GET['text'])) $text = $_GET['text']; else $text = 'NoText';
if (isset($_GET['status'])) $status = $_GET['status']; else $status = 0;

$hash = 'img/'.md5($text.$status).'.png';

if (!file_exists($hash)) {
$icon = imagecreate(40,16);

switch ($status) {
case 1:
$background = imagecolorallocate($icon, 0, 128, 0);
$textcolour = imagecolorallocate($icon, 255,255,255);
break;
case 2:
$background = imagecolorallocate($icon, 0, 0, 0);
$textcolour = imagecolorallocate($icon, 255,255,255);
break;
case 3:
$background = imagecolorallocate($icon, 255,255,255);
$textcolour = imagecolorallocate($icon, 255,0,255);
break;
case 4:
$background = imagecolorallocate($icon, 176, 172, 0);
$textcolour = imagecolorallocate($icon, 255,255,255);
break;
default:
$background = imagecolorallocate($icon, 255,255,255);
$textcolour = imagecolorallocate($icon, 0, 0,0);
break;
}
$text_width = 6*strlen($text);
$x = 20-(ceil($text_width/2))+1;

imagerectangle( $icon, 0, 0, 39, 15, $textcolour);
imagestring( $icon, 2, $x, 1, $text, $textcolour );

imagepng($icon, $hash);

imagecolordeallocate($icon, $background);
imagecolordeallocate($icon, $textcolour);
imagedestroy($icon);
}

header("Content-type: image/png");
echo file_get_contents($hash);

References

Google Map Custom Marker Maker – Generate a single marker with a shadow online

Creator of the Google Map Marker

PHP MD5 Reference