【数字孪生平台】使用 Three.js 以 3D 形式可视化日本新宿站地图

在这里插入图片描述

在本文中,我们将使用日本新宿站的室内地图数据,并使用 Three.js 将其进行 3D 可视化。更多精彩内容尽在数字孪生平台,关注公众号:sky的数孪技术,技术交流、源码下载请添加VX:digital_twin123

image.png

使用的数据

这次,我们将使用日本空间信息中心发布的“新宿站室内地图开放数据”的集成版本(ShapeFile)

要素数据

在QGIS中显示

网络数据

在QGIS中显示

数据转换

所有这些数据都是 ShapeFile,我们可以使用 GDAL 命令将 ShapeFile 转换为 GeoJson。

mkdir geojson

for f in *.shp; do
  ogr2ogr -f GeoJSON -t_srs EPSG:6677 "geojson/${f%.*}.geojson" $f
done

使用 Three.js 绘制

创建场景

创建场景并添加相机和控制器。在本文中,我将把移动操作分配给 MapControls,将缩放操作分配给 TrackballControls。

import * as THREE from 'three';
import {
    MapControls } from 'three/examples/jsm/controls/MapControls.js';
import {
    TrackballControls } from 'three/examples/jsm/controls/TrackballControls.js';

const sizes = {
   
  width: window.innerWidth,
  height: window.innerHeight,
};

// 创建画布
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100000);
camera.position.set(-190, 280, -350);
scene.add(camera);

// 创建控制器
const mapControls = new MapControls(camera, canvas);
mapControls.enableDamping = true;
mapControls.enableZoom = false;
mapControls.maxDistance = 1000;

const zoomControls = new TrackballControls(camera, canvas);
zoomControls.noPan = true;
zoomControls.noRotate = true;
zoomControls.noZoom = false;
zoomControls.zoomSpeed = 0.5;

// 渲染器
const renderer = new THREE.WebGLRenderer({
   
  canvas: canvas,
  alpha: true,
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

// 当屏幕大小调整时,画布也会调整大小
const onResize = () => {
   
  // 获取尺寸大小
  const width = window.innerWidth;
  const height = window.innerHeight;

  // 调整渲染器大小
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);

  // 修正相机纵横比
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
};
window.addEventListener('resize', onResize);

const animate = () => {
   
  requestAnimationFrame(animate);

  const target = mapControls.target;
  mapControls.update();
  zoomControls.target.set(target.x, target.y, target.z);
  zoomControls.update();
  renderer.render(scene, camera);
};
animate();

另外,在 WebGLRenderer 选项中设置 alpha: true 以使背景透明并使用 CSS 将渐变应用于背景。

canvas {
   
  background-image: radial-gradient(#382c6e, #000000);
}

背景

创建 GUI 和组

在场景中绘制要素数据。这次我们按图层对要素进行分组,因此需要提前在场景中创建一个组,并将使用要素数据创建的对象添加到每个图层的组中。我们还将添加一个复选框 GUI,以便可以切换每个层次结构的显示。

import {
    GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';

// 创建 dat.GUI 的实例
const gui = new GUI({
    width: 150 });

// 创建一个群组
const groupList = [4, 3, 2, 1, 0, -1, -2
  • 27
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搞GIS图形的sky.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值