如何在TileLayer的图块上进行预处理,然后在Leaflet上显示它们? [英] How to do a preprocessing on tiles of a TileLayer before displaying them on Leaflet?

查看:55
本文介绍了如何在TileLayer的图块上进行预处理,然后在Leaflet上显示它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张大图像,使用gdal2tiles.py在256x256的瓷砖中破碎了.

I have a large image that I broke up in 256x256 tiles using gdal2tiles.py.

我将其显示为L.tileLayer.效果很好.

I display it on leaflet as a L.tileLayer. It works fine.

现在,我想在256x256瓦片在tileLayer中呈现之前对其进行预处理.我需要对这些存储的图块应用一种算法,并且该算法会生成大小相同但内容不同的图块.看起来就像动态更改存储的图块内容.

Now, I'd like to preprocess the 256x256 tiles before they are rendered in tileLayer. I need to apply an algorithm on these stored tiles, and the algorithm generates tiles of same size, but with different content. It can looks like changing stored tiles content dynamically.

是否可以用已处理的图块替换TileLayer中的图块?

Is it possible to replace tiles that are in TileLayer with processed tiles ?

我应该如何进行?

我只希望处理这些切片一次,所以我想应该利用缓存.

I would like to process these tiles only once, so I guess I should take advantage of caching.

推荐答案

@IvanSanchez谢谢您的回答.

@IvanSanchez thank you for your answer.

我创建了一个新的tileLayer,允许调用rest API在图块上进行预测(获取并返回以base64编码的PNG图像).

I created a new tileLayer allowing to call a rest API doing predictions on tiles (taking and returning a base64-encoded PNG image).

/*
 * L.TileLayer.Infer, inspired by L.TileLayer.PixelFilter (https://github.com/GreenInfo-Network/L.TileLayer.PixelFilter/)
 */
L.tileLayerInfer = function (url, options) {
    return new L.TileLayer.Infer(url, options);
}

L.TileLayer.Infer = L.TileLayer.extend({
    // the constructor saves settings and throws a fit if settings are bad, as typical
    // then adds the all-important 'tileload' event handler which basically "detects" an unmodified tile and performs the pxiel-swap
    initialize: function (url, options) {
        L.TileLayer.prototype.initialize.call(this, url, options);
        // and add our tile-load event hook which triggers us to do the infer
        this.on('tileload', function (event) {
            this.inferTile(event.tile);
        });
    },

    // extend the _createTile function to add the .crossOrigin attribute, since loading tiles from a separate service is a pretty common need
    // and the Canvas is paranoid about cross-domain image data. see issue #5
    // this is really only for Leaflet 0.7; as of 1.0 L.TileLayer has a crossOrigin setting which we define as a layer option
    _createTile: function () {
        var tile = L.TileLayer.prototype._createTile.call(this);
        tile.crossOrigin = "Anonymous";
        return tile;
    },

    // the heavy lifting to do the pixel-swapping
    // called upon 'tileload' and passed the IMG element
    // tip: when the tile is saved back to the IMG element that counts as a tileload event too! thus an infinite loop, as wel as comparing the pixelCodes against already-replaced pixels!
    //      so, we tag the already-swapped tiles so we know when to quit
    // if the layer is redrawn, it's a new IMG element and that means it would not yet be tagged
    inferTile: function (imgelement) {
        // already processed, see note above
        if (imgelement.getAttribute('data-InferDone')) return;

        // copy the image data onto a canvas for manipulation
        var width  = imgelement.width;
        var height = imgelement.height;
        var canvas    = document.createElement("canvas");
        canvas.width  = width;
        canvas.height = height;
        var context = canvas.getContext("2d");
        context.drawImage(imgelement, 0, 0);

        // encode image to base64
        var uri = canvas.toDataURL('image/png');
        var b64 = uri.replace(/^data:image.+;base64,/, '');

        var options = this.options;

        // call to Rest API
        fetch('/api/predict', {
            method: 'POST',
            mode: 'no-cors',
            credentials: 'include',
            cache: 'no-cache',
            headers: {
              'Content-type': 'application/json',
              'Accept': 'application/json',
              'Access-Control-Allow-Origin': '*',
            },
            body: JSON.stringify({
              'image': [b64]
            })

          })
          .then((response) => response.json())
          .then((responseJson) => {
            // Perform success response.
            const obj = JSON.parse(responseJson);
            image = "data:image/png;base64," + obj["predictions"][0];
            var img = new Image();
            img.onload = function() {
              // draw retrieve image on tile (replace tile content)
              context.globalAlpha = options.opacity
              context.drawImage(img, 0, 0, canvas.width, canvas.height);
            }
            img.src = image;
            imgelement.setAttribute('data-InferDone', true);
            imgelement.src = image;

          })
          .catch((error) => {
            console.log(error)
          });
    }
});

这篇关于如何在TileLayer的图块上进行预处理,然后在Leaflet上显示它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