Maihan Nijat
Maihan Nijat

Reputation: 9355

How to avoid flickering in Leaflet Tile Layer WMS implementation?

I am using the Leaflet WMS tile layer to load radar and display it on the map. I have a play button that loops through time series and with each loop it requests new tile. Everything works except the flicking issue. There is a flick between those requests.

I load layer once and then change params with setParams for new requests:

this.layer.setParams({
  time: this.currentTime.toISOString().split(".")[0] + "Z"
});

And this is how I load layer:

this.layer = L.tileLayer.wms("http://geo.weather.gc.ca/geomet/?", {
  layers: "RADAR_1KM_RRAI",
  format: "image/png",
  transparent: true,
  opacity: 0.5,
  zIndex: 2
});

Stackblitz: https://stackblitz.com/edit/mn-angular-leaflet-wms

Documentation: https://leafletjs.com/reference-1.6.0.html#tilelayer-wms

There is a plugin for leaflet https://github.com/heigeo/leaflet.wms but I am not sure if this would solve the problem. I tried to implement it but couldn't understand it well.

Upvotes: 4

Views: 2509

Answers (1)

Maihan Nijat
Maihan Nijat

Reputation: 9355

There are few things to take care of in order to have a smooth transition between layers.

1- Preload the layers, set the opacity to 0 and add it to the map

generateLayers() {
  let date = new Date(this.radarDates[0]);
  while (date < new Date(this.radarDates[1])) {
    const layer = L.tileLayer.wms(this.wmsURL, this.wmsOptions);

    date = new Date(date.setMinutes(date.getMinutes() + 10));

    layer.setParams({
      time: date.toISOString().split(".")[0] + "Z"
    });
    this.map.addLayer(layer);
    this.timeLayers.push(layer);
  }
  // Show the first layer
  this.timeLayers[0].setOpacity(this.showOpacityValue);
}

2- While playing, loop through all the preloaded layers and set the opacity to 0 and add it to the map, hide the current layer (opacity 0) and show the current layer (opacity 0.57)

setTransitionTimer() {
  if (this.timeLayerIndex > this.timeLayers.length - 1 || !this.isPlaying) {
    return;
  }
  setTimeout(() => {
    this.timeLayers.forEach(timeLayer => {
      timeLayer.setOpacity(0);
      timeLayer.addTo(this.map);
    });

    if (this.isShowRadar) {
      // set the opacity 0
      this.hideLayerByIndex(this.timeLayerIndex);
      // Add by 1 or reset
      this.incrementLayerIndex();
      // set the opacity 0.57
      this.showLayerByIndex(this.timeLayerIndex);
      // increase time by 10 minutes
      this.setCurrentTime();
      this.setTransitionTimer();
    } else {
      this.removeLayers();
    }
  }, this.transitionMs);
}

The complete code is available in Stackblitz: https://stackblitz.com/edit/mn-angular-leaflet-wms

Upvotes: 4

Related Questions