行政区拔高并叠盖TileLayer图层
功能描述
- 行政区拔高
- 行政区上面叠加一个剪裁后的TileLayer图层
- 上面再叠盖个区域的轮廓的光线
难点分析
maptalks 当前是支持TileLayer剪裁的,底层用的canvas clip方法,但是当把TileLayer放到GroupGLLayer图层里 会变成webgl渲染导致剪裁失效
好在社区有maptalks瓦片处理插件 maptalks.tileclip 可以让对每个瓦片进行剪裁且这个过程是在worker里完成的不会有性能问题的,且比maptalks自带的剪裁功能更加 通用
数据准备
这里我们以北京的行政区为例
具体操作
- 行政区拔高
这个你可以使用maptalks的ExtrudePolygonLayer,矢量切片,或者three插件等,这里我使用了three插件了
js
function addAreas() {
const polygons = maptalks.GeoJSON.toGeometry(areaGeoJSON);
const extrudePolygons = polygons.map((p, index) => {
const id = maptalks.Util.GUID();
const extrudePolygon = threeLayer.toExtrudePolygon(
p,
{
height,
topColor: "#fff",
asynchronous: true,
altitude,
maxZoom: 12,
},
material,
);
// extrudePolygon.on('mouseover', polygonUp);
// extrudePolygon.on('mouseout', polygonDown);
extrudePolygon.setId(id);
return extrudePolygon;
});
threeLayer.addMesh(extrudePolygons);
}
WARNING
注意为了不抬高地图的整个水平线,我们把拔高的行政区海拔设置了负的了,这样方便其他的图层数据的叠加,如果 是抬高TileLayer这样就会导致其他的业务图层也得抬高,会让整个逻辑变得复杂
- 加载TileLayer并剪裁
js
const tileLayer = new maptalks.TileLayer("base", {
urlTemplate:
"https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
// urlTemplate: "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
// urlTemplate: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
subdomains: ["a", "b", "c", "d"],
});
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) => {
//clip tile
tileActor
.clipTile({
tile: imagebitmap,
tileBBOX: tileLayer._getTileBBox(tile),
projection: tileLayer.getProjection().code,
tileSize: tileLayer.getTileSize().width,
maskId,
})
.then((image) => {
callback(image);
})
.catch((error) => {
//do some things
console.error(error);
});
})
.catch((error) => {
//do some things
console.error(error);
});
};
});
具体的请参考 maptalks.tileclip插件的官方文档
- 叠加子区域的轮廓线
这个比较简单了使用简单的VectorLayer就可以了
js
function addSubAreas() {
fetch("./../assets/data/beijingarea.json")
.then((res) => res.json())
.then((geojson) => {
const polygons = maptalks.GeoJSON.toGeometry(geojson, (geo) => {
geo.setSymbol({ ...subAreaSymbol });
});
layer.addGeometry(polygons);
});
}