three.js开发3D地图记录(一)

该文章已生成可运行项目,

前置条件:

npm i three d3

关键代码部分:

 

<template>
  <div class="center-map-box" id="contant"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import {
  CSS2DRenderer,
  CSS2DObject,
} from "three/addons/renderers/CSS2DRenderer.js";
import * as d3 from "d3";

let textureLoader = new THREE.TextureLoader(); //纹理贴图加载器
let WaveMeshArr = []; //所有波动光圈集合
let rotatingApertureMesh, rotatingPointMesh;
// 墨卡托投影转换
const projection = d3.geoMercator();
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      contant: null,
      spotLight: null,
      map: null,
      centerPos: [114.255221, 30.619014], // 地图中心经纬度坐标
      raycaster: null, // 光线投射 用于进行鼠标拾取
      mouse: new THREE.Vector2(0, 0), // 鼠标位置
      labelRenderer: null, //CSS2DRenderer渲染器对象
    };
  },
  mounted() {
    // 第一步新建一个场景
    this.scene = new THREE.Scene();
    this.contant = document.getElementById("contant");
    // 辅助线
    const axesHelper = new THREE.AxesHelper(10);
    this.scene.add(axesHelper);

    //环境光
    const ambient = new THREE.AmbientLight("#ffffff", 4);
    this.scene.add(ambient);

    this.setCamera();
    this.setRenderer();
    this.generateGeometry();
    this.setClickFn();
    this.setController();
    this.animate();
    window.onresize = () => {
      this.renderer.setSize(
        this.contant.clientWidth,
        this.contant.clientHeight
      );
      this.camera.aspect = this.contant.clientWidth / this.contant.clientHeight;
      this.camera.updateProjectionMatrix();
    };

    this.initFloor();
  },
  methods: {
    // 新建透视相机
    setCamera() {
      this.camera = new THREE.PerspectiveCamera(
        45,
        this.contant.clientWidth / this.contant.clientHeight,
        0.1,
        1000
      );
      // 设置相机位置
      this.camera.position.set(20, 20, 20);
    },
    // 设置渲染器
    setRenderer() {
      this.renderer = new THREE.WebGLRenderer();
      // 设置画布的大小
      this.renderer.setSize(
        this.contant.clientWidth,
        this.contant.clientHeight
      );
      this.contant.appendChild(this.renderer.domElement);

      // 创建CSS2DRenderer渲染器(代替鼠标射线检测)
      this.labelRenderer = new CSS2DRenderer();
      // 设置labelRenderer渲染器宽高
      this.labelRenderer.setSize(
        this.contant.clientWidth,
        this.contant.clientHeight
      );
      this.labelRenderer.domElement.style.position = "absolute";
      this.labelRenderer.domElement.style.top = "0px";
      this.labelRenderer.domElement.style.pointerEvents = "none";
      // 将渲染器添加到页面
      this.contant.appendChild(this.labelRenderer.domElement);
    },

    render() {
      this.renderer.render(this.scene, this.camera);

      this.labelRenderer.render(this.scene, this.camera);
    },

    // 绘制地图
    generateGeometry() {
      // 初始化一个地图对象
      this.map = new THREE.Object3D();
      // 地理坐标数据 转换为3D坐标数据
      // 墨卡托投影转换
      projection.center(this.centerPos).scale(200).translate([0, 0]);
      const url =
        "https://geo.datav.aliyun.com/areas_v3/bound/420000_full.json";
      fetch(url)
        .then((res) => res.json())
        .then((jsondata) => {
          jsondata.features.forEach((elem) => {
            const coordinates = elem.geometry.coordinates;
            const province = new THREE.Object3D();
            province.name = elem.properties.name;

            // 拉伸 地图厚度
            const depth = 1;

            //这里创建光柱、文字坐标
            const lightPoint = this.initLightPoint(elem.properties, d
本文章已经生成可运行项目
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值