Three.js绘制多边形 - 四川省级行政区边界线

在阿里云DataV数据可视化平台可获取到行政区域边界数据,从中截取需要的数组,获取数据后结合Three.js,可绘制出四川省的行政区边界线,如下:

script

import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

// 创建场景
const scene = new THREE.Scene()

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角 指垂直方向为45度
  window.innerWidth / window.innerHeight, // 相机宽高比
  0.1,
  1000,
)

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true })
// 设置渲染器的size
renderer.setSize(window.innerWidth, window.innerHeight)
// 适配高清屏幕
renderer.setPixelRatio(window.devicePixelRatio)
// 将渲染器添加到body上
document.body.appendChild(renderer.domElement)

// 创建线段
const geometry = new THREE.BufferGeometry()
const vertices = new Float32Array(array2) // array2的数据由下方数据处理输出
// 创建顶点属性
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
// 设置材质
const material = new THREE.LineBasicMaterial({ color: 0x0000ff })
const line = new THREE.Line(geometry, material)
line.position.set(-103, -30, 0) // 设置绘制地图居中
// 将绘制线段添加到场景中
scene.add(line)

// 设置相机位置
camera.position.z = 15;
camera.lookAt(0, 0, 0)

// 添加世界坐标辅助器
const axesHelper = new THREE.AxesHelper(300) // 设置线段长度
scene.add(axesHelper)

// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement)

function animate() {
  // 每次渲染都需要更新轨道控制器
  controls.update()
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
}
animate()

window.addEventListener('resize', () => {
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  // 更新相机投影矩阵
  camera.updateProjectionMatrix()
})

array2数据的来源:
1、从阿里云DataV数据可视化平台可获取到的行政区域边界数据是一个多维数组,按照Three.js中BufferGeometry的参数需求需要处理成一个一维数组。
代码如下:

const array0 = [[[],[],[]]] // 从阿里云获取的数据
const array1 = array0.flat(Infinity) // 处理为一维数组

2、此时一个点只有X,Y轴有坐标位置,图示是将线段集绘制在Z轴为0的平面上,所以需要再添加Z轴的坐标为0。
代码如下:

function insertFixedValueSimple(arr, fixedVal) {
  return arr.reduce((acc, curr, index) => {
    acc.push(curr)
    // 每 2 个元素后插入
    if ((index + 1) % 2 === 0) {
      acc.push(fixedVal)
    }
    return acc
  }, [])
}
const array2 = insertFixedValueSimple(array1, 0)

以上。

posted @ 2025-12-04 16:16  显示昵称已被使用#  阅读(0)  评论(0)    收藏  举报