Yii 1.1: jquery-gmap

OO PHP interface to Google Maps with added functionality.
51 followers

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

  1. Extract the tarball.

  2. Place the "jquery-gmap" folder in your Yii extensions folder.

  3. 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

Version History

Total 16 comments

#18555 report it
e_jouan at 2014/11/16 11:06am
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

#17609 report it
funthere at 2014/07/07 09:12pm
Need Help

Great Extension!!

Is there anyone can show me examples of use polygon using this extension? I need your help. Thank you.

#15444 report it
fernandrez at 2013/11/10 11:31am
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>
#11079 report it
sirin k at 2012/12/14 03:31pm
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

#9965 report it
BigZ at 2012/09/25 11:02am
github: 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!

@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)

#9963 report it
ianaré at 2012/09/25 09:49am
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!

#9951 report it
BigZ at 2012/09/24 05:14pm
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

#9885 report it
mfarooq at 2012/09/19 04:39am
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...

#9147 report it
akimvital at 2012/07/24 07:20am
Size setup

How to set up width/height of map?

#8796 report it
shalaby at 2012/06/27 05:00am
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?

#7649 report it
alex-ks at 2012/04/04 07:28pm
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

#4370 report it
ianaré at 2011/06/30 03:51am
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.

#4367 report it
Nacesprin at 2011/06/29 11:45am
in IE appears blank

Hello. In IE 8, the DEMO section appears blank. Is this extension tested in IE?

#3756 report it
warden at 2011/05/05 10:12am
import in demo section

The import in demo section should be: Yii::import('ext.jquery-gmap.*'); if you place files in protected/extensions/

#3339 report it
ianaré at 2011/04/04 01:14pm
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,

  • ianaré
#3338 report it
Antonio Ramirez at 2011/04/04 12:54pm
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

Leave a comment

Please to leave your comment.

Create extension