This is a helper to generate GoogleMap maps (dynamic and static ones) in your CakePHP views.
Note: Google Maps API V2 is marked "deprecated". API V3 is supposed to be faster and more compatible to mobile browsers. Details
Also new: A googlemaps key is not necessary anymore.
Preamble
You can either dynamically collect the geo data, or you can use my behavior to retreive and store them persistently. I prefer storing them in a table using lat/lng fields as it will make displaying the markers faster (no need to fetch at runtime) – it also makes it possible to make distance queries using radius and such.
Usage
I wanted to keep it as simple as possible (otherwise you could use the maps with plain js right away).
You may set up configs/defaults in your config file:
$config['Google'] = array(
'zoom' => 6,
'lat' => 51.1,
'lng' => 11.2,
'type' => 'H', // Roadmap, Satellite, Hybrid, Terrain
'size' => array('width'=>'100%', 'height'=>400),
'staticSize' => '500x450',
);
Please include the Tools Plugin in your bootstrap with CakePlugin::loadAll()
or CakePlugin::load('Tools')
.
Now you need to add the helper to the controller (or the action):
// globally
public $helpers = array(..., 'Tools.GoogleMapV3');
// OR in the action:
public function map() {
$this->helpers[] = 'Tools.GoogleMapV3';
// rest of your code
}
Since there are many possible ways to include the required javascript file I formed an own method for it:
<?php
// include jQuery >= 1.4
echo $this->Html->script('jquery'); // or wherever it is in your js folder
// include the Google js code
echo $this->Html->script($this->GoogleMapV3->apiUrl());
// OR include it manually without cake (or use your own asset stuff)
echo '<script type="text/javascript" src="'.$this->GoogleMapV3->apiUrl().'"></script>';
You may also let the helper include it automatically – just pass the option "autoScript" => true to the map() method in the next step.
Now we can use it.
Interactive Maps
// init map (prints container)
echo $this->GoogleMapV3->map(array('div'=>array('height'=>'400', 'width'=>'100%')));
// add markers
$options = array(
'lat' => 48.95145,
'lng' => 11.6981,
'icon'=> 'url_to_icon', // optional
'title' => 'Some title', // optional
'content' => '<b>HTML</b> Content for the Bubble/InfoWindow' // optional
);
// tip: use it inside a for loop for multiple markers
$this->GoogleMapV3->addMarker($options);
// print js
echo $this->GoogleMapV3->script();
You can also add windows and (custom) events. See the code and its tests for details on that.
Buffering scripts instead of outputting them directly
With 2.x you can also write the JS to the buffer and output it combined anywhere you want in your layout.
Just call
$this->GoogleMapV3->finalize(); // replaces script()
instead of echoing the script()
then. The script() call must not be used then. Don’t mix those two methods.
Also make sure you got echo $this->Js->writeBuffer(array('inline' => true));
somewhere in your layout then.
Most developers put CSS in the head and JS at the very bottom (before the closing </body>
tag). This way, the layout renders very fast and the JavaScript will render last and does not impede the page loading process.
See the next chapter for details.
Directions (with or without additional text)
If you want to print directions from point A to point B, you can do so with:
echo $this->GoogleMapV3->map();
$from = 'Munich'; // needs to be geocoded at runtime
$to = array('lat' => 50.51, 'lng' => 13.40);
$this->GoogleMapV3->addDirections($from, $to);
$this->GoogleMapV3->finalize();
You can either pass in a string to be automatically geocoded or pass an array with lat/lng coordinates.
Note: Geocoding on demand is possible, but slightly slower and less resourceful. It is recommended to geocode in the backend – using PHP and the Plugin classes listed below – and output the coordinates here directly.
Static Maps
These are just images. Very handy if you don’t need the js overhead.
// markers
$markers = array(
array('lat'=>48.2, 'lng'=>11.1),
array('lat'=>48.1, 'lng'=>11.2, 'color' => 'green', ...)
);
// paths
$paths = array(
array(
'path' => array('Berlin', 'Stuttgart'),
'color' => 'green',
),
array(
'path' => array('44.2,11.1', '43.1,12.2', '44.3,11.3', '43.3,12.3'),
),
array(
'path' => array(array('lat'=>'48.1','lng'=>'11.1'), array('lat'=>'48.4','lng'=>'11.2')), //'Frankfurt'
'color' => 'red',
'weight' => 10
)
);
// some options and image attributes
$options = array(
'size' => '500x400',
'center' => true,
'markers' => $this->GoogleMapV3->staticMarkers($markers),
'paths' => $this->GoogleMapV3->staticPaths($paths),
);
$attr = array(
'title'=>'Yeah'
);
// now display the map image
echo $this->GoogleMapV3->staticMap($options, $attr);
// you can even add an url to click on
$attr['url'] = $this->GoogleMapV3->mapUrl(array('to'=>'Munich, Germany'));
echo $this->GoogleMapV3->staticMap($options, $attr);
As you can see, we can now mix lat/lng and normal addresses (which get automatically geocoded in the background).
Map Links
If you want to redirect to maps.google.com (for directions etc) you can use this method.
// leave "from" empty for the user
$url = $this->GoogleMapV3->mapUrl(array('to'=>'Munich, Germany'));
echo $this->Html->link('Visit Me', $url, array('target'=>'_blank')
// coming from a posted form or whatever
$url = $this->GoogleMapV3->mapUrl(array('to'=>'Munich, Germany', 'from'=>$from));
echo $this->Html->link('Directions to me', $url, array('target'=>'_blank')
Last but not least
Other updates:
- multiple paths and markers
- visible scope
- custom icons possible
For more examples check out the test case. It contains several more sophisticated examples.
Helper Code
The code can be found in my github rep:
Tools Plugin GoogleMapV3 helper
Update 2012-02
All URLs/links are now HTTPS sensitive. So if you display the map on a secure site (https://...
) it will also use the same connection for all the google stuff (images, js, …). This is necessary for HTTPS to be valid.
Update 2012-09: GoogleMapsV3Helper v1.3 – not backwards compatible
The helper is now E_STRICT compliant. The methods url() and link() are now mapUrl() and mapLink().
Update 2013-02
directions() has been added to print directions from point A to B. Also basic geocoding capabilities have been added for this method as well as addMarker().
Update 2013-10
The "open" option for markers allows you to display their infoWindow opened at loading. This was a feature request on github. It is available for single and multi windows mode. Note that for single window mode (default), only one marker can be shown as open at once (the last one declared).
Update 2018
The API key is now necessary/required, as such there is an update for 2.x.
And the CakePHP 3.x repo can be found at github.com/dereuromark/cakephp-geo.
its showing my cuurent location instead of dynamic location
Hello Mark,
i want to ask you how can i get the lat/lng visitor with this helper, if it’s impossible how can i do this with javascript. Codes and link are welcome.
Thanks for your help 🙂
I use a loop with foreach for create markers.
The ‘address’ work fine and display good the ‘icons’, but ‘title’ show the same title in all markers (is title from the last add marker)….
I can’t display ‘content’ …
Hello Mark
is there a way to get separate coordinates by clicking on map ? I need to store the coordinates in two different hidden fields on a form, for saving purposes.
With custom JS I am sure there is.
Hello Mark,
Can you help me, I need your tools plugin for cakephp 2.x. But it removed from git directory and moved to cakephp 3.x. I need this plugin for my current work. If you can provide me that, i am thankful to you 🙂