Search code examples
z-indexopenlayers

How can I set an Overlay on top when I click on it


I have an Openlayers map with a lot of overlays (Point-coordinates). These overlays are often very close to each other or overlapping.

When I click on an existing Overlay I want the Overlay to be set on top, so that it is fully seen, not behind any other Overlay.

So far I have only seen that the Layers can be set with an z-index. Is it possible to do that with overlays, too?

I would like to do something like that:

map.setLayerIndex(markers, 99);

but with an overlay


Solution

  • Overlays are controls, which are positioned on an coordinate instead of being in a fixed place. They are basically nothing more but regular html div elements and change position with the map.

    This also means, you can apply normal CSS styling and use z-index on them.

    var layer = new ol.layer.Tile({
      source: new ol.source.OSM()
    });
    
    var map = new ol.Map({
      layers: [layer],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 2
      })
    });
    
    // Vienna marker
    var marker1 = new ol.Overlay({
      position: ol.proj.fromLonLat([16.3725, 48.208889]),
      positioning: 'center-center',
      element: document.getElementById('marker1'),
      stopEvent: false,
      className: 'm1 ol ol-overlay-container ol-selectable'
    });
    map.addOverlay(marker1);
    
    marker2 = new ol.Overlay({
      position: ol.proj.fromLonLat([23.3725, 48.208889]),
      positioning: 'center-center',
      element: document.getElementById('marker2'),
      stopEvent: false,
      className: 'm2 ol ol-overlay-container ol-selectable'
    });
    map.addOverlay(marker2);
    
    
    
    function clicked(selector) {
      console.log('clicked overlay', selector);
      document.querySelectorAll(".ol").forEach(function(el){ 
        el.classList.remove('active');
      });
      document.querySelector(selector).classList.add('active');
    }
    html, body, .map {
      min-height: 50px;
      min-width: 50px;
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    
    .marker {
      width: 30px;
      height: 30px;
      border: 1px solid #088;
      border-radius: 15px;
      background-color: #0FF;
    }
    
    .m1 .marker {
      background-color: #FF0;
    }
    
    .active {
      z-index: 1234782904789;
    }
    .active .marker {
      background-color: red;
    }
    <link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v7.0.0/legacy/ol.css" rel="stylesheet"/>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@main/dist/en/v7.0.0/legacy/ol.js"></script>
    <div id="map" class="map"></div>
    <div id="marker1" title="Marker" class="marker" onclick="clicked('.m1')"></div>
    <div id="marker2" title="Marker" class="marker" onclick="clicked('.m2')"></div>