mapbox高阶,结合threejs(threebox)实现立体三维飞线图

👨‍⚕️ 主页: gis分享者

👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍⚕️ 收录于专栏:mapbox 从入门到精通

文章目录

  • 一、🍀前言
    • [1.1 ☘️mapboxgl.Map 地图对象](#1.1 ☘️mapboxgl.Map 地图对象)
    • [1.2 ☘️mapboxgl.Map style属性](#1.2 ☘️mapboxgl.Map style属性)
    • [1.3 ☘️threebox Line静态对象](#1.3 ☘️threebox Line静态对象)
  • 二、🍀使用threebox,实现立体三维飞线图
    • [1. ☘️实现思路](#1. ☘️实现思路)
    • [2. ☘️代码样例](#2. ☘️代码样例)

一、🍀前言

本文详细介绍如何基于mapbox-gl v3.*.* 版本,结合threejs(threebox)实现立体三维飞线图,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️mapboxgl.Map 地图对象

mapboxgl.Map 地图对象。
构造函数:

new Map class(options: Object)
本例使用属性:

1.2 ☘️mapboxgl.Map style属性

本例使用属性:

  • version:版本号,当前固定值为8。
  • sources:数据源集合(必填,用于包含一系列数据源
    source,这些数据源提供了在地图上显示的数据)。值为{}对象。{}中的属性名是数据源的名称。
    每个数据源 source 有的属性:
    type:数据源类型
    tiles:数据源地址
    tileSize:数据源切片大小
  • layers:图层集合(必填,包含了一系列图层 layer,这些图层指定了如何渲染数据源提供的数据)
    每个layer的属性(当前示例用到的):
    id:图层id
    type:图层类型
    source:数据源名称

1.3 ☘️threebox Line静态对象

javascript 复制代码
tb.line(options);

在整个三维空间中向地图添加一条线。颜色渲染独立于场景照明。在内部,调用自定义线着色器。

option 是否必填 默认值 类型 说明
geometry NA lineGeometry 绘制线条的经纬度坐标数组
color black color 线条的颜色。与其他Threebox对象不同,无论场景照明如何,此颜色都将在屏幕上精确渲染
width 1 number 线条宽度。与其他Threebox对象不同,此宽度以显示像素为单位,而不是米或场景单位。
opacity 1 number 线的透明度

threebox_API

二、🍀使用threebox,实现立体三维飞线图

1. ☘️实现思路

  • 1、引入'mapbox-gl'、'mapbox-gl/dist/mapbox-gl.css'、'threebox-plugin'文件
  • 2、添加id为map的html页面要素,定义map样式。
  • 3、定义initMap初始化地图方法,方法内创建mapboxgl.Map地图对象map。map绑定'style.load'事件,在load回调事件内部,map添加自定义图层,自定义图层onAdd方法内实现三维飞线的添加,具体代码参考代码样例。在mounted钩子函数中调用initMap方法。

2. ☘️代码样例

html 复制代码
<template>
    <div id='map'></div>
</template>

<script>
/** 迁徙线 **/
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import { Threebox } from 'threebox-plugin'
export default {
  name: 'ThreeBoxMigrateLine',
  data () {
    return {
      map: null
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.initMap()
    })
  },
  methods: {
    initMap () {
      mapboxgl.accessToken = 'mapbox官网注册token'
      this.map = new mapboxgl.Map({
        container: 'map',
        zoom: 2,
        minZoom: 0,
        pitch: 45,
        center: [116.4, 39.9],
        style: 'mapbox://styles/mapbox/light-v10'
      })
      let self = this
      this.map.on('load', function () {
        let lines = self.getMigrateLineData()
        self.map.addLayer({
          id: 'custom_layer',
          type: 'custom',
          renderingMode: '3d',
          onAdd: function (map, mbxContext) {
            window.tb = new Threebox(
              map,
              mbxContext,
              {defaultLights: true}
            )

            for (let line of lines) {
              var lineOptions = {
                geometry: line,
                color: (line[1][1] / 180) * 0xffffff, 
                width: Math.random() + 1
              }
              let lineMesh = window.tb.line(lineOptions)

              window.tb.add(lineMesh)
            }

          },
          render: function () {
            window.tb.update()
          }
        })
      })
    },
    getMigrateLineData () {
      var lines = new Array()
      // 25个坐标过渡点
      var arcSegments = 25
      // 50条飞线
      var lineQuantity = 50

      for (var i = 0; i < lineQuantity; i++) {

        var line = new Array()
        // 目标点坐标
        var destination = [300 * (Math.random() - 0.5), 140 * (Math.random() - 0.5)]
        // 最大高度
        var maxElevation = Math.pow(Math.abs(destination[0] * destination[1]), 0.5) * 80000

        var increment = destination.map(function (direction) {
          return direction / arcSegments
        })

        for (var l = 0; l <= arcSegments; l++) {
          var waypoint = []
          if (l === 0) {
          	// 飞线起点坐标
            waypoint = [116.4, 39.9]
            // waypoint = [0, 0]
          } else {
            waypoint = increment.map(function (direction) {
              return direction * l
            })
            waypoint = [waypoint[0] + 116.4, waypoint[1] + 39.9]
          }

          var waypointElevation = Math.sin(Math.PI * l / arcSegments) * maxElevation

          waypoint.push(waypointElevation)
          line.push(waypoint)
        }

        lines.push(line)
      }
      return lines
    }
  }
}
</script>

<style scoped>
#map{
    height: 100vh;
    width: 100vw;
}
</style>

效果如下:

相关推荐
青铜弟弟13 天前
无人机倾斜摄影农田航线规划
无人机·倾斜摄影·三维
allenjiao1 个月前
Cesium粒子系统模拟风场动态效果
javascript·arcgis·gis·webgl·cesium·三维·风场
新中地GIS开发老师1 个月前
2025Mapbox零基础入门教程(14)定位功能
前端·javascript·arcgis·gis·mapbox·gis开发·地理信息科学
GISHUB6 个月前
mapbox开发小技巧
前端·mapbox
gis分享者6 个月前
学习threejs,使用LineBasicMaterial基础线材质
threejs·line·basicmaterial·线材质·gosper·高斯帕曲线
Tumiz7 个月前
尝试一下,交互式的三维计算python库,py3d
python·3d·数据可视化·旋转·三维
小野猫子8 个月前
mapbox加载geojson,鼠标移入改变颜色,设置样式以及vue中的使用
gis·mapbox
陟彼高冈yu9 个月前
2-4位置服务示例
android·android studio·mapbox·mapbox sdk
GOTXX9 个月前
三维场景重建3D高斯点渲染复现
人工智能·python·机器学习·数学建模·3d·统一建模语言·三维