Dynamic Google Maps markers/icons with PHP

I am a avid fan of Google’s Map API, have even have created my own WordPress Google Maps plug-in (thydzikGoogleMap), but one feature that I find lacking are customisable markers, with the need to include an image file for every customisable marker, now if you want a selection of colours and labels this creates a huge image database.

Google has gone in the right step their MapIconMaker allowing very customisable markers using the Charts API marker output. But why not take this a step further and add dynamically generated text as well.

Hence, I provide a little demo of some PHP code that does this that I quickly whipped up. Here are some example markers:
DefaultAZ110PQ69%BEΩ$
(Have a look at the image name)

Now that gets a little boring, how about some color:
DefaultAZ110PQ69%BEΩ$
(Again, have a look at the image name)

Unfortunately, not all symbols work (not sure why, even though they are in the font) and if the symbol doesn’t work it will default to the default bullet (this is done with a modified font file).

Also there may be an issue with alignment. All main characters 0-9 and A-Z; I have added manual offsets, this could be improved.

You will need to download the modified arial font and host it in the same directory.

Update: it looks like in Internet Explorer the transparencies are incorrectly displayed, this is not the case when displayed on a Google Map.

Have a look at the PHP source code below:

<?php
	 $color = $_GET['color'];
	 if (!$color) {$color = "ff776b";} //default google map color
	 $color = str_replace("#", "", $color);
	 $string = $_GET['text'];

	 //some smarts to prevent hotlinking
	 if (!stristr($_SERVER['HTTP_REFERER'], "thydzik.com")) {
		$string = chr(169);
	 }
	 $font = 'arial';

	 //unfortunately we still must do some offsetting
	 switch (ord(substr($string,0,1))) {
		 case 49: //1
			$offset = -2;
			break;
		 case 55: //7
			$offset = -1;
			break;
		 case 65: //A
			$offset = 1;
			break;
		 case 74: //J
			$offset = -1;
			break;
		 case 84: //T
			$offset = 1;
			break;
		 case 99: //c
			$offset = -1;
			break;
		 case 106: //j
			$offset = 1;
			break;
	 }
	 if (strlen($string) == 1) {
		$fontsize = 10.5;
	 } else if (strlen($string) == 2) {
		$fontsize = 9;
	 } else {
		$fontsize = 10.5;
		$offset = 0; //reset offset
		$string = chr(149);
	 }

	 $bbox = imagettfbbox($fontsize, 0, $font, $string);
	 $width = $bbox[2] - $bbox[0] + 1;
	 $height = $bbox[1] - $bbox[7] + 1;

	 $image_name = "http://chart.apis.google.com/chart?cht=mm&chs=20x34&chco=$color,$color,000000&ext=.png";
	 $im = imagecreatefrompng($image_name);
	 imageAlphaBlending($im, true);
	 imageSaveAlpha($im, true);
	 $black = imagecolorallocate($im, 0, 0, 0);

	 imagettftext($im, $fontsize, 0, 11 - $width/2 + $offset, 9 + $height/2, $black, $font, $string);

	 header("Content-type: image/png");
	 imagepng($im);
	 imagedestroy($im);
?>

EDIT: 27th January 2010

I have experienced some users with errors produced by the imagecreatefrompng, either due to versions <4.3.0 disabling remote file access or allow_url_fopen being disabled.

A greater supported alternative is to use curl to fetch the Google marker. Replace the above with the below modification;

	$image_name = "http://chart.apis.google.com/chart?cht=mm&chs=20x34&chco=$color,$color,000000&ext=.png";

	$ch = curl_init();
	curl_setopt ($ch, CURLOPT_URL, $image_name);
	curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);

	// Getting binary data
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);

	$image_string = curl_exec($ch);
	curl_close($ch);

	$im = imagecreatefromstring ($image_string);

EDIT: 30th November 2011

Hosting of these dynamic markers, linked on NumericIcons is using all my allocated hosting server resources. I have modified the script to redirect to Google’s dynamic markers (yes, Google has the equivalent) hopefully that will take some of the load off, and I won’t need to remove it totally.

They look slightly different to mine;
DefaultAZ110PQ69%BEO$

DefaultAZ110PQ69%BEO$

	if (!$color = $_GET['color']) {
		$color = "ff776b"; //default google map color
	}
	$color = str_replace("#", "", $color);

	if (!$text = $_GET['text']) {
		$text = "%e2%bc%80"; //default google map icon
	}

	header("Location: http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld={$text}|{$color}|000000&.png");

EDIT: 6 December 2011
I now have implemented an Apache Mod_Rewrite solution, which will take all load off the php processing, existing users should see no difference.

RewriteCond %{QUERY_STRING} ^text=([^&]*)$
RewriteRule ^thydzikGoogleMap/markerlink\.php$ http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=%1|ff776b|000000&.png? [R,L]

RewriteCond %{QUERY_STRING} ^color=([^&]*)$
RewriteRule ^thydzikGoogleMap/markerlink\.php$ http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=â¼€|%1|000000&.png? [R,L]

