Skip to content
目录

行政区拔高并叠盖TileLayer图层

功能描述

  • 行政区拔高
  • 行政区上面叠加一个剪裁后的TileLayer图层
  • 上面再叠盖个区域的轮廓的光线

难点分析

maptalks 当前是支持TileLayer剪裁的,底层用的canvas clip方法,但是当把TileLayer放到GroupGLLayer图层里 会变成webgl渲染导致剪裁失效

好在社区有maptalks瓦片处理插件 maptalks.tileclip 可以让对每个瓦片进行剪裁且这个过程是在worker里完成的不会有性能问题的,且比maptalks自带的剪裁功能更加 通用

数据准备

这里我们以北京的行政区为例

  • 准备行政区外围轮廓的GeoJSON数据,数据来源 datav geo
  • 准备北京市各个区域的GeoJSON数据,数据来源 datav geo

具体操作

  • 行政区拔高

这个你可以使用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);
        });
}

This document is generated by mdpress