mapbox+babylon加载三维面

  1.引入相关依赖,构建mapbox地图场景

import mapboxgl from 'mapbox-gl';
import {onMounted} from "vue";
import * as BABYLON from 'babylonjs';

mapboxgl.accessToken = 'pk.eyJ1Ijoibm9haDk3MTMiLCJhIjoiY2p4aXppNXZoMTc4YTN5bzhzMWY0emw3cyJ9.7GhaVOSALR-DwV5Lpn_h4Q';

const map = new mapboxgl.Map({
    container: 'mapContainer',
    style: 'mapbox://styles/mapbox/streets-v11',
    zoom: 18,
    center: [120, 31],
    pitch: 60,
    antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});

2.根据CustomLayerInterface定义一个BabylonLayer

class BabylonLayer implements CustomLayerInterface {
    readonly id: string;
    readonly type: 'custom' = 'custom';
    readonly renderingMode: '3d' = '3d';

    private map: Map | undefined;
    private scene: BABYLON.Scene | undefined;
    private camera: BABYLON.Camera | undefined;

    constructor(id: string) {
        this.id = id;
    }

    onAdd = (map: Map, gl: WebGLRenderingContext) => {
        this.map = map;
        const engine = new BABYLON.Engine(gl, true, {
            useHighPrecisionMatrix: true
        }, true);

        this.scene = new BABYLON.Scene(engine);
        this.scene.autoClear = false;
        this.scene.detachControl();
        this.scene.beforeRender = function () {
            engine.wipeCaches(true);
        };
        this.scene.ambientColor = new BABYLON.Color3(1, 1, 1);
        this.camera = new BABYLON.Camera("mapbox-camera", new BABYLON.Vector3(), this.scene);
        const light = new BABYLON.HemisphericLight("mapbox-light", new BABYLON.Vector3(0.5, 0.5, 4000), this.scene);

        const points: Array<[number, number, number]> = [
            [120, 31.3, 0],
            [120.2, 31.2, 2000],
            [120.2, 31.1, 4000],
            [120.3, 31.0, 4000],
            [120, 31.1, 8000],
            [120, 31.3, 0]
        ];
        createRibbonPolygon(points, this.scene);
    }

    render = (gl: WebGLRenderingContext, matrix: number[]) => {
        const cameraMatrix = BABYLON.Matrix.FromArray(matrix);
        this.camera!.freezeProjectionMatrix(cameraMatrix);
        this.scene!.render(false);
        this.map!.triggerRepaint();
    }
}

3.定义创建多边形的方法

function createRibbonPolygon(points: Array<[number, number, number]>, scene: BABYLON.Scene) {
    const pathPoints = points.map((p) => {
        const mercatorCoord = mapboxgl.MercatorCoordinate.fromLngLat([p[0], p[1]], p[2]);
        // 将经纬度x,y转换成babylon的坐标
        return new BABYLON.Vector3(mercatorCoord.y, mercatorCoord.z, mercatorCoord.x);
    });
    const halfCount = Math.floor(pathPoints.length / 2)
    const path0 = pathPoints.slice(0, halfCount)
    const path1 = pathPoints.slice(halfCount).reverse()
    // 构建ribbonMesh需要相同长度的数组
    if (pathPoints.length % 2 === 1) path1.shift()

    const ribbonMesh = BABYLON.MeshBuilder.CreateRibbon('ribbon-polygon', {
        pathArray: [path0, path1],
        // sideOrientation: BABYLON.Mesh.DOUBLESIDE 若设置这个双面都是黑色,材质不生效
    }, scene);
    // 定义材质
    let myMaterial = new BABYLON.StandardMaterial("myMaterial", scene);
    // 设置漫反射颜色为红色
    myMaterial.diffuseColor = new BABYLON.Color3(1, 0, 0);
    // 给 ribbonMesh 设置材质
    ribbonMesh.material = myMaterial;
    // 设置 myMaterial 成为双面材质
    myMaterial.backFaceCulling = false;
    // 旋转到xy的平面
    ribbonMesh.rotateAround(BABYLON.Vector3.Zero(), new BABYLON.Vector3(1, 0, 0), Math.PI / 2)
        .rotateAround(BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, 1), Math.PI / 2);
}

4.添加BabylonLayer至mapbox场景

    map.on('style.load', () => {
        const babylonLayer = new BabylonLayer('babylon-layer');
        map.addLayer(babylonLayer);
    });

实现效果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mapbox是一个开源的地图平台,可以用来创建交互式地图应用程序。而百度地图是中国最大的在线地图服务提供商之一。如果你想在Mapbox百度地图,可以使用自定义图层的方式来实现。 以下是一种使用Mapbox百度地图的方法: 1. 首先,确保你已经安装了Mapbox的最新版本,因为老版本的Mapbox可能不支持自定义图层功能。 2. 在Mapbox中创建一个地图容器,并设置好地图的样式和初始视图。 3. 使用Mapbox的自定义图层功能,将百度地图的切片作为图层添到地图中。你可以使用Mapbox的TileLayer类来百度地图的切片。 4. 在百度地图切片时,需要注意百度地图的坐标系与Mapbox的坐标系不同。你可以使用网上找到的js库来解决坐标偏移的问题。 下面是一个示例代码,演示了如何在Mapbox百度地图: ```javascript // 创建地图容器 var map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11', center: [116.404, 39.915], zoom: 12 }); // 添百度地图切片图层 var baiduLayer = new mapboxgl.TileLayer({ source: { type: 'raster', tiles: [ 'http://online1.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1', 'http://online2.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1', 'http://online3.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1', 'http://online4.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1' ], tileSize: 256 } }); // 添图层到地图中 map.addLayer(baiduLayer); ``` 请注意,以上代码仅为示例,实际使用时需要根据你的具体需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值