Threejs 实现3D 地图(02)创建3d 地图

 

"d3": "^7.9.0",
"three": "^0.169.0",
"vue": "^3.5.10"

地图数据来源: DataV.GeoAtlas地理小工具系列 

<script setup>
import {onMounted, ref} from 'vue'
import * as THREE from 'three'
import * as d3 from "d3";  //莫开托坐标 矫正地图坐标
import map from './constant/map.json'
// 引入轨道控制器扩展库OrbitControls.js
import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
// 拿到页面的宽高
const width = window.innerWidth, height = window.innerHeight;// d3投影转换函数 (109, 34.5  中心点位置)
const handleProject = d3.geoMercator().center([109, 34.5]).scale(1000).translate([0, 0])
// 存储地图容器
const mapContainer = new THREE.Object3D()// 创建场景
const scene = new THREE.Scene();
// 将背景颜色设置为白色
scene.background = new THREE.Color("#000000");// 创建相机
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10000);
// 设置相机位置
camera.position.z = 1000;// // 辅助线 AxesHelper
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);// 初始化渲染器
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
//阻尼 更真实
controls.enableDamping = true// 地图数据处理
const initGeom = () => {// 将地图数据显示在屏幕上// 如果是服务器返回的数据,需要先将数据转为geojson格式 这里默认用的本地数据handleData(map)
}const handleData = (jsonData) => {const featureList = jsonData.features;featureList.forEach((feature) => {// 创建省的容器const province = new THREE.Object3D;// 省份名称province.properties = feature.properties.nameprovince.name = feature.properties.name // 省份名称mapContainer.name = feature.properties.name // 省份名称// 省份坐标信息const coordinates = feature.geometry.coordinatesif (feature.geometry.type === 'MultiPolygon') {coordinates.forEach((cord) => {// coordinate 就是边界素组坐标系cord.forEach((coordinate) => {// 三维多边形const extrudeMesh = creatDepthPolygon(coordinate)// 给extrudeMesh对象加一个自定义的属性(properties)用来存放省份名称extrudeMesh.properties = feature.properties.name// 绘制省份边缘线条const line = createLine(coordinate);// 将面加入3d 中province.add(extrudeMesh)// 将线加入3d 中province.add(line)})})}if (feature.geometry.type === 'Polygon') {coordinates.forEach((coordinate) => {// 三维多边形const extrudeMesh = creatDepthPolygon(coordinate)extrudeMesh.properties = feature.properties.name// 线条const line = createLine(coordinate);province.add(extrudeMesh)province.add(line)})}// 将每个省份的容器加入到地图容器中mapContainer.add(province)})// 将地图容器加入到场景中scene.add(mapContainer)
}// 创建三维多边形(也就是每个省份的地图)
const creatDepthPolygon = (coordinate) => {const shape = new THREE.Shape();// 每一个item都是省份边界坐标 需要把 json 的坐标系 转化为d3的坐标系  例如:[117.429915,40.576141]coordinate.forEach((item, index) => {const [x_XYZ, y_XYZ] = handleProject(item)if (index === 0) {// moveTo 的主要作用是定义形状的起点位置shape.moveTo(x_XYZ, -y_XYZ)} else {// 依次按照坐标 形成一个多边形shape.lineTo(x_XYZ, -y_XYZ)}})const extrudeSettings = {steps: 2,depth: 16,bevelEnabled: true,bevelThickness: 1,bevelSize: 1,bevelOffset: 0,bevelSegments: 1};// ExtrudeGeometry  创建一个多边形const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)  //挤压缓冲几何体// 设置每个身份的背景颜色const material = new THREE.MeshBasicMaterial({// color: new THREE.Color(Math.random() * 0xffffff), // 每个省随机赋色color: '#d13a34',transparent: true,opacity: 0.6})return new THREE.Mesh(geometry, material)
}// 创建省份边界线条
const createLine = (coordinate) => {const material = new THREE.LineBasicMaterial({color: '#ffffff'});const points = []coordinate.forEach((item, index) => {// 每一个item都是省份边界坐标 需要把 json 的坐标系 转化为d3的坐标系  例如:[117.429915,40.576141]const [x_XYZ, y_XYZ] = handleProject(item)points.push(new THREE.Vector3(x_XYZ, -y_XYZ, 25))})const geometry = new THREE.BufferGeometry().setFromPoints(points);return new THREE.Line(geometry, material);
}// 渲染页面
const render = () => {// 将场景(scene)和摄像机(camera 加入进来)renderer.render(scene, camera)// 渲染下一帧的时候会调用render函数requestAnimationFrame(render)controls.update()
}const initLight = () => {// 基本光源const ambLight = new THREE.AmbientLight('#ffffff', 0.3)/*** 设置聚光灯相关的的属性*/const spotLight = new THREE.SpotLight(0xFFFFFF); // 聚光灯spotLight.position.set(40, 200, 10);spotLight.castShadow = true; // 只有该属性为true时,该点光源允许产生阴影,并且下列属性可用scene.add(ambLight, spotLight); // 向场景中添加光源
}onMounted(() => {// 添加物体到场景initGeom()// 渲染render()// 设置环境光initLight()// 将渲染加入到页面上document.body.appendChild(renderer.domElement);
})
</script><template><div id="info"></div>
</template><style scoped></style>

下一篇:Threejs 实现3D 地图(03)3d 地图的上钻下钻操作-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453298.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

空间单细胞转录组cell2location分析流程学习

Cell2location 是一个用于空间转录组学数据分析的工具。它是一个基于贝叶斯统计模型的Python包&#xff0c;旨在利用空间转录组数据和单细胞转录组数据来进行细胞类型的空间解构。通过将单细胞转录组数据中的细胞类型信息投射到空间转录组数据中&#xff0c;Cell2location 可以…

如何应对 Android 面试官 -> ANR 如何优化?线上 ANR 如何监控?

前言 本章主要围绕 ANR 如何监控以及优化&#xff1b; 基本概念 ANR(Android Not Responding) 是指应用程序未响应&#xff0c;Android 系统对于一些事件需要在一定的时间范围内完成&#xff0c;如果超过预订时间未能得到有效响应或者响应时间过长&#xff0c;都会造成 ANR。 …

SAP_MM模块-设置业务合作伙伴类型字段必输(多种方案)

一、业务背景 公司需要把供应商增加一个细分的维度&#xff0c;并且要求该字段设置为必输&#xff0c;防止用户新增供应商时忘记维护。这里给用户找了一个分类的字段&#xff1a;业务合作伙伴类型&#xff0c;本文主要讲解如何设置该字段设置为必填&#xff1b; 注意&#xff…

[笔记] 关于CreateProcessWithLogonW函数创建进程

函数介绍 https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW([in] LPCWSTR lpUsername,[in, optional] LPCWSTR lpDomain,[in] …

【MySQL】表的约束、基本查询、内置函数

目录 1. 表的约束1.1 空属性1.2 默认值1.3 列描述1.4 zerofill1.5 主键1.6 自增长1.7 唯一键1.8 外键 2. 基本查询2.1 表的增删改查2.1.1 插入数据2.1.2 插入否则更新2.1.3 替换插入 2.2 Retrieve2.2.1 select ----- 查询2.2.2 where ----- 筛选2.2.3 order by ----- 结果排序2…

C++11——基础新增特性

目录 C11介绍统一的列表初始化对内置类型initializer_list 声明autodecltypenullptr 范围for容器新增接口emplace容器的新方法 C的前身是“C with Classes”&#xff0c; 最早于 1979年由 祖师爷Bjarne Stroustrup&#xff08;本贾尼斯特劳斯特鲁普&#xff09; 在贝尔实验室…

#HarmonyOS:页面和自定义组件生命周期

页面生命周期 即被Entry装饰的组件生命周期 onPageShow&#xff1a;页面每次显示时触发一次&#xff0c;包括路由过程、应用进入前台等场景。onPageHide: 页面每次隐藏时触发一次&#xff0c;包括路由过程、应用进入后台等场景。onBackPress: 当用户点击返回按钮是触发 组件…

成都睿明智科技有限公司解锁抖音电商新蓝海

在这个短视频风靡的时代&#xff0c;抖音已不仅仅是一个娱乐平台&#xff0c;它更是商家们竞相追逐的电商新战场。成都睿明智科技有限公司&#xff0c;作为抖音电商服务领域的佼佼者&#xff0c;正以敏锐的洞察力和专业的服务&#xff0c;助力众多品牌在这片蓝海中乘风破浪&…

RHCE-多IP访问网站

关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0下载nginx工具 [rootlocalhost ~]# yum install nginx Updating Subscription Management repositories. Unable to read consumer identityThis system is not registered with an …

面对AI算力需求激增,如何守护数据中心机房安全?

随着人工智能&#xff08;AI&#xff09;技术飞速发展&#xff0c;AI算力需求呈现爆发式增长&#xff0c;导致对数据设备电力的需求指数级攀升。这给数据中心带来前所未有的挑战和机遇&#xff0c;从提供稳定的电力供应、优化高密度的部署&#xff0c;到数据安全的隐私保护&…

【unity小技巧】Unity6 LTS版本安装和一些修改和新功能使用介绍

文章目录 前言安装新功能变化1、官方推荐使用inputsystem进行输入控制2、修复了InputSystem命名错误导致listen被遮挡的bug3、自带去除unity启动画面logo功能4、unity官方的behavior行为树插件5、linearVelocity代替过时的velocity方法待续 完结 前言 2024/10/17其实unity就已…

前端拦截302重定向

背景: 根据业务场景需要拦截302做后续的逻辑处理 尝试一: : axios拦截 、、、、、async created() {// 获取302请求返回的location后手动修改video的src路径let targetSrc;try {await axios.get(this.video).then((res) > {const { headers, status } res;const { locat…

Spring Cloud 解决了哪些问题?

大家好&#xff0c;我是锋哥。今天分享关于【Spring Cloud 解决了哪些问题&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; Spring Cloud 解决了哪些问题&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Cloud 是一个为构建分布式…

如何删除Maven

1.找到Maven安装路径 方法一&#xff1a; 可以直接在文件资源管理器里面选中“此电脑”然后右上角搜“apache-maven”&#xff0c;这个过程可能长达几分钟甚至更久 方法二&#xff1a; 这里推荐一个名叫“Everything”的软件&#xff0c;能够快速的查找到需要的文件 2.找到本…

每日一道算法题(Leetcode 20)

Whats past is prologue. 凡是过去&#xff0c;皆为序章。 题目 分析 1. 我们可以用栈的结构来解决这道题。 2. 我们使用while循环&#xff0c;每次读取字符串中一个元素进行操作&#xff0c;直到最后读取到 \0为止。 3. 如果遇见 (, [ ,{ 这三种左括号&#xff0c;则把该左…

【AIGC】AI如何匹配RAG知识库:关键词搜索

关键词搜索 引言jieba库简介TF-IDF简介实践例子用jieba库提取关键词计算TF-IDF计算文档和查询相似度结果完整代码&#xff1a; 总结 引言 RAG作为减少模型幻觉和让模型分析、回答私域相关知识最简单高效的方式&#xff0c;我们除了使用之外可以尝试了解其是如何实现的。在实现…

写一个自动采集地球前30行业的小程序

创建一个自动采集地球前30行业信息的小程序可以使用Python和一些常用的库&#xff0c;如BeautifulSoup和Requests。以下是一个基本示例&#xff0c;展示如何从网页上抓取行业信息&#xff1a; 环境准备 安装Python&#xff1a;确保你的计算机上已安装Python。安装库&#xff…

电影评论网站开发:Spring Boot技术指南

3系统分析 3.1可行性分析 通过对本电影评论网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本电影评论网站采用SSM框架&#xff0c;JAVA作为开发语言&#…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法&#xff0c;能够实现行为分析、人脸识别和异常事件检测等功能&#xff0c;提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

【linux009】文件操作命令篇 - touch 命令

文章目录 touch 命令1、基本用法2、常见选项3、举例4、注意事项 touch 命令 touch 是 Linux 系统中的一个常用命令&#xff0c;用于创建空文件或更新已有文件的时间戳。它既可以用来快速生成新文件&#xff0c;也可以用来修改文件的访问时间&#xff08;access time, atime&am…