Well, after a very long time trying to find a way to generate a Google Static Map with a filled circle of a specific Km radius around a specified map point, I’ve finally done it!!!
I always knew this could be done, but I did not have the time or mathematical skills to program it from scratch, so I have been searching on and off for the last year for a function that already did it – with no luck. The trick for me was that I needed to do it totally server-side in PHP (without using the Maps API), and simply get a static map URL including the encoded polyline parameter.
If like me, you have been searching for a simple solution to what should be a simple task, you will have found that the only way to do it is by drawing a Polygon that resembles a circle. This involves plotting a number of points in a circle around your given centre point, and then encoding the coordinates so they can be passed to the google static maps request.
Although I could find many examples, nothing provided a complete solution for my needs, so I thought I would share the method I ended up using in case others were running into the same issues as me. Be warned, this is not production code, it is largely untested as is very likely to contain bugs and inaccuracies. But, on face value it appears to work – use it at your own risk. I am sure it can be improved in many ways, please feel free to add comments at the end of the post (all comments are moderated).
You should save the above library somewhere appropriate on your web server (without the “.txt” extension), we need it later.
Generating The Points of The Circle
$R = 6371;
$pi = pi();
$Lat = ($Lat * $pi) / 180;
$Lng = ($Lng * $pi) / 180;
$d = $Rad / $R;
$points = array();
$i = 0;
for($i = 0; $i <= 360; $i+=$Detail):
$brng = $i * $pi / 180;
$pLat = asin(sin($Lat)*cos($d) + cos($Lat)*sin($d)*cos($brng));
$pLng = (($Lng + atan2(sin($brng)*sin($d)*cos($Lat), cos($d)-sin($Lat)*sin($pLat))) * 180) / $pi;
$pLat = ($pLat * 180) /$pi;
$points = array($pLat,$pLng);
$PolyEnc = new PolylineEncoder($points);
$EncString = $PolyEnc->dpEncode();
I think the above code is pretty self explanatory. As you can see, the function takes four parameters, the last one is optional.
- The latitude of the centre of the circle
- The longitude of the centre of the circle
- The radius of the circle (in kilometres)
- The detail of the circle (after all, it is just a bunch of straight lines). A setting of “1″ will create a maximum of 360 points, “2″ will create 180, “3″ will create 90 etc. The key here is to make sure you don’t end up with so many lines that the encoded string is too long to be parsed – have a play with it and see for yourself.
Putting it All Together
Now it is simply a matter of creating a static map URL and including the encoded polyline path.
/* set some options */
$MapLat = '-42.88188'; // latitude for map and circle center
$MapLng = '147.32427'; // longitude as above
$MapRadius = 100; // the radius of our circle (in Kilometres)
$MapFill = 'E85F0E'; // fill colour of our circle
$MapBorder = '91A93A'; // border colour of our circle
$MapWidth = 640; // map image width (max 640px)
$MapHeight = 480; // map image height (max 640px)
/* create our encoded polyline string */
$EncString = GMapCircle($MapLat,$MapLng, $MapRadius);
/* put together the static map URL */
$MapAPI = 'http://maps.google.com.au/maps/api/staticmap?';
$MapURL = $MapAPI.'center='.$MapLat.','.$MapLng.'&size='.$MapWidth.'x'.$MapHeight.'&maptype=roadmap&path=fillcolor:0x'.$MapFill.'33%7Ccolor:0x'.$MapBorder.'00%7Cenc:'.$EncString.'&sensor=false';
/* output an image tag with our map as the source */
echo '<img src="'.$MapURL.'" />'
And there you have it, a static map with a circle around a point.
You can see a complete working example of my solution here.
I have also packaged the working example up and you can download a zip file below.
You are free to use and modify this code however you like, but please be good enough to drop me a comment if you found it helpful.