threejs绘制3d中国地图

threejs yekong

threejs绘制3d中国地图

在Three.js中绘制中国地图,通常有两种方法:一种是使用Three.js直接根据地理坐标绘制,另一种是结合其他库(如Echarts)来实现。以下是基于Three.js直接绘制中国地图的基本步骤:

  1. 获取地图数据:首先,你需要获取中国地图的地理坐标数据。这些数据通常以GeoJSON格式提供,包含了中国各省市边界的经纬度信息。
  2. 转换坐标:由于GeoJSON中的坐标是经纬度格式,而Three.js使用的是笛卡尔坐标系,因此需要将经纬度转换为Three.js可以使用的坐标。
  3. 绘制地图:使用转换后的坐标在Three.js中绘制地图。这可以通过创建多边形几何体(THREE.ShapeGeometry)来实现,每个省份可以是一个多边形几何体。
  4. 添加细节:为了提高地图的可视化效果,可以添加光照、材质和阴影等细节。

three和vue版本

"three": "^0.154.0",
"vue": "^3.2.45",

实例代码

<script>
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import data from './data/data.json';
import {borderLine} from './js/line.js';
import {getBoxCenter, getBoxSize} from './js/centerCamera.js';
import {ExtrudeMesh} from './js/ExtrudeMesh.js';
import {createLights} from './js/lights.js';
import {destroyMap} from './js/destroyMap.js';

let mapHeight = 1;
let TensileHeight = 3;
let mapGroup = null;
let lineGroup = null;
let meshGroup = null;
let renderer = null;
let scene = null;
let camera = null;
let resizeObserver = null;
export default {
  name: 'map3D',
  data() {
    return {};
  },
  mounted() {
    this.initScene();
    this.drawMap();
    this.handleResize();

    const viewElem = document.body;
    this.resizeObserver = new ResizeObserver(() => {
      setTimeout(() => {
        this.handleResize();
      }, 300);
    });
    this.resizeObserver.observe(viewElem);
  },
  beforeDestroy() {
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    destroyMap(scene, renderer);
  },
  methods: {
    handleResize() {
      const width = this.$refs.map3DMain.offsetWidth;
      const height = this.$refs.map3DMain.offsetHeight;
      if (renderer) {
        renderer.setSize(width, height);
      }
    },
    initScene() {
      scene = new THREE.Scene();
      mapGroup = new THREE.Group();
      lineGroup = new THREE.Group();
      meshGroup = new THREE.Group();
      renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true,
      });
      // 其他初始化代码保持不变
    },
    drawMap() {
      const width = this.$refs.map3DMain.offsetWidth; // 使用 this.$refs 来访问 ref
      const height = this.$refs.map3DMain.offsetHeight;

      // 使用 this 来引用 data 中的属性
      const lights = createLights();
      scene.add(lights.directionalLight);
      scene.add(lights.directionalLight2);
      scene.add(lights.ambient);

      scene.add(mapGroup);
      mapGroup.add(lineGroup);
      mapGroup.add(meshGroup);
      data.features.forEach((area) => {
        if (area.geometry.type === 'Polygon') {
          area.geometry.coordinates = [area.geometry.coordinates];
        }
        lineGroup.add(borderLine(area.geometry.coordinates));
        const mesh = ExtrudeMesh(area.geometry.coordinates, TensileHeight);
        meshGroup.add(mesh);
      });

      const lineGroup2 = lineGroup.clone();
      mapGroup.add(lineGroup2);
      lineGroup2.position.z = TensileHeight + TensileHeight * 0.001;

      const k = width / height;
      let s = (getBoxSize(mapGroup).x + getBoxSize(mapGroup).y) / 4;
      camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(104, -105, 200);
      camera.lookAt(scene.position);

      renderer.setClearColor(0x000000, 0);
      renderer.setSize(width, height);

      const render = () => {
        renderer.render(scene, camera);
        requestAnimationFrame(render);
      }

      render();

      const controls = new OrbitControls(camera, renderer.domElement);
      const getBoxCenterData = getBoxCenter(mapGroup);
      controls.target.set(getBoxCenterData.x, getBoxCenterData.y, 0);
      controls.update();

      this.$refs.map3DMain.appendChild(renderer.domElement);
    }
  },
};
</script>

演示地址

threejs绘制3d中国地图

完整实例代码

代码环境 vue3 + vite + js + nodejs 16

vue3框架vue2写法

相关文件下载地址
此资源需支付 ¥1 后下载
支付宝购买扫右侧红包码购买更优惠,如无法下载请联系微信:17331886870
喜欢
threejs绘制3d中国地图