[GIS] External layer switcher and layer order

layersmapcontrolopenlayers

So I'm using an external layer switcher because I need it imbedded in a bootstrap dropdown menu. It works really great except for one thing…. when I change between viewing my base layers, the overlay layers get covered up and I have to deselect and reselect them again to place them on top.

Here's my code:

html:

<ul class="dropdown-menu" id="layerswitcher">
    <li class="dropdown">
            <li style="padding-left:5px;"><strong> Maps</strong></li>
            <label class="radio-inline"><li style="padding-left:10px;"><input type="radio" name="layer" value="0" checked=""> Open Street Map</li></label>
            <label class="radio-inline"><li style="padding-left:0px;"><input type="radio" name="layer" value="1"> MapQuest Map</li></label>
            <label class="radio-inline"><li style="padding-left:0px;"><input type="radio" name="layer" value="3"> Water Colors</li></label>
            <li class="divider"></li>
            <li style="padding-left:5px;"><strong> Imagery</strong></li>
            <label class="radio-inline"><li style="padding-left:10px;"><input type="radio" name="layer" value="2"> MapQuest Satellite</li></label>
        </ul>
    </li>
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown">
            <img src="../lib/images/layers.png" width="17" height="22" alt=""/> Layers <b class="caret"></b></a>
        <ul class="dropdown-menu" id="storeS">
            <li style="padding-left:10px;">
                <label class="checkbox-inline"><input id="pc0" type="checkbox" value="4"> Countries</li></label>
            <li style="padding-left:10px;">
                <label class="checkbox-inline"><input id="pc1" type="checkbox" value="5"> USA</li></label>
        </ul>
    </li>
</ul>

JS:

function switchLayer()
{
    var checkedLayer = $('#layerswitcher input[name=layer]:checked').val();
    for (i = 0, ii = layers.length - 2; i < ii; ++i)
        layers[i].setVisible(i == checkedLayer);
}
$(function () {
    switchLayer();
});
$("#layerswitcher input[name=layer]").change(function () {
    switchLayer();
});

var layers = [];
layers[0] = new ol.layer.Tile({
    source: new ol.source.OSM()
});

layers[1] = new ol.layer.Tile({
    visible: false,
    source: new ol.source.MapQuest({
        layer: 'osm'
    })
});

layers[2] = new ol.layer.Tile({
    visible: false,
    source: new ol.source.MapQuest({
        layer: 'sat'})
});

layers[3] = new ol.layer.Tile({
    visible: false,
    source: new ol.source.Stamen({
        layer: 'watercolor'
    })
});

$('#pc0').change(function () {
    if ($(this).is(':checked')) {
        layers[4].setVisible(true);
    } else {
        layers[4].setVisible(false);
    }
});

$('#pc1').change(function () {
    if ($(this).is(':checked')) {
        layers[5].setVisible(true);
    } else {
        layers[5].setVisible(false);
    }
});

layers[4] = new ol.layer.Tile({
    visible: false,
    source: new ol.source.TileWMS({
        url: 'http://localhost:8080/geoserver/opengeo/wms',
        params: {
            'LAYERS': 'opengeo:countries'},
        serverType: 'geoserver'
    })
});

layers[5] = new ol.layer.Tile({
    visible: false,
    source: new ol.source.TileWMS({
        url: 'http://localhost:8080/geoserver/usa/wms',
        params: {
            'LAYERS': 'usa:states'},
        serverType: 'geoserver'
    })
});

var map = new ol.Map({
    target: 'map',
    controls: ol.control.defaults().extend([
        new ol.control.ScaleLine({
            units: 'metric'
        })
    ]),
    layers: layers,
    view: new ol.View({
        center: ol.proj.transform([0, 10], 'EPSG:4326', 'EPSG:3857'),
        zoom: 3
    })
});

any ideas how to fix it to where layers 4 & 5 remain visible when I switch between the base layers (0 – 3)?

Best Answer

Needed to exclude the last two layers from the layerswitcher by adding a -2 to length like so:

for (i = 0, ii = layers.length-2; i < ii; ++i) layers[i].setVisible(i==checkedLayer);

This makes the layers visible on load, so set them to false like so:

layers[4] = new ol.source.TileWMS({
            Visible: false,
            source: new ol.source.TileWMS({
            url: 'http://something/geoserver/wms',
            params: {'LAYERS': 'country_borders'},
            serverType: 'geoserver'
        })
    });
layers[5] = new ol.source.TileWMS({
            Visible: false,
            source: new ol.source.TileWMS({
            url: 'http://something/geoserver/wms',
            params: {'LAYERS': 'lakes'},
        serverType: 'geoserver'
        })
    });