[GIS] Layer selection in Openlayers 3

layersmapcontrolopenlayers

I'm trying to develop a robust way to generate a UI incorporating map layer controls such as a base layer selector. I've read several posts including this recent one but I'm still not able to change the visibility of the layers and always seem to return an error 'layer.setVisible is not a function'. Once I have a reliable method, I will be developing other controls for layer-styling etc.

I've followed several tutorials and generated a layer tree with opacity controls for example, but even though all of my layers are in groups, the layer tree generates several 'undefined' layers which I can't locate. Hence the reason I would like to build this from scratch, so that I can understand how to include or exclude layers and ensure that the ui is bound to the map object.

I'm aware of Matt Walker's LayerSwitcher but again, it doesn't really do what I want and I'm struggling to understand the 'layer walking' process adequately. Below is a sample of my code:

function getBaseGroup() {
var layers = map.getLayers();
var len = layers.getLength(), l;
for (var i = 0; i < len; i++) {
    l = layers.item(i);
    var lt = l.get('title');
    // check for layers within groups
    if (lt == 'Base Layers') { // Title of Group
        if (l.getLayers) {
            var innerLayers = l.getLayers().getArray();
            var base = [];
            for (var j = 0; j < innerLayers.length; j++) {
                base.push(innerLayers[j]['B']);
            }
            return base;
        }
    }
}
}

function showBase() {
var this_ = this;
var sel = $('#baseMapLayer');
var layers = getBaseGroup();

layers.forEach(function (layer) {
    sel.append($("<option>").attr('value', layer.title).text(layer.title));
});

$(sel).change(function () {
    var selectedValue = $(this).find(":selected").val();
    console.log("the value you selected: " + selectedValue);
    layers.forEach(function (layer) {
        console.log(layer); // returns layer object
        if (layer.title == selectedValue) {
            console.log(layer.title); // returns title
            layer.setVisible(true);
        }
        else {
            layer.setVisible(false);
        }
    });
});

Best Answer

Its hard to find out what is wrong as long as we dont have your whole work. map.getLayers() gives back all the layers exist on map and these may be layers generated internally by ol3 for interactions etc. I would put layers, I am intersted in, into an array or an ol.collection and I would use this object then. You can always set an extra attribute when initialising your layers object. For example:

var baseLayer = new ol.layer.Tile({
        DISPLAY_IN_SWITCHER:true
        visible: false,
        preload: Infinity,
        source: new ol.source.BingMaps({
            key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3',
            imagerySet: 'AerialWithLabels'
        })
    }));
}

and then you may filter layers exist in your switcher only. like so:

var allLayrs = map.getLayers();
layers.forEach(function (layer) {
    if (layer.get('DISPLAY_IN_SWITCHER')===true){
    console.log("this layer is listed in my tree",layer);

}
});