Jun 05 2010
Google map v3 Cakephp Helper
Recetly I found out a nice google maps helper for Cakephp, but it is based on version 2. There is a new versione of the API, v3, which has many improvements, including faster loading time, better compatibility with mobile devices and more. Since I could not find an helper for this new version, I decided to create it on my own, and here is it!!
First, create the googlemap.php file under views / helpers, and copy/paste this:
<?php
/*
* CakeMap -- a google maps integrated application built on CakePHP framework.
* Based on initial versione from Garrett J. Woodworth : gwoo@rd11.com
* Rewritten by : http://www.small-software-utilities.com
*
* @author info@small-software-utilities.com
* @version 0.2
* @license OPPL
*
* Modified by Mahmoud Lababidi <lababidi@bearsontherun.com>
* Date Dec 16, 2006
* Rewritten by small software utilities <info@small-software-utilities.com>
* Date May, 2010
*/
class GoogleMapHelper extends Helper {
var $errors = array();
var $key = "your key here, not needed for v3";
var $url ="http://maps.google.com/maps/api/js?sensor=false";
function map($default, $style = 'width: 400px; height: 400px' )
{
//if (empty($default)){return "error: You have not specified an address to map"; exit();}
$out = "<div id=\"map\"";
$out .= isset($style) ? "style=\"".$style."\"" : null;
$out .= " ></div>";
$out .= "
<script type=\"text/javascript\">
//<![CDATA[
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var iconimage = \"http://labs.google.com/ridefinder/images/mm_20_red.png\";
var iconshadow = \"http://labs.google.com/ridefinder/images/mm_20_shadow.png\";
var myOptions = {
zoom: ".$default['zoom'].",
center: new google.maps.LatLng(".$default['lat'].", ".$default['long']."),
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: true
};
var map = new google.maps.Map(document.getElementById(\"map\"), myOptions);
// global infowindow object
var globalInfowindow = new google.maps.InfoWindow();
function cleardirs()
{
if(directionsDisplay)
directionsDisplay.setMap(null);
div = document.getElementById('".(isset($default['directions_div'])?$default['directions_div']:'directions_div')."');
if(div)
div.innerHTML = \"\";
}
";
if(isset($default['directions_div']))
{
$out .= "
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('".$default['directions_div']."'));
function calcRoute(fromid,tolat,tolon) {
directionsDisplay.setMap(map);
from = document.getElementById(fromid).value;
var start = from;
var end = new google.maps.LatLng(tolat,tolon);
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
";
}
$out .="
//]]>
</script>";
return $out;
}
function addMarkers(&$data, $icon=null)
{
$out = "
<script type=\"text/javascript\">
//<![CDATA[
";
if(is_array($data))
{
$i = 0;
foreach($data as $n=>$m){
$keys = array_keys($m);
$point = $m[$keys[0]];
if(!preg_match('/[^0-9\\.\\-]+/',$point['longitude']) &&
preg_match('/^[-]?(?:180|(?:1[0-7]\\d)|(?:\\d?\\d))[.]{1,1}[0-9]{0,15}/',$point['longitude'])
&& !preg_match('/[^0-9\\.\\-]+/',$point['latitude']) &&
preg_match('/^[-]?(?:180|(?:1[0-7]\\d)|(?:\\d?\\d))[.]{1,1}[0-9]{0,15}/',$point['latitude']))
{
$out .= "
var point".$i." = new google.maps.LatLng(".$point['latitude'].",".$point['longitude'].");
var marker".$i." = new google.maps.Marker({
position: point".$i.",
map: map,
title:\"".(isset($point['title'])?$point['title']:'')."\",
shadow: iconshadow,
icon: iconimage,
});";
if(isset($point['title'])&&isset($point['html']))
{
$out .= " var infowindow$i = new google.maps.InfoWindow({
content: \"$point[title]$point[html]\"
});
google.maps.event.addListener(marker".$i.", 'click', function() {
infowindow$i.open(map,marker".$i.");
});";
}
$data[$n][$keys[0]]['js']="marker$i.openInfoWindowHtml(marker$i.html);";
$i++;
}
}
}
$out .= "
//]]>
</script>";
return $out;
}
function addClick($var, $script=null)
{
$out = "
<script type=\"text/javascript\">
//<![CDATA[
$script
google.maps.event.addListener(map, 'click', ".$var.", true);
//]]>
</script>";
return $out;
}
function addMarkerOnClick($innerHtml = null)
{
$mapClick = '
var mapClick = function (event) {
var marker = new google.maps.Marker({
position:event.latLng,
icon: iconimage,
map:map
});
var infowindow = new google.maps.InfoWindow({
content: \"'.$innerHtml.'\"
});
google.maps.event.addListener(marker, \'click\', function() {
infowindow.open(map,marker);
});
}
';
return $this->addClick('mapClick', $mapClick);
}
function moveMarkerOnClick($lngctl, $latctl, $innerHtml = null)
{
$mapClick = '
var mapClick = function (event) {
marker0.setPosition(event.latLng);
lngctl = document.getElementById(\''.$lngctl.'\');
latctl = document.getElementById(\''.$latctl.'\');
if(lngctl)
lngctl.value = event.latLng.lng();
if(latctl)
latctl.value = event.latLng.lat();
}
';
return $this->addClick('mapClick', $mapClick);
}
}
?>
To use you just need to add the helper to the controller, or to AppController if you want this in every other controller, like this:
<?php
class MyController extends AppController {
var $helpers = array( 'Googlemap');
....
}
Then, in the view, add these line:
$default = array('type'=>'0','zoom'=>13,'lat'=>'42.5846353751749',
'long'=>'11.5191650390625');
$points = array();
$points[0]['Point'] = array('longitude' =>$default['long'],'latitude' =>$default['lat']);
$key = $googlemap->key;
echo $javascript->link($googlemap->url);
echo $googlemap->map($default,'width: 600px; height: 400px');
echo $googlemap->addMarkers($points);
echo $googlemap->moveMarkerOnClick('StructureLongitudine','StructureLatitudine');
A simple explanation:
points is the array where your store, guess, points! The map methos writes out the js for the map, the addMarkers method add markers to the page. The last method, moveMarkerOnClick, was useful to me, for user placement. With this code you can create a map where the user can click to move the marker. Note that the marker which moves is always the one called marker0. The two methos parameters are the ids of two input boxes, representing latitude and longitude. This id is created automatically by CakePHP by using the usual syntax ControllernameInputname. The default variable contains map type, zoom level, center of the map respectively. You can also add directions to your map by adding a div, setting and id for it and then passing the id in the default array like this:
'directions_div'=>'directions_div'
You can also use the addMarkerOnClick function, which adds a marker when you click on the map. InfoWindows are supported, just add a title and html item to the point array, they will be used to create an infowindow to be displayed when you click on the marker icon.
Hope this helps!
PS: please not that this is a initial version of the helper, use it at your own risk! But please leave here some comments, feature request, bug, or else!
Thanks!
EDIT: According to Amjith, to use this in cakephp v1.3 you must use:
$this->GoogleMap-> instead of $googlemap->
and name the file helper as google_map.php
EDIT 2: According to Duckula, for compatibility with Cake 1.3, you should use:
var $helpers = array( ‘GoogleMap’);
with capital M.
Sorry for these, but I still did not have the chance to try out v1.3, but I will soon!


Default
Small Fonts
Big Fonts