[GIS] why can’t I load a layers list to select from to the map in openLayers 3, addEventListener and attachEvent are unavailable

bing-mapsevent listenerjavascriptlayersopenlayers

I've tried to incorporate this sample that shows how to switch base layers into a page I am working on:

http://openlayers.org/en/v3.10.1/examples/bing-maps.html

When I try to load my page with the code included I get this error: Uncaught Error: addEventListener and attachEvent are unavailable. ol.js:34. I've googled this some but haven't found the answer yet. Here is all of the code for my page – I've pieced together code from various samples so I know it needs some cleanup, but wanted to include everything I have for reference. Can anyone help?

UPDATE:

I found that when I remove layerVector from the layers list to add to the map, I no longer get the error. Now my question is really, how can I have the functionality of choosing a base layer, while always maintaining the vector layer as well?

<!DOCTYPE html>
<html>
<head>
<title>Vector layer example</title>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://openlayers.org/en/v3.9.0/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.9.0/build/ol.js"></script>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div id="map" class="map"></div>
<div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content"></div>
    </div>
 <select id="layer-select">
       <option value="AerialWithLabels" selected>Aerial with labels</option>
       <option value="Road">Road</option>
     </select>
<script>                    

var style = new ol.style.Style({
  fill: new ol.style.Fill({
    color: 'rgba(255, 255, 255, 0)'
  }),
  stroke: new ol.style.Stroke({
    color: '#000066',
    width: 1
  }),
});
var styles = [style];

sourceVector = new ol.source.Vector({
    loader: function(extent) {
        $.ajax('http://52.24.37.126:8080/geoserver/wfs',{
            type: 'GET',
            data: {
                service: 'WFS',
                version: '1.1.0',
                request: 'GetFeature',
                typename: 'Iada_workspace:parcels',
                srsname: 'EPSG:3857',
                outputFormat: 'application/json',
                bbox: extent.join(',') + ',EPSG:3857'
                },
            }).done(loadFeatures);
        },
        strategy: ol.loadingstrategy.tile(new ol.tilegrid.createXYZ({
            })),
    });

window.loadFeatures = function(response) {
    geoJSON = new ol.format.GeoJSON();
    sourceVector.addFeatures(geoJSON.readFeatures(response));
    };

var layerVector = new ol.layer.Vector({
    source: sourceVector,
    minResolution: 0,
    maxResolution: 4
    });

var baseStyles = [
  'Road',
  'AerialWithLabels',
];
var baseLayers = [];
var i, ii;
for (i = 0, ii = baseStyles.length; i < ii; ++i) {
  baseLayers.push(new ol.layer.Tile({
    visible: false,
    preload: Infinity,
    source: new ol.source.BingMaps({
      key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3',
      imagerySet: baseStyles[i]
      // use maxZoom 19 to see stretched tiles instead of the BingMaps
      // "no photos at this zoom level" tiles
      // maxZoom: 19
    })
  }));
}

var map = new ol.Map({
    layers: [baseLayers, layerVector], //new ol.layer.Tile({source: new ol.source.OSM()}), layerVector],
    loadTilesWhileInteracting: true,
    target: document.getElementById('map'),
    view: new ol.View({
                //projection:projection
                center: ol.proj.transform(
                    [-116, 42], 'EPSG:4326', 'EPSG:3857'),
                zoom: 6
        })
    });

var select = document.getElementById('layer-select');
function onChange() {
  var style = select.value;
  for (var i = 0, ii = baseLayers.length; i < ii; ++i) {
    baseLayers[i].setVisible(baseStyles[i] === style);
  }
}
select.addEventListener('change', onChange);
onChange();

    var highlightStyleCache = {};

var featureOverlay = new ol.layer.Vector({
  source: new ol.source.Vector(),
  map: map,
  style: function(feature, resolution) {
    var res = resolution < 4; //? feature.get('FID') : '';
    if (!highlightStyleCache[res]) {
      highlightStyleCache[res] = [new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#f00',
          width: 1
        }),
        fill: new ol.style.Fill({
          color: 'rgba(255,0,0,0.4)'
        }),
      })];
    }
    return highlightStyleCache[res];
  }
});

var highlight;
var displayFeatureInfo = function(pixel) {

  var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
    return feature;
  });

  if (feature !== highlight) {
    if (highlight) {
      featureOverlay.getSource().removeFeature(highlight);
    }
    if (feature) {
      featureOverlay.getSource().addFeature(feature);
    }
    highlight = feature;
  }

};

map.on('pointermove', function(evt) {
  if (evt.dragging) {
    return;
  }
  var pixel = map.getEventPixel(evt.originalEvent);
  displayFeatureInfo(pixel);
});

var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');

closer.onclick = function() {
  popup.setPosition(undefined);
  closer.blur();
  return false;
};

var popup = new ol.Overlay(/** @type {olx.OverlayOptions} */ ({
  element: container,
  autoPan: true,
  autoPanAnimation: {
    duration: 250
  }
}));

map.addOverlay(popup);

// display popup on click
map.on('click', function(evt) {
  var feature = map.forEachFeatureAtPixel(evt.pixel,
      function(feature, layer) {
        return feature;
      });
  if (feature) {
    popup.setPosition(evt.coordinate);
    //$(container).popover({
      //'placement': 'top',
      //'html': true,
      content.innerHTML = '<b>Parcel No: </b>'+
      feature.get('parcel')+'<br>'+
      '<b>Owner: </b>'+
      feature.get('primowner')
  } 
});

// change mouse cursor when over marker
map.on('pointermove', function(e) {
  var pixel = map.getEventPixel(e.originalEvent);
  var hit = map.hasFeatureAtPixel(pixel);
  map.getTarget().style.cursor = hit ? 'pointer' : '';
});         
</script>
</body>
</html>

Best Answer

the problem comes from the way you declare layers when inisialising your map. so this piece of your code:

var map = new ol.Map({
    layers: [baseLayers, layerVector], 
    loadTilesWhileInteracting: true,
    target: document.getElementById('map'),
    view: new ol.View({
                //projection:projection
                center: ol.proj.transform(
                    [-116, 42], 'EPSG:4326', 'EPSG:3857'),
                zoom: 6
        })
    });

should change to this:

var layersToAdd = baseLayers.concat(layerVector);
var map = new ol.Map({
    layers: layersToAdd , 
    loadTilesWhileInteracting: true,
    target: document.getElementById('map'),
    view: new ol.View({
                //projection:projection
                center: ol.proj.transform(
                    [-116, 42], 'EPSG:4326', 'EPSG:3857'),
                zoom: 6
        })
    });

It seems they way you pass layers on map is not a proper array. so concatenating the array of base layers with the vector layer, forms a proper array. I have also made o fiddle check it here to test. There are slight mods of your code but the piece I mentioned above seems to cause the problem. Hope to help you!!!!