RewriteCond %{QUERY_STRING} ^text=(.*)\&color=(.*)$
RewriteRule ^thydzikGoogleMap/markerlink\.php$ http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=%1|%2|000000&.png? [R,L]

RewriteCond %{QUERY_STRING} ^color=(.*)\&text=(.*)$
RewriteRule ^thydzikGoogleMap/markerlink\.php$ http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=%2|%1|000000&.png? [R,L]

RewriteCond %{QUERY_STRING} =""
RewriteRule ^thydzikGoogleMap/markerlink\.php$ http://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=â¼€|ff776b|000000&.png? [R,L]

Related posts:

  1. thydzikGoogleMap – an inline Google map plugin for WordPress
  2. thydzik Google Map version 1.4.6.1

Tags: , , , , , ,

  • http://austintreeexperts.com keith

    The blue marker is google maps default; not coming from marker.php.

    You are right. I wrote the marker.php file as described above to get the & symbol out of the in my kml and still not working.
    http://digitalarborist.com/new_markers.php?icon=97EC7D6

    I tried adding &.png to the end of url call and it short-circuits the feed (nothing displays). The & symbol cannot appear anywhere in the feed or google maps won’t display the kml.

    I added an image to the description box to confirm that I got some sort of image to load, and it worked:
    http://digitalarborist.com/maps/?f=http%3A%2F%2Fwww.austintreeexperts.com%2Fkml-rss.cfm%3Fu%3D684%26ad%3D29927

    But, still no luck on the dynamic icon.

  • http://thydzik.com thydzik

    keith,

    first try it with static markers. I have seen the 1green.png marker in the kml, but not working on the google map.

  • http://austintreeexperts.com keith

    Got it! It was formatting problems with my kml. I was trying to embed IconSyle tag inside placemark tag instead of inside Style tag.

    It was an issue having & symbol in kml file as kml is xml and must be encoded. I changed my php marker script to accept one variable where first six characters in string are $color and any remaining characters are $string:

    $color = substr($_GET['icon'],0,6);
    $string = substr($_GET['icon'],6);

    Working good now!:
    http://digitalarborist.com/maps/?f=http%3A%2F%2Fwww.austintreeexperts.com%2Fkml-rss.cfm%3Fu%3D684%26ad%3D29927

  • http://austintreeexperts.com keith

    One other thing about kml files in google maps. The smarts to prevent hotlinking in the marker.php file does not work for kml. Google maps actually retrieves your icon images from Google’s servers and sends them to the map with the map tiles as one big overlay (they are not conventional map markers).

  • http://www.amctinstitute.com AMCT

    I want to display all parameters between two location with distance and driving hours. if it possible

  • Karry

    Hi i tried to execute the above code but i was unable to do it. how to run the above code on a local server in my college campus because we are not allowed to access http://thydzik.com. Any help is appreciated..

  • http://thydzik.com thydzik

    Karry,

    You need to copy the code to a php file and install it on your web server. You will also need to include the modified Aerial font to the same directory.

  • Karry

    Hi i copied the font file, made a php file of the code above and put them in www directory but when i executed the local web page the page was appearing blank, i am using Wampp server, Evey i passed the address bar parameters test.php?text=8&color=#551A8B to it but it didnt work, when i didnt pass tha parameters then this is the error “Notice: Undefined index: color in C:\wamp\www\t2.php on line 1″ please help me..

  • Karry

    This was the new error The image “http://localhost:8080/t2.php?text=8&color=#FF34B3” cannot be displayed, because it contains errors. Please help me..

  • http://thydzik.com thydzik

    Karry,

    I need further information on the produced errors.

    remove this line “header(“Content-type: image/png”);” and tell me what errors are produced.

  • Karry

    Hi this was the error when i removed header(“Content-type: image/png”);” and executed the code.
    ( ! ) Notice: Undefined index: color in C:\wamp\www\t2.php on line 2
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0

    ( ! ) Notice: Undefined index: text in C:\wamp\www\t2.php on line 5
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0

    ( ! ) Notice: Undefined index: HTTP_REFERER in C:\wamp\www\t2.php on line 8
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0

    ( ! ) Warning: imagettfbbox() [function.imagettfbbox]: Invalid font filename in C:\wamp\www\t2.php on line 47
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0
    2 0.0708 696440 imagettfbbox ( ) ..\t2.php:47

    ( ! ) Notice: Undefined variable: offset in C:\wamp\www\t2.php on line 57
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0

    ( ! ) Warning: imagettftext() [function.imagettftext]: Invalid font filename in C:\wamp\www\t2.php on line 57
    Call Stack
    # Time Memory Function Location
    1 0.0010 695512 {main}( ) ..\t2.php:0
    2 0.3633 712624 imagettftext ( ) ..\t2.php:57

  • http://thydzik.com thydzik

    Karry, I am really not sure what is going on.

    what version of PHP do you use?

  • Pingback: In search of the elusive Google default marker | Blog of Travis Hydzik