You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenLayers:切换TileImage源URL时保留WebGL瓦片显示的方法

解决方案:保留旧瓦片直至新瓦片加载完成

直接调用TileImage.setUrl()会清空现有瓦片缓存并触发重新加载,导致旧瓦片立即消失。要实现新瓦片加载完成前保留旧瓦片,最简便的方式是通过双图层交替预加载的方式实现:

核心思路

维护两个WebGLTile图层:一个作为当前显示的气象图层,另一个作为预加载图层(初始隐藏)。切换时间戳时,先让预加载图层加载新瓦片,待其完成加载并可渲染后,再切换两个图层的可见性,确保视图始终有瓦片显示。

修改后的代码

import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import TileLayer from 'ol/layer/WebGLTile.js';
import View from 'ol/View.js';
import TileImage from 'ol/source/TileImage.js';

let urlA = "https://www.example.com/temperature.php?tile_x={x}&tile_y={y}&tile_zoom={z}&datetime=now";
let urlB = "https://www.example.com/temperature.php?tile_x={x}&tile_y={y}&tile_zoom={z}&datetime=now+1hour";
let urlC = "https://www.example.com/temperature.php?tile_x={x}&tile_y={y}&tile_zoom={z}&datetime=now+2hours";

// 当前显示的气象图层
let currentLayer = new TileLayer({
  source: new TileImage({url: urlA}),
});

// 预加载图层,初始隐藏
let preloadLayer = new TileLayer({
  source: new TileImage(),
  visible: false,
});

const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM(),
    }),
    currentLayer,
    preloadLayer,
  ],
  view: new View({
    center: [0, 0],
    zoom: 0,
  }),
});

// 切换瓦片逻辑
function switchWeatherTile(targetUrl) {
  // 给预加载图层设置新URL
  preloadLayer.getSource().setUrl(targetUrl);
  
  // 监听预加载图层的首次渲染事件(说明瓦片已加载完成)
  const renderHandler = () => {
    // 切换图层可见性
    currentLayer.setVisible(false);
    preloadLayer.setVisible(true);
    // 交换图层引用,为下一次切换做准备
    [currentLayer, preloadLayer] = [preloadLayer, currentLayer];
    // 移除监听,避免重复触发
    preloadLayer.un('render', renderHandler);
  };
  
  preloadLayer.once('render', renderHandler);
}

// 绑定按钮事件
document.getElementById("tempA").addEventListener("click", e => {
  switchWeatherTile(urlA);
  e.preventDefault();
})
document.getElementById("tempB").addEventListener("click", e => {
  switchWeatherTile(urlB);
  e.preventDefault();
})
document.getElementById("tempC").addEventListener("click", e => {
  switchWeatherTile(urlC);
  e.preventDefault();
})

补充说明

  • 利用render事件判断瓦片加载完成:当预加载图层能触发render事件时,说明已有足够的瓦片可以渲染到视图中,此时切换不会出现空白。
  • 如果需要更精确地等待所有可见瓦片加载完成,可以监听数据源的tileloadend事件,统计已加载瓦片数量与当前视图所需瓦片数量,匹配后再切换图层,但render事件已能满足绝大多数场景的需求。

内容的提问来源于stack exchange,提问作者Kuba Maroušek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 06:55:38