瓦片图层高亮区域
实现如下的效果:
实现如下方法主要方法有:
- 利用矢量数据进行挖洞,在全球的数据中挖去对应的区域数据,因为要渲染矢量数据性能可能要差点
- 利用两个TileLayer,下面的进行简单的黑色处理,上面的进行mask(TileLayer.setMask()),因为两个TileLayer性能可能要差点
- 只用一个TileLayer来实现,性能最好
下面我来介绍下方法3具体实现:
这里我们会用到 瓦片处理插件 maptalks.tileclip
步骤
- 拦截默认的瓦片请求
- 请求瓦片
- 复制瓦片并剪裁
- 对原始的瓦片进行黑色的处理
- 合并黑色的瓦片和剪裁的瓦片
拦截和请求瓦片
拦截默认的瓦片请求
js
tileLayer.on("renderercreate", function (e) {
//load tile image
// img(Image): an Image object
// url(String): the url of the tile
e.renderer.loadTileBitmap = function (url, tile, callback) {
//get Tile data
tileActor
.getTile({
url: maptalks.Util.getAbsoluteURL(url),
// filter: 'sepia(100%) invert(90%)'
})
.then((imagebitmap) => {})
.catch((error) => {
//do some things
console.error(error);
});
};
});
剪裁瓦片
因为瓦片还要进行蒙层处理,所以我们copy一份Image,原始的瓦片保留着
js
tileLayer.on("renderercreate", function (e) {
//load tile image
// img(Image): an Image object
// url(String): the url of the tile
e.renderer.loadTileBitmap = function (url, tile, callback) {
//get Tile data
tileActor
.getTile({
url: maptalks.Util.getAbsoluteURL(url),
// filter: 'sepia(100%) invert(90%)'
})
.then((imagebitmap) => {
copyImage(imagebitmap)
.then((copyImage) => {
//clip tile
tileActor
.clipTile({
tile: copyImage,
tileBBOX: tileLayer._getTileBBox(tile),
projection: tileLayer.getProjection().code,
tileSize: tileLayer.getTileSize().width,
maskId,
})
.then((clipImage) => {})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
};
});
原始瓦片进行蒙层处理
js
function copyImage(image) {
return createImageBitmap(image);
}
const canvas = new OffscreenCanvas(1, 1);
function maskTile(image) {
const { width, height } = image;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, width, height);
ctx.filter = "grayscale(1.2)";
ctx.drawImage(image, 0, 0);
ctx.fillStyle = "rgba(0,0,0,0.7)";
ctx.fillRect(0, 0, width, height);
return canvas.transferToImageBitmap();
}
合并黑色的瓦片和剪裁的瓦片
js
tileLayer.on("renderercreate", function (e) {
//load tile image
// img(Image): an Image object
// url(String): the url of the tile
e.renderer.loadTileBitmap = function (url, tile, callback) {
//get Tile data
tileActor
.getTile({
url: maptalks.Util.getAbsoluteURL(url),
// filter: 'sepia(100%) invert(90%)'
})
.then((imagebitmap) => {
copyImage(imagebitmap)
.then((copyImage) => {
//clip tile
tileActor
.clipTile({
tile: copyImage,
tileBBOX: tileLayer._getTileBBox(tile),
projection: tileLayer.getProjection().code,
tileSize: tileLayer.getTileSize().width,
maskId,
})
.then((clipImage) => {
tileActor
.getTile({
url: [maskTile(imagebitmap), clipImage],
// filter: 'sepia(100%) invert(90%)'
})
.then((mergeImage) => {
callback(mergeImage);
})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
};
});
边框效果
这个比较简单的,加载矢量数据并配置对应的样式即可,不具体介绍了