threejs 渲染geoJson数据绘制世界地图 学习笔记

threejs yekong

使用threejs加载geoJson数据绘制渲染地图
threejs 渲染geoJson数据绘制世界地图 学习笔记

<template>
  <div class="homebody">
    <div class="canvasGLTFBody">
      <div ref='canvasGLTF' class="canvasGLTF">
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
// 引入Three.js扩展库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import worldData from '@/data/world.json'

export default {
  name: 'GLTFCanvas',
  data () {
    return {
      list: []
    }
  },
  created: function () {

  },
  mounted: function () {
    var that = this
    /**
     * 创建场景对象Scene
     */
    var scene = new THREE.Scene()
    //three.js文件加载类FileLoader:封装了XMLHttpRequest
    var loader = new THREE.FileLoader()
    loader.setResponseType('json')
    // 组对象mapGroup是所有国家边界Line模型的父对象
    var mapGroup = new THREE.Group()
    scene.add(mapGroup)
    // 异步加载包含世界各个国家边界坐标的GeoJSON文件:world.json
    loader.load('data/world.json', function (data) {
      // 访问所有国家边界坐标数据:data.features
      data.features.forEach(function (area) {
        // "Polygon":国家area有一个封闭轮廓
        if (area.geometry.type === 'Polygon') {
          var pointArr = []//边界线顶点坐标
          area.geometry.coordinates[0].forEach(elem => {
            // z坐标设置为0.这样地图轮廓位于XOY平面上
            pointArr.push(elem[0], elem[1], 0)
          })
          mapGroup.add(closedLoop(pointArr))//国家边界轮廓插入组对象mapGroup
          //"MultiPolygon":国家area有多个封闭轮廓
        } else if (area.geometry.type === 'MultiPolygon') {
          // 解析所有封闭轮廓边界坐标area.geometry.coordinates
          area.geometry.coordinates.forEach(polygon => {
            var pointArr = []//边界线顶点坐标
            polygon[0].forEach(elem => {
              pointArr.push(elem[0], elem[1], 0)
            })
            mapGroup.add(closedLoop(pointArr))//国家边界轮廓插入组对象mapGroup
          })
        }
      })
    })

    // pointArr:行政区一个多边形轮廓边界坐标(2个元素为一组,分别表示一个顶点x、y值)
    function closedLoop (pointArr) {
      /**
       * 通过BufferGeometry构建一个几何体,传入顶点数据
       * 通过Line模型渲染几何体,连点成线
       * LineLoop和Line功能一样,区别在于首尾顶点相连,轮廓闭合
       */
      var geometry = new THREE.BufferGeometry() //创建一个Buffer类型几何体对象
      //类型数组创建顶点数据
      var vertices = new Float32Array(pointArr)
      // 创建属性缓冲区对象
      var attribue = new THREE.BufferAttribute(vertices, 3) //3个为一组,表示一个顶点的xyz坐标
      // 设置几何体attributes属性的位置属性
      geometry.attributes.position = attribue
      // 线条渲染几何体顶点数据
      var material = new THREE.LineBasicMaterial({
        color: 0x00ffff //线条颜色
      })//材质对象
      // var line = new THREE.Line(geometry, material);//线条模型对象
      var line = new THREE.LineLoop(geometry, material)//首尾顶点连线,轮廓闭合
      return line
    }

    //three.js辅助坐标系
    var axesHelper = new THREE.AxesHelper(300)
    scene.add(axesHelper)
    /**
     * 相机设置
     */
    var width = window.innerWidth //窗口宽度
    var height = window.innerHeight //窗口高度
    var k = width / height //窗口宽高比
    var s = 200 //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000)
    camera.position.set(200, 300, 200) //设置相机位置
    camera.lookAt(scene.position) //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    var renderer = new THREE.WebGLRenderer()
    renderer.setSize(width, height) //设置渲染区域尺寸
    // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色

    // 渲染函数
    function render () {
      renderer.render(scene, camera) //执行渲染操作
      requestAnimationFrame(render) //请求再次执行渲染函数render,渲染下一帧
    }

    render()
    //创建控件对象  控件可以监听鼠标的变化,改变相机对象的属性
    // 旋转、缩放用于代码调试

    var controls = new OrbitControls(camera, renderer.domElement)
    that.$refs.canvasGLTF.appendChild(renderer.domElement)

  },
  methods: {}
}
</script>

<style lang="scss" scoped>
.homebody {
  width: 100%;
  height: 100%;
  position: fixed;
  background: #0f1633;
  //position: relative;

  .pageMain {
    position: relative;
    width: calc(100% - 60px - 60px);
    margin: 0 auto;
    height: calc(100% - 108px - 150px);
  }
}
</style>

使用其他地图

使用其他地图,比如河北地图
使用其他地图

教程地址

教程地址

喜欢