【问题标题】:How to avoid flickering in Leaflet Tile Layer WMS implementation?如何避免 Leaflet Tile Layer WMS 实现中的闪烁?
【发布时间】:2026-02-03 23:25:01
【问题描述】:

我正在使用 Leaflet WMS 切片图层来加载雷达并将其显示在地图上。我有一个循环播放时间序列的播放按钮,每个循环都请求新的瓷砖。一切正常,除了闪烁的问题。这些请求之间有一个轻弹。

我加载层一次,然后使用 setParams 更改参数以获取新请求:

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

这就是我加载图层的方式:

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

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

有一个用于传单https://github.com/heigeo/leaflet.wms 的插件,但我不确定这是否能解决问题。我试图实现它,但不能很好地理解它。

【问题讨论】:

  • 您的 stackblitz 示例似乎由于跨域问题而无法显示切片图层?但总的来说,您是否尝试过预加载/创建您需要的图层,以防止闪现?
  • @chrismarx 你能刷新几次吗?它大部分时间加载,但有时不加载。我尝试预加载图层并将其存储在数组中,然后添加删除图层,但我仍然遇到同样的问题。
  • 啊,我现在确实看到了图层。当您预加载图层时,您是否在删除当前图层之前在现有图层下方添加了下一个图层?
  • @chrismarx 删除了当前的,因为它没有给出预期的结果。如果是预加载的问题,我刚刚再次测试。我运行这出戏并将其放置几个周期。网络停止请求图层,因为已经缓存但仍在闪烁。
  • @chrismarx 我再次处理了您的建议(预加载图层),并通过几个在线示例最终得到了解决方案。谢谢

标签: javascript angular leaflet


【解决方案1】:

为了在层之间进行平滑过渡,需要注意的事项很少。

1- 预加载图层,将不透明度设置为 0 并将其添加到地图中

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- 播放时,循环播放所有预加载的图层并将不透明度设置为 0 并将其添加到地图中,隐藏当前图层(不透明度 0)并显示当前图层(不透明度 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);
}

完整代码可在 Stackblitz 中找到:https://stackblitz.com/edit/mn-angular-leaflet-wms

【讨论】: