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
June 21st, 2010 at 10:13 pm
thanks for this helper.
there is type on line 152
double “new new”
feature request : sidebar with maps markers points
June 22nd, 2010 at 8:15 am
Thanks, corrected the bug. Regarding the feature request, do you mean a list of all markers on the map next or below the map itself? Must they be clickable or something?
July 16th, 2010 at 3:27 pm
Thanks for the helper – I’m setting it up now.
I cannot help but wonder why you don’t include the code in a format that is easier to copy and paste. I appreciate your effort, but manually removing the line numbers from 187 lines of code is not fun.
July 16th, 2010 at 3:44 pm
You’re right, hope it’s better now!
July 16th, 2010 at 4:10 pm
Wow – that was really quick! I hadn’t even gotten around to editing 10 lines, and you had the fixed. Thanks so much!
July 23rd, 2010 at 12:40 pm
for new version of cakePHP 1.3 use in view
$this->GoogleMap-> insterd of $googlemap->
and name file helper as google_map.php
Works great! keep rocking.
July 23rd, 2010 at 12:53 pm
[...] is another link i found for google map. Google Map Helper . You can copy this code for good map for your [...]
July 23rd, 2010 at 3:57 pm
Thanks, I’ll add this.
July 27th, 2010 at 2:17 am
sorry for late reply about your questions regards my feature request for Sidebar
yes you got what i meant.
clicking on link in sidebar will highlight respective marker and vice-versa.
i hope its clear to you now.
thanks again
August 14th, 2010 at 6:39 pm
in Cake 1.3 the helper-inclusion in the controller should be “var $helpers = array( ‘GoogleMap’);” (with a capital M)
August 14th, 2010 at 6:46 pm
Thanks, I edited the post with the explanation at the end! I hope to be able to try out cakephp v1.3 soon!
September 2nd, 2010 at 12:56 pm
How can I add a function to close the opened info window when a new point is being clicked?
September 11th, 2010 at 4:26 pm
Thanks, this is great! As you mentioned in CakePHP change all occurrences of
$googlemap-> to $this->GoogleMap
var $helpers = array(‘GoogleMap’);
and the helper file should be called ‘google_map.php’
September 21st, 2010 at 7:21 am
hii…sorry I’m newbie here…
I have followed lababidi tutorial at http://bakery.cakephp.org/articles/view/adding-a-google-map-to-your-app and http://bakery.cakephp.org/articles/view/googlemaphelper
and also change :
$googlemap-> to $this->GoogleMap
var $helpers = array(‘GoogleMap’);
and the helper file should be called ‘google_map.php’
but I cant try on my localhost, still error…
may you give me success example of this tutorial?
I’m confused, my googlemap never work..
send me an email at deem_014@yahoo.com
thank you so much..
regards,
Didik
September 21st, 2010 at 7:55 am
Hi, what kind of error do you get?
September 21st, 2010 at 8:19 am
there is no view in my index.ctp..
I also have app\views\layouts\map.ctp :
link($url);
?>
September 21st, 2010 at 8:22 am
sorry bad connection..
there is no view in my index.ctp..
I also have app\views\layouts\map.ctp :
link($url);
?>
September 21st, 2010 at 8:25 am
there is no view in my index.ctp..
I also have app\views\layouts\map.ctp :
link($url);
?>
not bad connection but my code can’t read here..
so i use #…
thank you paomic..
September 21st, 2010 at 8:25 am
I don’t really understand your comment, did you try to add the lines that are written above in your view?
$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’);
September 21st, 2010 at 8:31 am
Try to remove the php tags (< ?) from your comment!
September 21st, 2010 at 8:41 am
still error with your view..
this is my map.ctp:
link($url);
? >
September 21st, 2010 at 8:43 am
map.ctp
$key = “PASTE KEY HERE”;
$url = “http://maps.google.com/maps?file=api&v=2&key=$key”;
echo $javascript->link($url);
September 21st, 2010 at 8:45 am
Where did you find this? This is not the helper described above! Besides, it’s also api version 2. Did you sign up for a key at http://code.google.com/apis/maps/signup.html and replaced “PASTE KEY HERE”?
September 21st, 2010 at 8:55 am
sorry before..hehe
but now I use your tutorial, I copypaste all..
so what can I do?
in your tutorial, you only have 3 files right?
1.views\helpers\google_map.php
2.mycontroller
3.index.ctp
is that enough to make it work?
I’m still confused…
may I send my file to you?
thank
September 21st, 2010 at 8:58 am
I don’t think you copied those files, because at the top of the helper file there is:
var $key = “your key here, not needed for v3″;
var $url =”http://maps.google.com/maps/api/js?sensor=false”;
which is not the same as in your previous comment (I copied and pasted the above text from this post!). Please check that again, copy the text exactly as you find it in the post (remember to rename correctly if you are using cake 1.3) and then, if you still have problems, we can try to solve them.
September 21st, 2010 at 9:21 am
I can see the map now even few of the function doesn’t work…
:thumbup
thank you so much paomic….this is work!!!
GREAT TUTORIAL….
September 21st, 2010 at 9:34 am
Thanks! Which functions do not work?
September 21st, 2010 at 10:25 am
oh sorry paomic..
there some mistake with my mind..
after I read all, they are working fine…
I will tell my friend about your awesome website..
September 22nd, 2010 at 5:21 pm
hii..are there tutorial how to add marker & save in database?
thanks
September 22nd, 2010 at 8:18 pm
Hi, did you create a model with the appropriate fields? In this example you just need to create a form with two fields, longitude and latitude. Then tou use this
echo $googlemap->moveMarkerOnClick(‘StructureLongitudine’,'StructureLatitudine’);
in this case Structure is the name of the model, so StructureLongitudine is the id of the input box generated by
echo $form->create(‘Structure’);
..
echo $form->input(‘latitude’);
September 23rd, 2010 at 5:55 pm
yes of course..i have Place model with longitude and latitude fields…
the form has been created but still I can’t save to the database…
September 24th, 2010 at 8:15 am
Did you change this line:
$googlemap->moveMarkerOnClick(‘StructureLongitudine’,’StructureLatitudine’);
to
$googlemap->moveMarkerOnClick(‘PlaceLongitudine’,’PlaceLatitudine’);
September 26th, 2010 at 5:26 am
yes I did..
but still not working..
this is my controller :
function add(){
if(!empty($this->data)){
$this->Place->create();
if($this->Place->save($this->data)){
$places = $this->Place->find(‘all’);
$this->set(compact(‘$places’));
$this->render(‘success’,'ajax’);
}
else{
$this->render(‘failure’,'ajax’);
}
}
}
—————————–
and my index.ctp
<div id="map">
<?php
$default = array(‘type’=>’0′,’zoom’=>13,’lat’=>’-7.8′,
‘long’=>’110.3666667′);
$places = array();
$places[0]['Place'] = array(‘longitude’ =>$default['long'],’latitude’ =>$default['lat']);
$key = $this->GoogleMap->key;
echo $javascript->link($this->GoogleMap->url);
echo $this->GoogleMap->map($default,’width: 600px; height: 400px’);
echo $this->GoogleMap->addMarkers($places);
echo $this->GoogleMap->moveMarkerOnClick(‘PlaceLongitudine’,'PlaceLatitudine’);
?>
</div>
<?php
echo $form->create(‘Place’);
echo $form->input(‘latitude’);
echo $form->input(‘longitude’);
echo $ajax->submit(‘add’,array(‘url’=>’/place/add’,'update’=>’places’));
?>
September 26th, 2010 at 5:29 am
I use this to encode the php code http://centricle.com/tools/html-entities/
thanks
November 11th, 2010 at 10:36 am
Hi,
Im facing problem in google map integration with cakephp. Please help me on this.
Thanks
November 11th, 2010 at 10:38 am
i m getting bellow error
APP/views/points/index.ctp, line 53
and i m not able to add and edit
November 11th, 2010 at 10:42 am
Hi, you should be more precise, what kind of problem are you facing?
November 22nd, 2010 at 3:42 pm
I folks, I need help to use direction option, I’m able to add markers but, I want to get route between them.Tks
November 29th, 2010 at 2:43 pm
If i click on Marker how to get popup in this situation