Search code examples
openlayersopenlayers-5

Color overviewMap according to mainMap


I need to color the area of the overview map which has been visited in the same map for the last zoom only.

I am able to get the extent to color and am able to append ImageLayer to the layers but over time layers increase a lot and the browser crashes.

I tried the CanvasImageLayer too but the canvas there is only of the size of the overview map so the coloring moves along with the scan.

ImageLayer Attempt

if (this.viewer.getView().getZoom() === this.viewer.getView().getMaxZoom()) {
            let raster = new RasterSource(this.rasterOptions);
            let newExtent = this.viewer.getView().calculateExtent();
            let previewColorLayer = new ImageLayer({
              opacity: 0.1,
              source: raster,
              extent: newExtent,
            });
            this.overviewMap.getOverviewMap().addLayer(previewColorLayer);
            raster.changed();
          }

CanvasLayer Attempt

this.canvasFunction = (extent, resolution, pixelRatio, size, projection) => {
      console.log("called");

      let canvasWidth = size[0], canvasHeight = size[1];
      if (!this.canvas) {
        this.canvas = document.createElement('canvas');

        this.canvas.setAttribute('width', canvasWidth);
        this.canvas.setAttribute('height', canvasHeight);
      }


      let ctx = this.canvas.getContext("2d");

      let mapExtent = this.viewer.getView().calculateExtent();
      let mapCenter = this.viewer.getView().getCenter();
      let mapCenterPixel = this.overviewMap.getOverviewMap().getPixelFromCoordinate(mapCenter);

      // ctx.clearRect(0, 0, canvasWidth, canvasHeight);
      if (this.viewer.getView().getZoom() === this.viewer.getView().getMaxZoom()) {
        ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
        ctx.save();

        // Draw relative to the center of the canvas
        // ctx.translate(canvasWidth / 6, canvasHeight / 6);
        // Cancel the rotation of the map.
        ctx.rotate(-this.overviewMap.getOverviewMap().getView().getRotation());
        // Position everything relative to the center of the map
        // ctx.translate(-mapCenterPixel[0], -mapCenterPixel[1]);

        let corner1 = this.overviewMap.getOverviewMap().getPixelFromCoordinate(getBottomRight(mapExtent));
        let corner2 = this.overviewMap.getOverviewMap().getPixelFromCoordinate(getTopLeft(mapExtent));
        console.log(pixelRatio, resolution);
        let scale = 1;
        let rect = [corner2[0], corner2[1],(corner1[0] - corner2[0])/scale, (corner1[1] - corner2[1])/scale];
        this.paint(this.canvas, ctx, rect);
        ctx.restore();
      }

      return this.canvas;
    };

    this.colorSource = new ImageCanvasSource({
      canvasFunction: this.canvasFunction,
      projection: this.state.projection
    });

    this.colorLayer = new ImageLayer({
      source: this.colorSource
    });

    this.overviewMap.getOverviewMap().addLayer(this.colorLayer);

Solution

  • For anyone else needing this, the only way to do this is using canvas layer and then store the state of the visited extents and then paint them when they are in the view. The tricky thing in this would be to paint once only but finding intersections and removing them to get a disjoint set of extents to paint is a solvable problem.