1

In this application layers are constructed dynamically from values stored in a JSON object. There is a layer control function that is called from buttons which toggle the visibility of the groups and the individual layers within the groups.

The problem - When an individual layer inside a group is toggled, the change isn't applied to the map until the user clicks on the map view-port. So when the user switches a layer on/off nothing happens.

It's fine if layer constructors are hard coded. It's only when building the layers from JSON that this happens. Also, if map.updateSize(); is called just after the visibility is set then the map visibility changes as required but this isn't how setvisible is meant to be used.

Is there a way to fix this issue with setvisible other than calling map.updateSize() to force it to apply the change?

I have created a fiddle demonstrating the issue here: https://jsfiddle.net/Rob_H/wvdmex8m/5

HTML

<div class="row">

    <div class="col-xs-2">

      <div id="layertree" class="row">

        <ul>
          <li>

           <input type="button" onclick="toggleLayer(basemaps)" value="Group"/>
            <ul>
              <li>
                <input type="button" onclick="toggleLayer(osm_baselayer)" value="Layer">            </li>
            </ul>
          </li>
        </ul>
      </div>
    </div>

Javascript

var response = {
  lyrs: [{
    subLayer: "osm_baselayer",
    name: "Open Street Map",
    visible: 1
  }],

  lyrGroups: [{
    groupName: "basemaps",
    visible: 1
  }]
};


var mapLayers = [];

function makelayerGroup() {
  var lyrGroups = response.lyrGroups;
  for (i in lyrGroups) {
    var layerGroup = lyrGroups[i].groupName;
    var vis = lyrGroups[i].visible;

    this[layerGroup] = new ol.layer.Group({
      visible: vis,
      name: layerGroup,
      layers: []
    });

    mapLayers.push(this[layerGroup]);

  };
  return makelayers();
};

function makelayers() {
  var lyrs = response.lyrs;
  for (row in lyrs) {
    var group_name = lyrs[row].groupName
    var sub_layer = lyrs[row].subLayer;
    var vis = lyrs[row].visible;

    //layer constructor                 
    this[sub_layer] = new ol.layer.Tile({
      visible: vis,
      name: lyrs[row].name,
      source: new ol.source.OSM()
    });


    var a = mapLayers[i].getLayers().getArray();
    a.push(this[sub_layer]);
  }

  return mapLayers;
};


//intialise the map
var map = new ol.Map({
  target: 'map',
  layers: makelayerGroup(),
  view: new ol.View({
    center: ol.proj.transform([-0.7, 52.1], 'EPSG:4326', 'EPSG:3857'),
    zoom: 11
  })
});

//function to toggle layers
function toggleLayer(layerName) {
  if (layerName.getVisible() == 1) {
    layerName.setVisible(0);
    console.log(layerName.get('name'));
  } else {
    layerName.setVisible(1);
    console.log(layerName.get('name'));
  }
};
  • Also, if map.updateSize(); is called just after the visibility is set then the map visibility changes as required. What's the problem now? – pavankguduru Sep 8 '17 at 4:55
  • The problem is that setvisible isn't working correctly. I don't want to call map.updateSize() each time just to make it work. – Robert Sep 9 '17 at 9:05

Your Answer

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

Browse other questions tagged or ask your own question.