Skip to content
目录

实现高亮的道路效果

本例子里使用了maptalks.three插件里的ThreeLayer.

准备对应的数据

  • 准备建筑物的geojson数据,注意每个建筑物应该携带自身的高度数据
  • 准备道路的geojson数据,例子的道路数据携带了高度数据了,如果你的效果不要求三维效果,可以无需携带高度数据。

道路数据携带高度如下格式:

json
"coordinates": [
                    [
                        120.5901478287473,
                        31.277654711461373,
                        12
                    ],
                    [
                        120.59063275011565,
                        31.27719233895469,
                        12
                    ],
					...

			  ]

准备对应的纹理图片

例子里主要的贴图有建筑物图片和道路流动效果的贴图

  • 建筑贴图

  • 道路纹理

自己请根据业务需要准备对应的图片,这里的图片均来自互联网作为测试使用

加载建筑物

准备建筑物的材质

js
const material = new THREE.MeshPhongMaterial({ color: "#fff" });

const textureLoader = new THREE.TextureLoader();
textureLoader.load(
    "./../assets/image/building-texture-dark2.jpg",
    (texture) => {
        texture.needsUpdate = true; //使用贴图时进行更新
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
        // texture.repeat.set(0.002, 0.002);
        texture.repeat.set(1, 1);
        material.map = texture;
        material.needsUpdate = true;
    },
);

加载建筑物

js
function addBuildings() {
    fetch("../assets/data/buildingsfilter-test.geojson")
        .then((res) => res.json())
        .then((geojson) => {
            const polygons = maptalks.GeoJSON.toGeometry(geojson);
            const extrudePolygons = polygons.map((p) => {
                const height = p.getProperties().height;
                const extrudePolygon = threeLayer.toExtrudePolygon(
                    p,
                    { height, topColor: "#fff", asynchronous: true },
                    material,
                );
                return extrudePolygon;
            });
            threeLayer.addMesh(extrudePolygons);
        });
}

加载道路

准备道路的材质

js
const highMaterial = new THREE.MeshBasicMaterial({
    color: "#fff",
    transparent: true,
});
textureLoader.load("./../assets/image/path_007_21.png", (texture) => {
    texture.needsUpdate = true; //使用贴图时进行更新
    texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
    // texture.repeat.set(0.002, 0.002);
    texture.repeat.set(0.01, 1);
    highMaterial.map = texture;
    highMaterial.needsUpdate = true;
});

加载道路的数据

js
function addPaths(polygons) {
    fetch("../assets/data/briges.geojson")
        .then((res) => res.json())
        .then((geojson) => {
            geojson.features = geojson.features.filter((f) => {
                return f.geometry.type.includes("LineString");
            });
            const lines = maptalks.GeoJSON.toGeometry(geojson);
            const paths = lines.map((p) => {
                const path = threeLayer.toPath(
                    p,
                    { width: 6, bloom: true },
                    highMaterial,
                );
                return path;
            });
            threeLayer.addMesh(paths);
        });
}

开启高亮效果

  • 首先开启地图的后处理功能,这是个全局性的功能,maptalks里后处理有GroupGLLayer实现的,配置下其配置项即可
js
const sceneConfig = {
    postProcess: {
        enable: true,
        antialias: { enable: true },
        //bloom effect
        bloom: {
            enable: true,
            threshold: 0,
            factor: 1,
            radius: 0.02,
        },
    },
};
const groupLayer = new maptalks.GroupGLLayer("group", [threeLayer], {
    sceneConfig,
});
groupLayer.addTo(map);
  • 道路开启bloom选项,bloom开启表示其将被全局的bloom作用
js
const paths = lines.map((p) => {
    const path = threeLayer.toPath(p, { width: 6, bloom: true }, highMaterial);
    return path;
});

开启纹理动画

  • 纹理动画我们一般通过设置 材质的的纹理的偏移量来实现
js
function animation() {
    // layer animation support Skipping frames
    threeLayer._needsUpdate = !threeLayer._needsUpdate;
    if (threeLayer._needsUpdate) {
        threeLayer.redraw();
    }
    //set material map offset
    if (highMaterial.map) {
        highMaterial.map.offset.x -= 0.002;
    }
    requestAnimationFrame(animation);
}

This document is generated by mdpress