Object oriented PHP interface to jquery-gmap plugin, used to access Google Maps with added functionality.
Q : Why use this extension when there are already others ?
A : This extension does not access the Google Maps API directly (although it can), it uses the GMap3 jQuery plugin. There are additional functionalities, and it is easier to do certain things, for example you can place markers and info windows using addresses instead of figuring out the latitude/longitude. There is also some built-in callbacks for centering certain overlays on the map.
This is still undergoing active development, mainly adding new features. The API should be stable.
Requirements ¶
Tested on Yii 1.1.6-7, should work on all 1.1.x versions.
Install ¶
Extract the tarball.
Place the "jquery-gmap" folder in your Yii extensions folder.
You can copy the example view files into your application for testing.
Usage ¶
Gmap3 has two modes of constructing the map : pure object oriented and object with arrays based. Internally, the extension converts any arrays to objects of the correct type.
Pure Object Oriented ¶
The pure OO way is useful for those that are using an IDE such as Netbeans or Eclipse, as all the options and properties are well documented in the code using Google's API documentation as a base.
This means you don't need to look up the API website to see which parameters are available for a particular object, and what type of value is needed.
It may also be easier to work with the map programmatically using this approach (i.e. setting options & parameters based on database values, etc ...).
$gmap = new EGmap3Widget();
$options = new EGmap3MapOptions();
$options->scaleControl = true;
$options->streetViewControl = false;
$options->zoom = 1;
$options->center = array(0,0);
$options->mapTypeId = EGmap3MapTypeId::HYBRID;
$typeOptions = new EGmap3MapTypeControlOptions();
$typeOptions->style = EGmap3MapTypeControlStyle::DROPDOWN_MENU;
$typeOptions->position = EGmap3ControlPosition::TOP_CENTER;
$options->mapTypeControlOptions = $typeOptions;
$zoomOptions = new EGmap3ZoomControlOptions();
$zoomOptions->style = EGmap3ZoomControlStyle::SMALL;
$zoomOptions->position = EGmap3ControlPosition::BOTTOM_CENTER;
$options->zoomControlOptions = $zoomOptions;
$gmap->setOptions($options);
Object With Array ¶
The object with array approach is maybe a little simpler to use, but you will need to know the exact names and types of the parameters you set. Note that to add overlays to the map such as markers, info windows, shapes, etc you will still need to pass objects. The arrays are only for object options.
$gmap = new EGmap3Widget();
$options = array(
'scaleControl' => true,
'streetViewControl' => false,
'zoom' => 1,
'center' => array(0,0),
'mapTypeId' => EGmap3MapTypeId::HYBRID,
'mapTypeControlOptions' => array(
'style' => EGmap3MapTypeControlStyle::DROPDOWN_MENU,
'position' => EGmap3ControlPosition::TOP_CENTER,
),
'zoomControlOptions' => array(
'style' => EGmap3ZoomControlStyle::SMALL,
'position' => EGmap3ControlPosition::BOTTOM_CENTER
),
);
$gmap->setOptions($options);
Combining ¶
Now of course, this isn't an all or nothing proposition, you can very well combine the two approaches :
$options = new EGmap3MapOptions();
$options->scaleControl = true;
$options->streetViewControl = false;
$options->zoom = 1;
$options->center = array(0,0);
$options->mapTypeId = EGmap3MapTypeId::HYBRID;
$options->mapTypeControlOptions = array(
'style' => EGmap3MapTypeControlStyle::DROPDOWN_MENU,
'position' => EGmap3ControlPosition::TOP_CENTER
);
$options->zoomControlOptions = array(
'style' => EGmap3ZoomControlStyle::SMALL,
'position' => EGmap3ControlPosition::BOTTOM_CENTER
);
$gmap->setOptions($options);
Extra Functions ¶
This extension comes with some built in enhancements to the Google Maps interface.
Save Marker Position and Map Zoom to Yii Model ¶
Allows capturing the latitude and longitude from a map marker, and the map's zoom level, to a Yii model object. This is useful if you want to save additional information related to an address in your database.
Address model example :
class Address extends CActiveRecord
{
public $latitude;
public $longitude;
public $mapZoomLevel;
public function rules()
{
return array(
array('latitude,longitude', 'numerical'),
array('mapZoomLevel', 'numerical', 'integerOnly'=>true),
);
}
}
In your view file :
// init the model (usually passed to view)
$address = new Address();
// init the map
$gmap = new EGmap3Widget();
$gmap->setOptions(array('zoom' => 14));
// create the marker
$marker = new EGmap3Marker(array(
'title' => 'Draggable address marker',
'draggable' => true,
));
$marker->address = '10 Downing St, Westminster, London SW1A 2, UK';
$marker->centerOnMap();
// set the marker to relay its position information a model
$marker->capturePosition(
// the model object
$address,
// model's latitude property name
'latitude',
// model's longitude property name
'longitude',
// Options set :
// show the fields, defaults to hidden fields
// update the fields during the marker drag event
array('visible','drag')
);
$gmap->add($marker);
// Capture the map's zoom level, by default generates a hidden field
// for passing the value through POST
$gmap->map->captureZoom(
// model object
$address,
// model attribute
'mapZoomLevel',
// whether to auto generate the field
true,
// HTML options to pass to the field
array('class' => 'myCustomClass'),
);
$gmap->renderMap();
Update Marker Position from Yii Model ¶
Allow updating a marker based on a Yii model, this is done interactively as a user completes or modifies a form (onchange).
Assuming the model «Address» as described above but also having the typical address parameters (lines, city, zip, etc).
In your view file :
// build a normal Yii form
$form = $this->beginWidget('CActiveForm', array(
'id'=>'address-form',
));
echo $form->textField($address, 'address1');
echo $form->textField($address, 'address2');
echo $form->textField($address, 'city');
// [etc ... etc ...]
// create a map centered in the middle of the world ...
$gmap = new EGmap3Widget();
$gmap->setOptions(array(
'zoom' => 2,
'center' => array(0,0),
));
// add a marker
$marker = new EGmap3Marker(array(
'title' => 'Updateable marker',
));
$marker->latLng = array(0,0);
$gmap->add($marker);
// tell the gmap to update the marker from the Address model fields.
$gmap->updateMarkerAddressFromModel(
// the model object
$address,
// the model attributes to capture, these MUST be present in the form
// constructed above. Attributes must also be given in the correct
// order for assembling the address string.
array('address1','address2','city','postalCode','region','country'),
// you may pass these options :
// 'first' - set to first marker added to map, default is last
// 'nopan' - do not pan the map on marker update.
array()
);
$gmap->renderMap();
Demo ¶
Take a look at the examples folder in the download for demos and examples. These are Yii view files you can copy into your application.
Resources ¶
- GMap3 plugin API & demos
- Forum topic, please use this to discuss all aspects of this extension.
- Github Fork it !
very good job
Love this library wrapper, and its structure is very well designed. I really like the option for 'reverse geolocation of the markers', I may include that option on EGMap if you don't mind as it also has that feature but not as easily provided as yours.
Good work
By all means
Thank you Antonio, your comment means a lot to me as I studied your extension closely before doing this one and was influenced by it.
You are welcome to take any ideas or functionality from this extension, however any code would have to be kept under the LGPL, as per my company's wishes.
Thanks,
import in demo section
The import in demo section should be:
Yii::import('ext.jquery-gmap.*');
if you place files in protected/extensions/
in IE appears blank
Hello. In IE 8, the DEMO section appears blank. Is this extension tested in IE?
should work
Should work in IE, have tested before but not for while now. Try disabling the elements one by one until the map appears, there could be a bug in there.
Get coordinates by right click
Hi.
How i can get current lat lon by clicking on the map and populate it in the form? Here is the code in js:
google.maps.event.addListener(map, "rightclick", function(event) { var lat = event.latLng.lat(); var lng = event.latLng.lng(); // populate yor box/field with lat, lng alert("Lat=" + lat + "; Lng=" + lng); });
How i can do this using this extension?
Thanks
repopulate the text boxes
Thanks so much for this amazing extension, i am using this widget in a form and i was wondering, how to repopulate the text boxes the widget creates in update action, and the map?
Size setup
How to set up width/height of map?
info window show/hide problem
Hi everyone.
is there any way to show/hide the info window, when the marker is clicked (by default hidden)... kindly help me...
Map auto-size
Hi, I customized the default behavior to support auto-size on responsive layouts.
I'm sharing the code in case anybody needs to do the same thing.
In EGmap3Widget.php, replace the 'run' function with this one:
public function run_autosize() { echo CHtml::openTag('div', array( 'id' => 'map_container', 'style' => "display: inline-block; position: relative; width: 100%;")); echo CHtml::openTag('div', array( 'id' => "map_dummy", 'style' => "margin-top: 65%", )), CHtml::closeTag('div'); echo CHtml::openTag('div', array( 'id' => $this->id, 'class' => 'gmap3', 'style' => "position: absolute; top: 0; bottom: 0; left: 0; right: 0", )), CHtml::closeTag('div'); echo CHtml::closeTag('div'); }
(play around w/ margin-top % for desired proportions)
And call it in renderMap:
public function renderMap() { $this->init(); $this->run_autosize(); }
I took the idea from:
http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio
Map auto-size
@bigZ if you would submit a patch to github for this functionnality I would be happy to include it in the code base. Thanks!
github: Map auto-size
@ianaré: I'd be happy to, but unfortunately I'm not familiar w/ submitting patches & github...
Can you give me some directions? (wipeout09@gmail.com)
is there is any way to plot the gmap inside a fancy box?
is there is any way to plot the gmap inside a fancy box?
i tried but failed.
-Sirin
Thanks man for this work
Hey man thanks for this extension, I appreciate it. I was trying to display a draggable marker and I couldn't get it to be draggable. Here I post the code for the whole view in which I render the map.
<?php /* @var $this InmuebleController */ /* @var $model Inmueble */ $this->breadcrumbs=array( Yii::t('app','inmueble',0)=>array('index'), $model->id, ); $this->menu=array( array('label'=>Yii::t('app','list',1)." ". Yii::t('app','inmueble',0), 'url'=>array('index')), array('label'=>Yii::t('app','create')." ". Yii::t('app','inmueble',1), 'url'=>array('create')), array('label'=>Yii::t('app','update')." ". Yii::t('app','inmueble',1), 'url'=>array('update','id'=>$model->id)), array('label'=>Yii::t('app','delete')." ". Yii::t('app','inmueble',1), 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->id),'confirm'=>Yii::t('app','sureDelete'))), array('label'=>Yii::t('app','manage')." ". Yii::t('app','inmueble',0), 'url'=>array('admin')), array('label'=>Yii::t('app','asociarArchivo'), 'url'=>array('/docs/doc/create','categoria'=>strtolower(get_class($model)),'relacionado_id'=>$model->id)), array('label'=>Yii::t('app','crearSolicitud'), 'url'=>array('/inmuebles/inmuebleSolicitud/create','inmueble_id'=>$model->id)), array('label'=>Yii::t('app','asociarTercero'), 'url'=>array('/inmuebles/inmuebleTercero/create','inmueble_id'=>$model->id)), ); ?> <h1><?php echo Yii::t('app','view')." ".Yii::t('app','inmueble',1).' # '. $model->id; ?></h1> <div class="row-fluid"> <div class="span12"> <?php $imgs=array(); if(count($model->inmuebleImagenes)>0){ //Ejecutar el codigo de slicing aca foreach($model->inmuebleImagenes as $imagen){ $imgs[]=array('image'=> Yii::app()->request->baseUrl.DIRECTORY_SEPARATOR.$imagen->ruta //$this->createUrl('marcaAgua',array('image_id'=>$imagen->id)) ); } $this->widget('bootstrap.widgets.TbCarousel', array( 'items'=>$imgs, )); } ?> </div> </div> <div class="row-fluid"> <?php /**/ $this->widget('zii.widgets.CDetailView', array( 'cssFile' => '/../../../base/assets/style.css', 'data'=>$model, 'attributes'=>$attributes, )); /**/?> </div> <?php echo '<h3>'.Yii::t('app','solicitud',0).'</h3>'; ?> <div class="row-fluid"> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'doc-impresion-grid', 'dataProvider'=>$inmuebleSolicitud->search(), //'ajaxUpdate'=>false, 'columns'=>array( 'id', 'titulo', 'descripcion', 'fecha_hora', array( 'class'=>'CButtonColumn', 'buttons'=>array( 'view' => array ( 'url'=>'Yii::app()->createUrl("inmuebles/inmuebleSolicitud/view", array("id"=>$data->id))', ), 'update' => array ( 'url'=>'Yii::app()->createUrl("inmuebles/inmuebleSolicitud/update", array("id"=>$data->id))', ), 'delete' => array ( 'url'=>'Yii::app()->createUrl("inmuebles/inmuebleSolicitud/delete", array("id"=>$data->id))', ), ), ), ), )); ?> </div> <?php echo '<h3>'.Yii::t('app','tercero',0).'</h3>'; ?> <div class="row-fluid"> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'doc-impresion-grid', 'dataProvider'=>$inmuebleTercero->search(), //'ajaxUpdate'=>false, 'columns'=>array( 'id', array('name'=>'razon_social','value'=>'isset($data->tercero)?$data->tercero->razon_social:""'), array('name'=>'categoria_id','value'=>'isset($data->categoria)?$data->categoria->titulo:""'), 'pct_participacion', 'pct_facturacion', 'pct_pagos', array( 'class'=>'CButtonColumn', 'buttons'=>array( 'view' => array ( 'url'=>'Yii::app()->createUrl("/inmuebles/inmuebleTercero/view", array("id"=>$data->id))', ), 'update' => array ( 'url'=>'Yii::app()->createUrl("/inmuebles/inmuebleTercero/update", array("id"=>$data->id))', ), 'delete' => array ( 'url'=>'Yii::app()->createUrl("/inmuebles/inmuebleTercero/delete", array("id"=>$data->id))', ), ), ), ), )); ?> </div> <?php echo '<h3>'.Yii::t('app','doc',0).'</h3>'; ?> <div class="row-fluid"> <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'doc-impresion-grid', 'dataProvider'=>$doc->search(), //'ajaxUpdate'=>false, 'columns'=>array( 'id', 'ruta', array('name'=>'usuario_id','value'=>'$data->usuario->username','filter'=>getUsers()), array('name'=>'macrocategoria_id','value'=>'$data->macrocategoria->titulo','filter'=>getDocumentMacrocategories()), array('name'=>'categoria_id','value'=>'$data->categoria->titulo','filter'=>getDocumentCategories()), array('name'=>'subcategoria_id','value'=>'$data->subcategoria->titulo','filter'=>getDocumentSubcategories()), 'fecha_hora', array( 'class'=>'CButtonColumn', 'buttons'=>array( 'view' => array ( 'url'=>'Yii::app()->createUrl("/docs/doc/view", array("id"=>$data->id))', ), 'update' => array ( 'url'=>'Yii::app()->createUrl("/docs/doc/update", array("id"=>$data->id))', ), 'delete' => array ( 'url'=>'Yii::app()->createUrl("/docs/doc/delete", array("id"=>$data->id))', ), ), ), ), )); ?> </div> <?php echo '<h3>'.Yii::t('app','mapaUbicacion',0).'</h3>'; ?> <div class="row-fluid"> <?php Yii::import('application.modules.inmuebles.extensions.gmap.gmap.*'); $gmap = new EGmap3Widget(); $gmap->setSize(600, 600); $gmap->id='mapa-ubicacion'; // base options $options = array( 'scaleControl' => true, 'streetViewControl' => true, 'zoom' => 14, 'center' => array(0, 0), 'mapTypeControlOptions' => array( 'style' => EGmap3MapTypeControlStyle::DROPDOWN_MENU, 'position' => EGmap3ControlPosition::BOTTOM_LEFT, ), 'zoomControlOptions' => array( 'style' => EGmap3ZoomControlStyle::DEFAULT_STYLE, 'position' => EGmap3ControlPosition::TOP_LEFT ), ); $gmap->setOptions($options); $marker = new EGmap3Marker(); $latitud=$model->latitud; $longitud=$model->longitud; if($latitud=="" || $longitud==""){ $marker->address=$model->direccion.",".$model->ciudad->nombre.",".$model->pais->nombre; } else{ $marker->latLng = array($latitud, $longitud); } $marker->centerOnMap(); $marker->setMapZoom(14); /* $js = "function(marker, event, data){ var map = $(this).gmap3('get'), infowindow = $(this).gmap3({action:'get', name:'infowindow'}); if (infowindow){ infowindow.open(map, marker); infowindow.setContent(data); } else { $(this).gmap3({action:'addinfowindow', anchor:marker, options:{content: data}}); } }"; $marker->data = 'test data !'; $marker->addEvent('click', $js);*/ $marker->draggable=true; $gmap->add($marker); ?> <div class="text-center transparent-background col-map" id="map-container"> <?php $gmap->renderMap(); ?> </div> <?php //echo CHtml::link('Marcar','',array('onclick'=>'marcadorDireccion(\''.$model->direccion.','.$model->ciudad->nombre.'\');')); ?> </div> <script> function marcadorDireccion(dir){ try{ $("#mapa-ubicacion").gmap3({'action': 'addMarker', 'address' : dir}); alert(dir); } catch(err) { alert(err.message); } } </script>
Need Help
Great Extension!!
Is there anyone can show me examples of use polygon using this extension?
I need your help. Thank you.
Filtering markers
Hi I am trying to filter the markers created via $gmap->add($marker); based on tags, using a javascript within script tags which is triggered via a change event attached to some checkboxes.
The script triggers fine BUT I dont manage to access any of gmap3 elements, especially the markers.
I have developed an alternative solution based on mapbox.js and it works... I would like to avoid using it.
Thanks for your kind help
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.