1

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>
2

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!!!!

  • thanks so much, that did the trick. So if in the future I have additional vector layers, can concat take multiple arguments, like baseLayers.concat(layerVector1, layerVector2)? – kflaw Oct 14 '15 at 14:52
  • I guess this should work. baseLayers.concat([layerVector1, layerVector2]) should work as well. In both cases you have a proper array object, The key is to pass layers argument as an array object.(to be more correct as an ol.Collection[openlayers.org/en/master/apidoc/ol.Collection.html] In your case, you did pass the layers as:layers:[[baseLayers[1],baseLayers[2]],layerVector] , while you should layers:[baseLayers[1],baseLayers[2],layerVector] so the concat did the trick – pavlos Oct 14 '15 at 20:50
  • How would this work if I wanted to add something othre than a bing map to the baseLayers array, could I do this? Say I have another WMS I want to add in as another option to choose from. – kflaw Oct 14 '15 at 22:30
  • Depends on what you want to achieve. Your current function switch on the selected base layer and off the rest of them. In that way it should work. But if you want to keep one baselayer and overlay your wms on top you should use a tree with checkboxes for example (for wms and/or wfs layers) where you may switch on and off independently. – pavlos Oct 15 '15 at 8:05
  • I want to add the WMS layer as a choice in my baseLayers list, though it is not a bing map. So I guess I could declare the WMS with its parameters and then push that to the baseLayers list.. I will try it – kflaw Oct 15 '15 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.