IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> threejs导入简单地图模型 -> 正文阅读

[JavaScript知识库]threejs导入简单地图模型

抄的b站一个大佬的
添加链接描述
vite建的项目vue3+ts
地图数据需要自己下载
https://overpass-turbo.eu/
浏览器需要调成英文模式不然下不下来(18年以前貌似没事)

<!-- 加载人物模型 -->
<template>
  <div ref="statsDivRef"></div>
  <div ref="threeRef"></div>
</template>

<script lang="ts">
import {
  reactive,
  toRefs,
  onBeforeMount,
  onMounted,
  defineComponent,
  ref,
  render,
} from "vue";
import {
  AmbientLight,
  AnimationMixer,
  AxesHelper,
  BoxGeometry,
  BufferAttribute,
  BufferGeometry,
  Camera,
  Clock,
  Color,
  DirectionalLight,
  DoubleSide,
  ExtrudeBufferGeometry,
  Fog,
  FogExp2,
  GridHelper,
  Group,
  HemisphereLight,
  Line,
  LineBasicMaterial,
  LinePieces,
  Mesh,
  MeshBasicMaterial,
  MeshLambertMaterial,
  MeshNormalMaterial,
  MeshPhongMaterial,
  PerspectiveCamera,
  PlaneBufferGeometry,
  PlaneGeometry,
  PointLight,
  PointLightShadow,
  Scene,
  Shape,
  SphereGeometry,
  SpotLight,
  SpotLightHelper,
  Vector3,
  WebGLRenderer,
} from "three";
import States from "stats.js";
import * as dat from "dat.gui";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { MapControls } from "three/examples/jsm/controls/OrbitControls.js";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
import { getDistance, getRhumbLineBearing } from "geolib";
interface DataProps {}
export default defineComponent({
  name: "ExampleB",
  setup() {
    let camera: any;
    let scene: any;
    let group: any;
    let controls: any;
    let light: any;
    let center = [-3.1846411, 55.9457427];
    let MAT_EUILDING: any;

    const threeRef = ref();
    const statsDivRef = ref<HTMLDivElement>();
    const statsRef = ref<States>();
    function initStats() {
      statsRef.value = new States();
      statsRef.value.showPanel(0);
      if (statsDivRef.value) {
        statsDivRef.value.appendChild(statsRef.value.dom);
      }
    }

    //生成一个group
    function groupObj() {
      group = new Group();
      scene.add(group);
    }

    function Awake() {
      threeRef;
      scene = new Scene();
      scene.background = new Color(0x222222);

      //init
      camera = new PerspectiveCamera(
        25,
        window.innerWidth / window.innerHeight,
        1,
        100
      );
      camera.position.set(8, 4, 0);

      //light
      light = new AmbientLight(0xfafafa, 0.25);

      let light1 = new PointLight(0xfafafa, 0, 4);
      light1.position.set(100, 90, 40);

      let light2 = new PointLight(0xfafafa, 0, 4);
      light2.position.set(200, 90, -40);

      scene.add(light);
      scene.add(light1);
      scene.add(light2);

      let gh = new GridHelper(
        60,
        160,
        new Color(0x555555),
        new Color(0x333333)
      );
      scene.add(gh);

      //renderer 渲染
      let renderer = new WebGLRenderer({ antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);

      //添加到画布上
      threeRef.value.appendChild(renderer.domElement);

      //控制器
      controls = new MapControls(camera, renderer.domElement);
      controls.enableDamping = true;
      controls.dampingFactor = 0.25;
      controls.screenSpacePanning = false;
      controls.maxDistance = 800;

      controls.update();

      Update();

      //全局材质
      MAT_EUILDING = new MeshNormalMaterial();
      GetGeoJson();

      function Update() {
        window.addEventListener("resize", onWindowResize, false);
        requestAnimationFrame(Update);
        renderer.render(scene, camera);
        controls.update();
      }

      //实时拖放窗口
      function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      }

      //jsoN文件
      function GetGeoJson() {
        fetch("./assets/export.geojson").then((res) => {
          res.json().then((data) => {
            loadBuilding(data);
          });
        });
      }

      //加载建筑数据
      function loadBuilding(data: any) {
        let features = data.features;

        for (let i = 0; i < features.length; i++) {
          let fel = features[i];
          if (!fel["properties"]) return;

          if (fel.properties["building"]) {
            addBuilding(
              fel.geometry.coordinates,
              fel.properties,
              fel.properties["building:levels"]
            );
          }
        }
      }

      function addBuilding(data: any, info: any, height = 1) {
        for (let i = 0; i < data.length; i++) {
          let el = data[i];

          let shape = genShape(el, center);
          let geometry = genGeometry(shape, {
            curveSegments: 1,
            depth: 0.05 * height,
            bevelEnabled: false,
          });

          geometry.rotateX(Math.PI /2)
          geometry.rotateZ(Math.PI)

          let mesh = new Mesh(geometry, MAT_EUILDING);

          scene.add(mesh);
        }
      }

      function genShape(points: any, el: any) {
        let shape = new Shape();

        for (let index = 0; index < points.length; index++) {
          let elp = points[index];

          elp = GPSPosition(elp, center);

          if (index == 0) {
            shape.moveTo(elp[0], elp[1]);
          } else {
            shape.lineTo(elp[0], elp[1]);
          }
        }
        return shape;
      }

      /**
       * yarn add geolib
       * import { getDistance } from 'geolib';
       */
      function GPSPosition(objPosi: any, centerPosi: any) {
        let dis = getDistance(objPosi, centerPosi);

        let bearing = getRhumbLineBearing(objPosi, centerPosi);

        let x = centerPosi[0] + dis * Math.cos((bearing * Math.PI) / 180);

        let y = centerPosi[1] + dis * Math.sin((bearing * Math.PI) / 180);

        return [-x / 100, y / 100];
      }

      function genGeometry(shape: any, config: any) {
        let genGeometry = new ExtrudeBufferGeometry(shape, config);

        genGeometry.computeBoundingBox();

        return genGeometry;
      }
    }

    //更新

    onMounted(() => {
      Awake();
    });
    return {
      statsDivRef,
      threeRef,
    };
  },
});
</script>
<style scoped></style>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:20:29  更:2022-04-24 09:22:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:47:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码