[GIS] Using OpenLayers 3 with feature overlay

geojsonjavascriptopenlayers

I left out some very relevant information in my first post. I realized the issue I'm having isn't because of the counties layer itself but of the Feature overlay that is created when the user hovers over a feature from the counties layer.

My issue is this: I have two vector layers (USA states & USA counties) and what I am trying to do is have the map zoom to the extent of the state clicked, and also when a county is hovered over with the cursor it creates a new feature overlay (to highlight it) and pulls county information from the counties layer. So the clicking and zooming action should be limited to just states, and the hover and highlighting/information pulling should be limited to the county. But while the zoom to extent works for the state clicked it will also zoom to the extent of the county clicked (since it has to be hovered over to do so).

I think what is happening is that since the feature overlay is independent of a layer, the layer filter in the foreachfeatureatpixel does not ignore it? So the problem seems to be clicking on the feature layer results in the same zooming to extent action that I want to limit to only clicking on a state. Is there a way to do this such as disabling the on.click event when the feature overlay exists?

I have looked over Using OpenLayers 3 forEachFeatureAtPixel to specify layer? and tried implementing the same attempt at filtering selectable layers with the foreachfeatureatpixel method. But is there away to also filter a feature overlay too?

I am new to both JavaScript and OpenLayers so perhaps I am going about this in the wrong way.

Here are my layers:

var statesLayer = new ol.layer.Vector({
      title: 'usa states',
      source: new ol.source.GeoJSON({
          projection: 'EPSG:3857',
          url: 'simple_states.geojson'
      }),
      style: new ol.style.Style({
          stroke: new ol.style.Stroke({
              color: [44, 127, 184, 1],
              width: 2.5
          })
      })
  });
  var countiesLayer = new ol.layer.Vector({
      title: 'cpo counties',
      source: new ol.source.GeoJSON({
          projection: 'EPSG:3857',
          url: 'simple_counties.geojson'
      }),
      style: new ol.style.Style({
          stroke: new ol.style.Stroke({
              color: 'white',
              width: 1.75
          }),
          fill: new ol.style.Fill({
              color: [127, 205, 187, 0.6]
          })
      }),
      maxResolution: 4000
  });

Here is my attempt to use a singleclick interaction on the map.

      map.on('singleclick', function (evt) {
          var stateFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
              return feature;
          }, null, function (layer) {
              return layer === statesLayer;
          });
          if (stateFeature) {
              var extent = stateFeature.getGeometry().getExtent();
              map.getView().fitExtent(extent, map.getSize());
          } else {
              stateFeature = null;
          }
      });

Here is the overlay:

    var featureOverlay = new ol.FeatureOverlay({
          map: map,
          style: styleFunction
      });

And here is the method for creating the feature overlay for the highlight and getting the county info:

      map.on('pointermove', function (evt) {
          featureOverlay.getFeatures().clear();
          var countyFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
              return feature;
          }, null, function (layer) {
              return layer === countiesLayer;
          });

          if (countyFeature) {
              featureOverlay.addFeature(countyFeature);
              var countyName = countyFeature.get('NAME');
              var pop = countyFeature.get('POP');
          } else {
              countyName = "\u00A0";
              pop = "\u00A0";
          }
          document.getElementById('summaryLabel').innerHTML = '<p style="font-size:18px">' + countyName + '<br>' + pop + '</p>';
      });

Best Answer

The feature from the Feature Overlay is always returned. To filter out the filterOverlay just test if the layer parameter is defined. Like this:

var stateFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
  // If layer is undefined, that means it's a feature from a FeatureOverlay
  if (layer) {
    return feature;
  }
}, null, function (layer) {
  return layer === statesLayer;
});