threejs+vue 省份3D可视化地图
创始人
2024-11-13 00:09:14
0

这里写自定义目录标题

    • 先上效果图
    • 需要查找地图的josn数据、需要引入的js、 和需要安装的依赖如下
    • 具体代码

先上效果图

在这里插入图片描述
在这里插入图片描述

需要查找地图的josn数据、需要引入的js、 和需要安装的依赖如下

1.先获取想要展示地图的区域json数据
阿里云获取地图区域的json
示例为陕西省
在这里插入图片描述

2.npm安装three.js和d3 npm i threenpm i d3
3.引入相关方法和json数据

import * as THREE from 'three'; import { OrbitControls } from "../../../node_modules/three/examples/jsm/controls/OrbitControls.js" import { TextGeometry } from '../../../node_modules/three/examples/jsm/geometries/TextGeometry.js'; import { FontLoader } from '../../../node_modules/three/examples/jsm/loaders/FontLoader.js'; import * as d3 from 'd3'; import jsondata from './shanxi.json' 

具体代码

 
 mounted() { 		// 第一步新建一个场景         this.scene = new THREE.Scene()         this.contant = document.getElementById('contant')         // 辅助线         // const axesHelper = new THREE.AxesHelper(10);         // this.scene.add(axesHelper);         // 光源         this.spotLight = new THREE.PointLight('#fff', 4, 100)         this.spotLight.position.set(0.2, -0.4, 1)         this.scene.add(this.spotLight)         //环境光         const ambient = new THREE.AmbientLight('#fff', 4)         this.scene.add(ambient)         // 可视化点光源         // const pointLightHelper = new THREE.PointLightHelper(this.spotLight, 0.1)         // this.scene.add(pointLightHelper)         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();         };  }   methods: {   	 // 新建透视相机         setCamera() {             this.camera = new THREE.PerspectiveCamera(60, this.contant.clientWidth / this.contant.clientHeight, 0.1, 500);             this.camera.position.z = 10         },         // 设置渲染器         setRenderer() {             this.renderer = new THREE.WebGLRenderer()             // 设置画布的大小             this.renderer.setSize(this.contant.clientWidth, this.contant.clientHeight)             //这里 其实就是canvas 画布  renderer.domElement             this.contant.appendChild(this.renderer.domElement)             this.renderer.setClearColor(0x000000, 0)         },         render() {             this.renderer.render(this.scene, this.camera)         },         generateGeometry() {             // 初始化一个地图对象             this.map = new THREE.Object3D()              // 墨卡托投影转换             const projection = d3                 .geoMercator()                 .center([104.0, 37.5])                 .scale(80)                 .translate([0, 0])              jsondata.features.forEach((elem) => {                 this.renderer.render(this.scene, this.camera);                 const coordinates = elem.geometry.coordinates                 // 循环坐标数组                 coordinates.forEach((multiPolygon) => {                     multiPolygon.forEach((polygon, index) => {                         const province = new THREE.Object3D()                         const shape = new THREE.Shape()                         const lineMaterial = new THREE.LineBasicMaterial({                             color: 'white',                         })                         const lineGeometry = new THREE.BufferGeometry()                         const pointsArray = new Array()                         for (let i = 0; i < polygon.length; i++) {                             const [x, y] = projection(polygon[i])                             if (i === 0) {                                 shape.moveTo(x, -y)                             }                             shape.lineTo(x, -y)                             pointsArray.push(new THREE.Vector3(x, -y, 0))                         }                         lineGeometry.setFromPoints(pointsArray)                           const extrudeSettings = {                             depth: 0.07,                             bevelEnabled: false,                         }                          const geometry = new THREE.ExtrudeGeometry(                             shape,                             extrudeSettings                         )                         const material = new THREE.MeshPhongMaterial({                             color: '#43A7FF',                             transparent: true,                             opacity: 0.8,                         })                         const material1 = new THREE.MeshBasicMaterial({                             color: '#3480C4',                             transparent: true,                             opacity: 0.4,                         })                         const loader = new FontLoader();                         //字体需放到根目录public下                         loader.load('./fonts/FZCuHeiSongS-B-GB_Regular.json', (font) => {                             const fontOption = {                                 font: font,                                 size: 0.07,                                 height: 0.01,                                 curveSegments: 1,                                 bevelThickness: 1,                                 bevelSize: 0,                                 bevelEnabled: false,                                 bevelSegments: 0                             };                             const txtMater = new THREE.MeshBasicMaterial({ color: 0xffffff });                             const txtGeometry = new TextGeometry(name, fontOption);                             const txtMesh = new THREE.Mesh(txtGeometry, txtMater);                             const [x, y] = projection(elem.properties.center)                             txtMesh.position.set(x - 8.3, -y + 4.4, 0.08)                             if (name == 'xx县') {                             //这里位置不对可以做微调                                 txtMesh.position.set(x - 8.33, -y + 4.55, 0.08)                             }                             this.scene.add(txtMesh);                         });                         var name = elem.properties.name;//区县名                         const mesh = new THREE.Mesh(geometry, [material, material1])                         const line = new THREE.Line(lineGeometry, lineMaterial)                         this.materialArr.push(material)                         province.properties = elem.properties                         province.add(mesh)                         province.add(line)                         this.map.add(province)                         this.render()                     })                 })             })             this.map.position.set(-8.2, 4.4, 0);             this.scene.add(this.map);             this.spotLight.target = this.map;             this.camera.position.set(0, -0.7, 2.5);             this.renderer.render(this.scene, this.camera);          },         //加事件         setClickFn() {             this.raycaster = new THREE.Raycaster();             this.mouse = new THREE.Vector2();             const onMouseMove = (event) => {                 var marginLeft = this.contant.offsetLeft                 var marginTop = this.contant.offsetTop + 92                 // 如果该地图不是占满全屏需要减去margintop和marginleft                 // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)                 // this.mouse.x = (event.clientX / this.contant.clientWidth) * 2 - 1;                 // this.mouse.y = -(event.clientY / this.contant.clientHeight) * 2 + 1;                 this.mouse.x = ((event.clientX - marginLeft) / this.contant.clientWidth) * 2 - 1;                 this.mouse.y = -((event.clientY - marginTop) / this.contant.clientHeight) * 2 + 1;             };              let clickPosition;             window.addEventListener("mousemove", onMouseMove, false);             const onclick = (event) => {                 var marginLeft = this.contant.offsetLeft                 var marginTop = this.contant.offsetTop                 // let x = (event.clientX / this.contant.clientWidth) * 2 - 1;                 // let y = -(event.clientY / this.contant.clientHeight) * 2 + 1;                 // 如果该地图不是占满全屏需要减去margintop和marginleft                 let x = ((event.clientX - marginLeft) / this.contant.clientWidth) * 2 - 1;                 let y = -((event.clientY - marginTop) / this.contant.clientHeight) * 2 + 1;                 clickPosition = { x: x, y: y };                 this.raycaster.setFromCamera(clickPosition, this.camera);                 // 算出射线 与当场景相交的对象有那些                 const intersects = this.raycaster.intersectObjects(this.scene.children, true);                 let clickObj = intersects.find(                     (item) => item.object.material && item.object.material.length === 2                 );                 // 点击区县                 if (clickObj && clickObj.object) {                 	console.log(clickObj)                     // this.$emit('clickAreaCheck',clickObj)                 }             };             window.addEventListener("mousedown", onclick, false);         },         // 设置最大旋转的角度         setController() {             const controls = new OrbitControls(this.camera, this.renderer.domElement);             controls.maxPolarAngle = 2.5             controls.minPolarAngle = 1             controls.maxAzimuthAngle = 1             controls.minAzimuthAngle = -1             controls.addEventListener("change", () => {                 this.renderer.render(this.scene, this.camera);             });         },          animate() {             window.requestAnimationFrame(this.animate);             this.raycaster.setFromCamera(this.mouse, this.camera);             this.renderer.render(this.scene, this.camera);         },   } 

该文章只做记录,具体在场景中使用中自己调整。

相关内容

热门资讯

微信炸金花房卡找谁买/美猴王大... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
终于找到“微信斗牛房卡怎么获得... 金牛座金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡...
秒懂教程!怎么创建炸金花房间房... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:56001354许多玩家在游戏中会购买房卡来享...
玩微信牛牛房卡从哪里买/火神大... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享受...
安卓系统小游戏100个,畅享指... 手机里的时间总是不知不觉就溜走了,是不是你也和我一样,总是在各种小游戏里迷失了自我?今天,就让我带你...
秒懂教程!微信牛牛房卡专卖店联... 牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:71319951许多玩家在游戏中会购买房卡来享受...
给大家讲解“可以一起创房的牛牛... 新毛豆互娱是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:44346008许多玩家在游戏中会购买房卡...
炸金花从哪里买房卡/新西游大厅... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
秒懂教程!拼三张的房卡找谁买,... 大牌九是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:66336574许多玩家在游戏中会购买房卡来享...
微信群链接炸金花房卡/牛牛房卡... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
购买金花房卡联系方式/微信开金... 金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:15984933许多玩家在游戏中会购买房卡来享受...
秒懂教程!拼三张房卡链接去哪里... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:56001354许多玩家在游戏中会购买房卡来享...
安卓系统怎么强制usb连接,安... 你是不是也遇到过这种情况:手机连接电脑时,总是默认选择MTP模式,而不是我们想要的USB调试模式?别...
微信炸金花在哪里充值房卡/新卡... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:55051770许多玩家在游戏中会购买房卡来享...
金花房卡在哪获取/在哪里买炸金... 金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房卡来享...
秒懂教程!拼三张房卡链接在哪弄... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:71319951许多玩家在游戏中会购买房卡来享...
微信群炸金花房间买房卡/新蛮王... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:8488009许多玩家在游戏中会购买房卡来享受...
一分钟推荐“微信链接金花房卡如... 新蓝鲸是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:86909166许多玩家在游戏中会购买房卡来享...
微信群拼三张房间卡怎么开/熊猫... 拼三张是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:33903369许多玩家在游戏中会购买房卡来享...
秒懂教程!微信里上玩炸金花购买... 炸金花是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:66336574许多玩家在游戏中会购买房卡来享...