ImageLayer
ImageLayer是用来添加和管理图片资源的,有时我们需要将一些静态图片整体的添加到地图上,这时ImageLayer就派上用场了,ImageLayer的使用方式就是不断的:
- 添加到地图
- 从地图上移除
- 不断设置其图片集合(setImages),
- 清空图片资源(clear)
加载大图片
一般业务里在前端我们是不会加载大的图片的(几十甚至百兆的),如果你一定要加载
由于浏览器底层限制(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);
});
}