threejs+vue 省份3D可视化地图

这篇具有很好参考价值的文章主要介绍了threejs+vue 省份3D可视化地图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先上效果图

threejs三维地图可视化,vue.js,3d,前端
threejs三维地图可视化,vue.js,3d,前端

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

1.先获取想要展示地图的区域json数据
阿里云获取地图区域的json
示例为陕西省
threejs三维地图可视化,vue.js,3d,前端

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'

具体代码

<template>
    <div class="center-map-box" id="contant">
    </div>
</template>
 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);
        },
  }

该文章只做记录,具体在场景中使用中自己调整。文章来源地址https://www.toymoban.com/news/detail-851581.html

到了这里,关于threejs+vue 省份3D可视化地图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 3D可视化集装箱货柜模型开发 --threejs

    3D可视化集装箱货柜模型开发 --threejs

    教程效果实现效果     集装箱模型 箱子模型   中文文档:three.js docs 1.安装并 引入threejs 创建 安装threejs依赖包 在需要用的的代码文件里面引入threejs 2.实现3D模型最基础的渲染骨架部分 以下例子是在vue的项目里面实现一个简单的场景渲染,目前场景除了坐标轴并无其他物体

    2024年02月15日
    浏览(16)
  • 前端前沿web 3d可视化技术 ThreeJS学习全记录

    前端前沿web 3d可视化技术 ThreeJS学习全记录

    完整案例与项目代码: gitee开源项目地址 https://gitee.com/jumping-world-line/01_threeJS_basic 随着浏览器性能和网络带宽的提升 使得3D技术不再是桌面的专利 打破传统平面展示模式 前端方向主要流向的3D图形库包括Three.js和WebGL WebGL灵活高性能,但代码量大,难度大,需要掌握很多底层

    2024年02月01日
    浏览(52)
  • 【地图可视化】Echarts地图上展示3D柱体

    【地图可视化】Echarts地图上展示3D柱体

    这是以前有这方面可视化的需求做的,找了很多资料,最后感觉这样的效果比较满意。 效果展示  以下以江苏省的地图为例: 数据准备 对于想要做3d效果的地区,需要准备对应的json文件 可以在这个网站上下载,数据最小粒度可以具体到县: DataV.GeoAtlas地理小工具系列 这里

    2023年04月19日
    浏览(14)
  • three.js 3D可视化地图

    threejs地图 可视化地图——three.js实现 地图数据的加载渲染

    2024年02月20日
    浏览(41)
  • 三维可视化平台有哪些?Sovit3D可视化平台怎么样?

    三维可视化平台有哪些?Sovit3D可视化平台怎么样?

    随着社会经济的发展和数字技术的进步,互联网行业发展迅速。为了适应新时代社会发展的需要,大数据在这个社会经济发展过程中随着技术的进步而显得尤为重要。同时,大数据技术的快速发展进程也推动了可视化技术的飞速发展,国内外各类可视化工具软件平台如雨后春

    2024年02月13日
    浏览(10)
  • 三维重建 阈值分割 3D可视化 医学图像分割 CT图像分割及重建系统 可视化编程技术及应用

    三维重建 阈值分割 3D可视化 医学图像分割 CT图像分割及重建系统 可视化编程技术及应用

    此系统实现了常见的VTK四视图,实现了很好的CT图像分割,可以用于骨骼,头部,肺部,脂肪等分割,,并且通过三维重建实现可视化。使用了第三方库 VTK,ITK 实现分割和生不重建。 窗口分为 (横断面)、冠状面、矢状面,和3D窗口;包含了体绘制和面绘制; 效果: CT分割

    2024年02月08日
    浏览(11)
  • 使用Open3D进行OBJ模型三维可视化

    使用Open3D进行OBJ模型三维可视化 在三维图像处理领域,OBJ文件是一种常见的三维模型格式,而Open3D则是一个强大的开源3D计算机视觉库。本文将介绍如何使用Open3D对OBJ文件进行可视化。 首先,需要安装Open3D库。使用pip install即可: 接下来,我们可以使用Open3D提供的read_triang

    2024年02月06日
    浏览(12)
  • 用Three.js实现3D中国地图的可视化大屏

    在前端开发中,使用Three.js库可以轻松创建各种令人印象深刻的3D效果。本文将介绍如何使用Three.js库创建一个令人惊叹的3D中国地图可视化大屏。我们将使用JavaScript和Three.js来呈现中国地图,并添加一些交互功能。 首先,我们需要在HTML页面中引入Three.js库。你可以从官方网站

    2024年02月03日
    浏览(81)
  • open3d教程(二):可视化三维模型,并转换成点云(Python版本)

    open3d教程(二):可视化三维模型,并转换成点云(Python版本)

    可以自己用建模软件建立一个模型 从free3d免费下载 open3d.visualization. draw_geometries 参数: geometry_list ( List[open3d.geometry.Geometry]) : 要可视化的几何体列表. window_name( str ,  optional ,  default=\\\'Open3D\\\'): 展示模型的可视化窗口名称,默认是Open3d. width: 

    2024年02月11日
    浏览(14)
  • ChatGPT AIGC 完成各省份销售动态可视化分析

    ChatGPT AIGC 完成各省份销售动态可视化分析

    像这样的动态可视化由人工智能ChatGPT  AIGC结合前端可视化技术就可以实现。 Prompt:请使用HTML,JS,Echarts 做一个可视化分析的案例,地图可视化,数据可以随机生成,请写出完整的代码 完整代码复制如下:

    2024年02月04日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包