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>

效果如下:

相关推荐
GISHUB1 个月前
mapbox开发小技巧
前端·mapbox
gis分享者1 个月前
学习threejs,使用LineBasicMaterial基础线材质
threejs·line·basicmaterial·线材质·gosper·高斯帕曲线
Tumiz2 个月前
尝试一下,交互式的三维计算python库,py3d
python·3d·数据可视化·旋转·三维
小野猫子2 个月前
mapbox加载geojson,鼠标移入改变颜色,设置样式以及vue中的使用
gis·mapbox
陟彼高冈yu4 个月前
2-4位置服务示例
android·android studio·mapbox·mapbox sdk
GOTXX4 个月前
三维场景重建3D高斯点渲染复现
人工智能·python·机器学习·数学建模·3d·统一建模语言·三维
Ian10254 个月前
《Learn Three.js》学习(3)光源
前端·javascript·学习·webgl·图形学·三维·三维光源
duansamve5 个月前
WebGIS地图框架有哪些?
javascript·gis·openlayers·cesium·mapbox·leaflet·webgis
xiangshangdemayi5 个月前
vue3环境下mapbox本地部署极速入门
部署·矢量切片·mapbox·内网·离线·天地图