Jordi Piqueras Jordi Piqueras - 28 days ago 11
Javascript Question

Getting information from overlapping layers in Google Maps Javascript API

I have a map developed with javascript Google Maps API V3 that loads 3 GeoJSON layers. I added some addListener functions in order to get the information of each layer when is clicked:

layer1.addListener('click', function() {
alert("layer1");
});
layer2.addListener('click', function() {
alert("layer2");
});
layer3.addListener('click', function() {
alert("layer3");
});


Some of these layers are overlapping themeselves like this example

At this point I am only able to acquire top layer information (the top layer listener is the only one triggered) and I want to get the information from all the layers.

After seeing that behaviour, I tried to have a global map addListener triggered when a user clicks on map

map.addListener('click', function(event) {
//alert("map click");
console.log(event);
});


I added this listener function attached to the map object but it is not triggered when a feature is clicked (it seems that feature listener takes precedence over map listener).

What can I do to get all the layers information under a latlng point?

Answer

The suggestion with "normal" Google Maps Polygons, KmlLayers, FusionTablesLayers, is to make them not take mouse events (set clickable: false), but it looks like DataLayer Polygons doen't use the clickable: false property of the DataStyleOptions.

One option would be to translate the DataLayer Polygons to google.maps.Polygon objects, setting clickable: false on them, then do a point in polygon analysis on all those polygons to determine which polygon(s) contain the clicked point.

proof of concept fiddle

code snippet:

var map;
var layer1;
var layer2;
var layer3;
var polygons = [];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {
      lat: 41.5224,
      lng: 2.1455
    }
  });

  layer1 = new google.maps.Data();
  layer2 = new google.maps.Data();
  layer3 = new google.maps.Data();

  layer1.addListener('addfeature', createPolygons);
  layer2.addListener('addfeature', createPolygons);
  layer3.addListener('addfeature', createPolygons);

  // Load GeoJSONs.
  layer1.addGeoJson({
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "properties": {
        "name": "tsstwstae",
        "desc": "taeae"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.2254180908203125, 41.46717104920911],
            [2.1004486083984375, 41.42393631848872],
            [2.1838760375976562, 41.362122449727956],
            [2.2511672973632812, 41.407200866420744],
            [2.2267913818359375, 41.46356925533331],
            [2.2254180908203125, 41.46717104920911]
          ]
        ]
      }
    }]
  });
  layer2.addGeoJson({
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "properties": {
        "name": "test1",
        "desc": "test1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.1790695190429688, 41.466399253078876],
            [2.167739868164062, 41.41904486310779],
            [2.1704864501953125, 41.39226405354582],
            [2.2209548950195312, 41.39097623653649],
            [2.231597900390625, 41.42393631848872],
            [2.2144317626953125, 41.43680680891725],
            [2.2034454345703125, 41.459452674486556],
            [2.1818161010742188, 41.470772643007564],
            [2.1790695190429688, 41.466399253078876]
          ]
        ]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "test2",
        "desc": "test2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.256317138671875, 41.46151099757483],
            [2.231597900390625, 41.45070407253965],
            [2.2487640380859375, 41.42625319507269],
            [2.278289794921875, 41.42625319507269],
            [2.2683334350585938, 41.45404926555731],
            [2.2638702392578125, 41.46408380956508],
            [2.256317138671875, 41.46151099757483]
          ]
        ]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "test3",
        "desc": "test3"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.13134765625, 41.42754031300878],
            [2.1018218994140625, 41.39226405354582],
            [2.1430206298828125, 41.377066187268866],
            [2.182846069335937, 41.380930388318],
            [2.1581268310546875, 41.39097623653649],
            [2.1639633178710938, 41.40153558289846],
            [2.1605300903320312, 41.413638089039786],
            [2.1577835083007812, 41.4249660516211],
            [2.164306640625, 41.427797733534135],
            [2.1361541748046875, 41.430371882652814],
            [2.13134765625, 41.42754031300878]
          ]
        ]
      }
    }]
  });
  layer3.addGeoJson({
    "type": "FeatureCollection",
    "features": [{
      "type": "Feature",
      "properties": {
        "name": "test1",
        "desc": "test1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.2061920166015625, 41.453534631705814],
            [2.1258544921875, 41.429342235252946],
            [2.1869659423828125, 41.329904449073865],
            [2.300262451171875, 41.368048825311206],
            [2.2576904296875, 41.454563895325855],
            [2.2247314453125, 41.45816618938139],
            [2.2061920166015625, 41.453534631705814]
          ]
        ]
      }
    }, {
      "type": "Feature",
      "properties": {
        "name": "test2",
        "desc": "test2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [2.2240447998046875, 41.48852043212608],
            [2.132720947265625, 41.48569140009698],
            [2.1138381958007812, 41.4504467428547],
            [2.2724533081054688, 41.47334508750842],
            [2.242584228515625, 41.49237800399966],
            [2.2240447998046875, 41.48852043212608]
          ]
        ]
      }
    }]
  });

  layer1.setStyle({
    fillColor: 'green',
    opacity: 0.5,
    strokeWeight: 1,
    clickable: false
  });

  layer2.setStyle({
    fillColor: 'red',
    opacity: 0.5,
    strokeWeight: 1,
    clickable: false
  });

  layer3.setStyle({
    fillColor: 'blue',
    opacity: 0.5,
    strokeWeight: 1,
    clickable: false
  });

  layer1.setMap(map);
  layer2.setMap(map);
  layer3.setMap(map);

  var layers = [];
  layers.push(layer1);
  layers.push(layer2);
  layers.push(layer3);

  map.addListener('click', function(event) {
    document.getElementById('status').innerHTML = "";
    for (var i = 0; i < polygons.length; i++) {
      if (google.maps.geometry.poly.containsLocation(event.latLng, polygons[i])) {
        document.getElementById('status').innerHTML += "polygon " + i + " name=" + polygons[i].name + " desc=" + polygons[i].desc + "<br>";
      }
    }
  });

  function getAllProperties(pointLatLng) {
    for (var key in layers) {
      var layer = layers[key];
      layer.forEach(function(feature) {
        var gaGeom = feature.getGeometry();
      });
    }
  }
  layer1.setMap(null);
  layer2.setMap(null);
  layer3.setMap(null);
}
google.maps.event.addDomListener(window, "load", initMap);

function createPolygons(e) {
  if (e.feature.getGeometry().getType() == "Polygon") {
    var paths = [];
    for (var i = 0; i < e.feature.getGeometry().getArray().length; i++) {
      var path = [];
      paths.push(e.feature.getGeometry().getAt(i).getArray());
    }
  }
  var polygon = new google.maps.Polygon({
    paths: paths,
    map: map,
    clickable: false,
    name: e.feature.getProperty('name'),
    desc: e.feature.getProperty('desc')
  });
  polygons.push(polygon);
}
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="status"></div>
<div id="map"></div>