Skip to content
目录

ImageLayer

ImageLayer是用来添加和管理图片资源的,有时我们需要将一些静态图片整体的添加到地图上,这时ImageLayer就派上用场了,ImageLayer的使用方式就是不断的:

  • 添加到地图
  • 从地图上移除
  • 不断设置其图片集合(setImages),
  • 清空图片资源(clear)

加载时序图片

ImageLayer 常规的使用方式是:

js
layer.setImages({
    url,
    extent,
});

当我们使用url图片时因为内部要请求图片这个过程是需要时间的,所以当用户不断的的setImages时就会出现闪烁的效果

怎样解决这个问题呢?

  • 在重新设置图片资源前,我们可以先把图片加载完,然后在设置ImageLayer的数据
  • ImageLayer的图片资源不仅仅支持url,也支持ImageBitMap的
  • ImageBitMap是纯内存的,复制速度非常快的就可以避免引擎加载图片时空出的白屏时间了

WARNING

maptalks version 1.1.2版本才支持该特性

简单的时序图例子

js
const max = 6;
let idx = 1;
let imageLoading = false;

function loadImage() {
    if (imageLoading) {
        return;
    }
    imageLoading = true;
    const image = new Image();
    image.onload = () => {
        createImageBitmap(image).then((bitImage) => {
            console.log(image);
            idx++;
            if (idx > max) {
                idx = 1;
            }
            imageLoading = false;
            layer.setImages({
                url: bitImage,
                extent,
            });
        });
    };
    image.src = `./../assets/image/wendu/${idx}.png`;
}

const now = maptalks.Util.now;
let time = now();

function animation() {
    const t = now();
    if (t - time >= 2000) {
        loadImage();
        time = t;
    }
    requestAnimationFrame(animation);
}

requestAnimationFrame(animation);
loadImage();

加载大图片

一般业务里在前端我们是不会加载大的图片的(几十甚至百兆的),如果你一定要加载

由于浏览器底层限制(canvas/webgl等)的原因加载大尺寸的图片会报错的

这时我们需要将大图片进行切割的,社区插件maptalks.tileclip提供了图片切割功能

返回的图片集合是ImageBitMap

  • ImageBitMap纯内存的,不管是数据的复制和渲染性能更好
  • maptalks内部也支持ImageBitMap作为数据源的

具体操作:

  • 利用 maptalks.tileclip 切割图片
  • 计算切割的子图片集合的包围盒
  • 将子图片的数据加入 ResourceProxy 资源管理工具
  • 批量设置ImageLayer的数据集合
js
const bbox = [120, 31, 121, 32];

const layer = new maptalks.VectorLayer("layer").addTo(map);

const extent = new maptalks.Extent(bbox);

const polygon = new maptalks.Polygon(extent.toArray()).addTo(layer);

const imagelayer = new maptalks.ImageLayer("imagelayer", {}).addTo(map);

const prefix = `temp_${imagelayer.getId()}_`;

//清除每次的临时图片资源
function clearCache() {
    const caches = maptalks.ResourceProxy.allResource();
    const keys = Object.keys(caches).filter((key) => {
        return key.includes(prefix);
    });
    keys.forEach((key) => {
        const image = maptalks.ResourceProxy.getResource(key);
        if (image && image.close) {
            image.close();
        }
        maptalks.ResourceProxy.removeResource(key);
    });
}
//图片加入资源管理工具
function addCache(key, image) {
    // const { row, col } = item;
    maptalks.ResourceProxy.addResource(key, image);
}

function setImages(result) {
    clearCache();
    const { width, height, items } = result;
    const [minx, miny, maxx, maxy] = bbox;
    const ax = (maxx - minx) / width;
    const ay = (maxy - miny) / height;
    items.forEach((item) => {
        const { x, y, width, height, image } = item;
        const x1 = minx + x * ax;
        const x2 = x1 + width * ax;
        const y2 = maxy - y * ay;
        const y1 = y2 - ay * height;
        //计算每个小图片的包围盒范围
        item.bbox = [x1, y1, x2, y2];
    });
    const images = items.map((item) => {
        // console.log(item.image);
        const id = maptalks.Util.GUID();
        const key = `${prefix}${id}`;
        addCache(key, item.image);
        return {
            //表示从资源池里取资源
            url: `$${key}`,
            extent: item.bbox,
        };
    });
    imagelayer.setImages(images);
}

let fileUrl;

function readImage() {
    if (!fileUrl) {
        return;
    }
    console.log("readimage ing");
    tileActor
        .imageSlicing({
            url: fileUrl,
            // returnBlobURL: true,
            debug: true,
            // filter: 'sepia(100%) invert(90%)'
        })
        .then((result) => {
            console.log(result);
            setImages(result);
            URL.revokeObjectURL(fileUrl);
            console.log("readimage end");
        })
        .catch((error) => {
            console.error(error);
            URL.revokeObjectURL(fileUrl);
        });
}

具体的例子

maptalks教程 document auto generated by mdpress and vitepress