Search code examples
javascriptnode.jsoverlayopenlayers

Openlayers: Add a solid coloured layer as overlay


I want to give two points (GPS coordinates) as input (e.g. left top corner and bottom right corner) and add a layer where only this region is fully visible. The rest should be filled with a solid color and semi transparent. Should look something like this:

enter image description here

Im new to Openlayers and cant find an example... I found this example to add overlays but it didn't really help here: https://openlayers.org/en/latest/examples/overlay.html

Any idea on which function / part of the library is necessary to be used?


Solution

  • You could define a polygon covering the view extent with a hole for your specified extent. Then display it in the base layers vector context

    import "ol/ol.css";
    import Map from "ol/Map";
    import OSM from "ol/source/OSM";
    import TileLayer from "ol/layer/Tile";
    import View from "ol/View";
    import { fromLonLat, transformExtent } from "ol/proj";
    import { getVectorContext } from "ol/render";
    import { fromExtent } from "ol/geom/Polygon";
    import { Style, Fill } from "ol/style";
    
    var extent = transformExtent([10, 53, 20, 57], "EPSG:4326", "EPSG:3857");
    
    var osmLayer = new TileLayer({
      source: new OSM()
    });
    
    osmLayer.on("postrender", function (event) {
      var vectorContext = getVectorContext(event);
      vectorContext.setStyle(
        new Style({
          fill: new Fill({
            color: "rgba(0, 255, 255, 0.25)"
          })
        })
      );
      var polygon = fromExtent(map.getView().getProjection().getExtent());
      polygon.appendLinearRing(fromExtent(extent).getLinearRing(0));
      vectorContext.drawGeometry(polygon);
    });
    
    var map = new Map({
      layers: [osmLayer],
      target: "map",
      view: new View({
        center: fromLonLat([15, 55]),
        zoom: 5
      })
    });
    

    https://codesandbox.io/s/crazy-sun-qnezt?file=/main.js

    or in a separate vector layer above the base layer

    var polygon = fromExtent(map.getView().getProjection().getExtent());
    polygon.appendLinearRing(fromExtent(extent).getLinearRing(0));
    var feature = new Feature({geometry: polygon});
    
    var vectorLayer = new VectorLayer({
      source: new VectorSource({
        feature: [feature]
      }),
      style: new Style({
        fill: new Fill({
          color: "rgba(0, 255, 255, 0.25)"
        })
      })
    });
    
    map.addLayer(vectorLayer);