Update/Reload 传单中动态的特定图块

Update/Reload specific tile in leaflet dynamicly

如果我的服务器告诉客户端 reload/update 何时发送什么磁贴,服务器如何 reload/update 发送磁贴? 我正在使用L.CRS.Simple CRS。而且我在自定义游戏地图上没有缩放级别。

这是我的代码:

var map = L.map('map', {
    crs: L.CRS.Simple,
    attributionControl: false
}).setView([0, 0], 2)

L.tileLayer('/chunks/{x}.{y}.png', {
 maxNativeZoom: 1, 
 minNativeZoom: 1,
}).addTo(map)


function ReloadTile(x,y){
   // UPDATE TILE HERE Request for example /chunks/{1}.{1}.png depending on input
}

首先,收听 tileload and tileunload events of the L.TileLayer 以在加载时获取对图块的引用(并在卸载时释放这些引用),例如

let myTileLayer = L.tileLayer(...);

let tileRefs = {};

myTileLayer.on('tileload', function(ev) {
   tileRefs[ ev.coords.x + ',' + ev.coords.y ] = ev.tile;
});
myTileLayer.on('tileunload', function(ev) {
   delete tileRefs[ ev.coords.x + ',' + ev.coords.y ];
});

...所以无论何时你想更新一个图块,你只需要在数据结构中搜索它。

请记住,要重新加载 HTMLImageElement,您必须更改其 src 属性,例如:

function ReloadTile(x,y){
   const tile = tileRefs[x + ',' + y];
   if (!tile) {
      // Tile is not currently loaded on the screen
      return;
   }
   tile.src = "/chunks/{1}.{1}.png";
}

谨防请求您的浏览器已缓存的 URL。做好有关缓存清除和相关 HTTP 的作业 headers.

请注意,我使用 javascript Object 作为 key-value 数据结构,并使用字符串连接为每个图块构建一个唯一的键。您可以自由使用其他数据结构(例如 Map)和任何其他方法来索引图块(例如 double-depth 数据结构用于 x-y,或 triple-depth对于 x-y-z,或按图块索引 URL)。另请注意,示例代码仅使用图块的 X 和 Y 坐标,因为您的 TileLayer 似乎只有一个缩放级别。

l感谢您的帮助!

我的最终代码:

var map = L.map('map', {
    crs: L.CRS.Simple,
    attributionControl: false
}).setView([0, 0], 2)


const path = '/chunks/{x}.{y}.png?cash={time}'

const layer = L.tileLayer(path, {
    maxNativeZoom: 1, 
    minNativeZoom: 1,
    time: 0
}).addTo(map)

function VectorToString(vector) {
    return vector.x + "." + vector.y
}

class TileHandler {
    constructor(layer){
        this.layer = layer
        this.layers = {}

        this.layer.on('tileload', (tile) =>  {
            this.layers[VectorToString(tile.coords)] = tile
        })
         
        
        this.layer.on('tileunload', (tile) => {
            delete this.layers[VectorToString(tile.coords)]
        })
    }

    update(position){
        const tile = this.layers[VectorToString(position)]
        const url = L.Util.template(tile.target._url, {
            ...position,
            time: new Date().getTime()
        })
        if (!tile) return
        tile.tile.src = url
    }
}