Simple Google Maps object for use with ajax maps

You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#2) »

The Google mapping extension by Dos Amigos (link) is really great but there are difficulties with Google maps when you want to manipulate your map object with Ajax.

Thanks to some core code from Dos Amigos, I have fashioned a simpler way to manage ajax manipulation of Google maps.

The method described here enables you to create a map canvas and then update it over time with Ajax calls.

First, create an javascript file with the following code

[javascript]

var myGMap = (function(){
    var gmap0infoWindow;
    var gmap0;
    var gmarker = [];
    var container;
    var mapOptions;
    
    function myGMap(){
        this.canvas = 'gmap0-map-canvas';
        this.lat = 43.7621527000;
        this.long = 2.9246927000;
        this.zoom = 7;
        
        for(var prop in arguments[0])   {
            if(this.hasOwnProperty(prop))   {
                this[prop]=arguments[0][prop];   
            }
        }
        
        mapOptions = {"center":new google.maps.LatLng( this.lat, this.long ),"zoom": this.zoom};
        console.log('set map canvas:' + this.canvas);
        console.log(this);
        
        container = document.getElementById( this.canvas );
        
        if (container)
        {
            container.style.width = '100%';
            container.style.height = '512px';
            gmap0 = new google.maps.Map(container, mapOptions);

            gmap0infoWindow = new google.maps.InfoWindow();
        }
    //    google.maps.event.addDomListener(window, 'load', initialize);
    }

    myGMap.prototype.getMap = function() {
            return gmap0;
    }
    myGMap.prototype.addMarker = function(lat, lng, title, content, iconFile) {
        count = gmarker.length;

        gmarker[count] = new google.maps.Marker({
            "map": gmap0,
            "position": new google.maps.LatLng(lat, lng),
            "title": title,
            "icon": iconFile
        });

        google.maps.event.addListener(gmarker[count], 'click', function(event){

            gmap0infoWindow.setContent( content );

            gmap0infoWindow.open(gmap0, this);
        });
    }

    myGMap.prototype.clearMarkers = function() {
      for (var i = 0; i < gmarker.length; i++) {
        gmarker[i].setMap( null );
      }
      gmarker = [];
    }

    return myGMap;

})();

and then include it in your view, probably using an asset file.

Somewhere in a view, render the map canvas, something like this

<div class="col-md-12">
        <div id="gmap0-map-canvas"></div>
    </div>
                              

Now, you have the choice of initialising the map at the bottom of the same view

$js .= "gmap0 = new myGMap({canvas: 'gmap0-map-canvas'}); ";
    // options include {
    // canvas: "element id of canvas" - defaults to gmap0-map-canvas
    // lat: latitude of center of map,
    // long: longitude of center of map,
    // zoom: zoom factor
    // }
    
    $this->registerJs($js, View::POS_READY, 'map_tab');

and then adding map Markers

$js .= "gmap0.addMarker( 43.308941, 3.346367, 'html for popup box', '/path/to/custom_icon.png');

or, in a more complex scenario, you can return the addMarkers in an Ajax call

[javascript]

        link = 'url/to/action-that-returns-just-javascript';
        gmap0.clearMarkers();
        $.getScript( link  , function( data, textStatus, jqxhr ) {
                 setTimeout(function() {map = gmap0.getMap(); var center = map.getCenter(); google.maps.event.trigger(map, 'resize'); map.setCenter(center);}, 500);
        });

example of action-that-returns-just-javascript

public function actionThatReturnsJustJavascript()
{
    $markers = SomeModel::find()->where(some condition)->all();
    foreach($markers as $marker) {
        echo $marker->mapMarker('gmap0');
    }
}

// marker model
public function getMapMarker($gmapId)
{
    $js = $mapId.".addMarker( $this->lat, $this->lng, '{$this->title}', '$this->content', '/images/icons/$this->type.png');";
    return $js;
}

As the map canvas name is configurable, you can easily include more than one map on a page, without any conflicts between the multiple maps. This would also apply to having one map in your main page and then others in pop-ups or overlays.

Happy mapping!

0 0
3 followers
Viewed: 16 490 times
Version: Unknown (update)
Category: How-tos
Written by: Chris Backhouse
Last updated by: Chris Backhouse
Created on: Oct 5, 2015
Last updated: 8 years ago
Update Article

Revisions

View all history

Related Articles