Search code examples
javascriptgoogle-maps-api-3web2pygeojson

Add infowindow and custom icon to Google map using Geojson


I have this simple Google map in a Web2py application. I would like to apply something like a switch for choosing the feature icon and also setting an infoWindow from json text.

Someone knows how I can do it?

var map;

function initMap() {
    map = new google.maps.Map(document.getElementById("events_map"), {
        center: {lat: 45.070309, lng: 7.686580999999933},
        zoom: 13,
        mapTypeControl: false
    });

    var largeInfowindow = new google.maps.InfoWindow();

    google.maps.event.addListener(map, 'idle', function() {
        var ne = map.getBounds().getNorthEast();
        var north = ne.lat();
        var east = ne.lng();
        var sw = map.getBounds().getSouthWest();
        var south = sw.lat();
        var west = sw.lng();
        var queryString = '?east=' + east + '&west=' + west + '&south=' + south + '&north=' + north + '&zoom=8'
        map.data.loadGeoJson('{{=URL('f_ajax', 'get_locations_g')}}' + queryString);
    });
}

json data has a category field that can have 1, 2, 3, or 4 as value.
So with a switch I would like to set the icon in this way:
var icon;
switch (feature.properties.category) {
    case '1':
        icon = greenIcon;
        break;
    case '2':
        icon = bluIcon;
        break;
    case '3':
        icon = redIcon;
        break;
    case '4':
        icon = blackIcon;
        break;
}

But I don't know how.

For the infowindow, can I use this function and how for displaying the json field 'description'?

Thanks.

function populateInfoWindow(marker, infowindow) {
    // Check to make sure the infowindow is not already opened on this marker.
    if (infowindow.marker != marker) {
        infowindow.marker = marker;
        infowindow.setContent("<div><a href='" + marker.link + "'>" + marker.title + '</a></div>');
        infowindow.open(map, marker);
        // Make sure the marker property is cleared if the infowindow is closed.
        infowindow.addListener('closeclick', function() {
            infowindow.marker = null;
        });
    }
}

Solution

  • For the icon you have to use the setStyle-function.

    A object with the icons should be the easiest approach here

      map.data.setStyle(function(feature) {
        return {
          icon:({1:greenIcon,
                 2:redIcon,
                 3:blueIcon,
                 4:blackIcon})[feature.getProperty('category')]
        };
      }); 
    

    The function for the InfoWindow may not be used, because there is no marker available in the click-handler, you have to set the options of the InfoWindow based on the clicked feature

      map.data.addListener('click', function(event) {
        largeInfowindow.setOptions({
          map     : map,
          position: event.feature.getGeometry().get(),
          content : '<strong>'+event.feature.getProperty('description')+'</strong>'
        })
      });
    

    Demo:

    function initMap() {
     
      var greenIcon       = 'http://maps.gstatic.com/mapfiles/markers2/icon_green.png',
          redIcon         = 'http://maps.gstatic.com/mapfiles/markers2/marker.png',
          blueIcon        = 'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png',
          blackIcon       = 'http://maps.gstatic.com/mapfiles/markers2/drag_cross_67_16.png',
         
          map             = new google.maps.Map(document.getElementById('map'), {
                              zoom: 4,
                              center: {lat:52.41, lng: 9.74}
                            }),
          largeInfowindow = new google.maps.InfoWindow({pixelOffset:new google.maps.Size(0,-30)});
      
      
      map.data.setStyle(function(feature) {
        return {
          icon:({1:greenIcon,
                 2:redIcon,
                 3:blueIcon,
                 4:blackIcon})[feature.getProperty('category')]
        };
      });
      
      map.data.addListener('click', function(event) {
        largeInfowindow.setOptions({
          map     : map,
          position: event.feature.getGeometry().get(),
          content : '<strong>'+event.feature.getProperty('description')+'</strong>'
        })
      });
    
      map.data.addGeoJson(json);
    
    }
    var json={
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {category:1,description:'Berlin'},
          "geometry": {
            "type": "Point",
            "coordinates": [
              13.392333984375,
              52.53627304145948
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {category:2,description:'Hamburg'},
          "geometry": {
            "type": "Point",
            "coordinates": [
              10.008544921875,
              53.57293832648609
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {category:3,description:'Cologne'},
          "geometry": {
            "type": "Point",
            "coordinates": [
              6.954345703125,
              50.951506094481545
            ]
          }
        }
      ]
    };
    html, body {
            height: 100%;
            margin: 0;
            padding: 0;
          }
          #map {
            height: 100%;
          }
    <script async defer
            src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
    <div id="map"></div>