2
votes

My OpenLayers application includes several vector layers that interact with mouse movements. Everything was working as expected until I made one change to my css file. In my html, I defined a div:

<div id="main_map" class="map"></div>

My original/working css file includes:

#main_map {
 position: absolute;
 left: 200px;
 top: 0px;
 height: 600px;
 width: 1000px;
}

To give the map div a fluid width, I changed the css file to:

#main_map {
 position: absolute;
 left: 200px;
 top: 0px;
 height: 600px;
 width: calc(100% - 487px);
}

Now when the map displays, there is some misalignment between the vector layers and the mouse coordinates, so my mouse-hover functions do not work correctly. If I change the size of the browser window just slightly, a redraw or refresh of the map div is invoked which makes this misalignment problem disappear. I visibly notice a slight shifting of vector elements on the map upon slightly resizing the browser window.

The following are my OpenLayer code snippets they may be relevant to this problem...first establish a map:

  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      })
    ],
    target: 'main_map',
    controls: ol.control.defaults({
      attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
        collapsible: true
      })
    })
  });

Next, I construct several vector layers (details not shown here) and group a few of them as:

  var vector_layer_all = new ol.layer.Group({ layers: [vector_layer,vector_layer2] });

Next, I set my zoom extent based on selected vector layer content:

  var extent = ol.extent.createEmpty();
  vector_layer_all.getLayers().forEach(function(layer) {
    ol.extent.extend(extent, layer.getSource().getExtent());
  });
  map.getView().fit(extent, map.getSize());

Finally, I display some text data in a text box div named map_location_info based on the position of the mouse over some vector layers on the map:

  var displayFeatureInfo = function(pixel) {
    var features = [];
    map.forEachFeatureAtPixel(pixel, function(feature,layer) {
      features.push(feature);
    }, null, function(layer) {
      return (layer === vector_layer | layer === vector_layer2 | layer === vector_layer3);
    });
    if (features.length > 0) {
      var info = [];
      var i, ii;
      for (i = 0, ii = features.length; i < ii; ++i) {
        info.push(features[i].get('Name'));
        info.push(features[i].get('Status'));
      }
      document.getElementById('map_location_info').innerHTML = info.join(', ') || '(unknown)';
    } else {
      document.getElementById('map_location_info').innerHTML = '&nbsp;';
    }
  };
  map.on('pointermove', function(evt) {
    if (evt.dragging) {
      return;
    }
    var pixel = map.getEventPixel(evt.originalEvent);
    displayFeatureInfo(pixel);
  });

Somehow I need to force a redraw or refresh to some OpenLayers component just after the initial rendering of the map and vector layers. At what point in the code/process should I redraw/refresh and which OpenLayers component should this refresh/redraw be applied to? Any suggestions would be appreciated.

Edit: In thinking about this further...the OpenLayers script is positioned inside the hmtl content section of a JQuery tab. The problem might be coming from the way JQuery renders its tab content.

1

1 Answers

0
votes

I was able to resolve the issue by moving the OpenLayers script block from inside a JQueryUI tab content space to the $(document).ready(function() { }); script block at the bottom of my html template (and below a bunch of script using the DataTables library within that script block). So, all that remains in the JQueryUI tab content spaces are divs with no inline scripts. I did not attempt to trace out the css propagation so I really don't know exactly what was causing my problem. With several high level js libraries (JQuery, JQueryUI, DataTables, OpenLayers - which includes Google Closure and more) playing together in the same space I need to be careful about the order in which things are getting done. So, my problem was not an OpenLayers problem, but rather a code organization and ordering problem. This problem/solution reminds me of some good advice I didn't take from my earlier days of learning javascript.