three.js 3D可视化地图

threejs地图

可视化地图------three.js实现
复制代码
this.provinceInfo = document.getElementById('provinceInfo');
// 渲染器
this.renderer = new THREE.WebGLRenderer({
   antialias: true
});
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.container.appendChild(this.renderer.domElement);

this.labelRenderer = new THREE.CSS3DRenderer(); //新建CSS3DRenderer
this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
this.labelRenderer.domElement.style.position = 'absolute';
this.labelRenderer.domElement.style.top = 0;
document.body.appendChild(this.labelRenderer.domElement);

// 场景
this.scene = new THREE.Scene();
// 假设 scene 是一个 Scene 对象
const textureLoader = new THREE.TextureLoader();
this.scene.background = textureLoader.load("img/bg.png");
 
// 相机 透视相机
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
this.camera.position.set(this.orbitParams.pos.x, this.orbitParams.pos.y, this.orbitParams.pos.z);
this.camera.lookAt(this.orbitParams.target.x, this.orbitParams.target.y, this.orbitParams.target.z);

地图数据的加载渲染

复制代码
this.map = new THREE.Object3D();
this.map.add(cityPointGroup);
this.map.add(cityGroup);
this.map.add(flyGroup);

let _this = this;
_this.maptext = [];
const projection = d3.geoMercator().center([104.0, 37.5]).scale(80).translate([0, 0]);
let pintArr = [];
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshPhongMaterial({
   color: '#03121b',
   transparent: true,
   normalScale: new THREE.Vector2( 0.150, 0.150 ),
   normalMap: textureLoader.load( 'img/OIP-C.jpg' ),
   opacity: 0.9
});

const material1 = new THREE.MeshBasicMaterial({
   color: '#15d0b1',
   transparent: true,
   // normalMap: textureLoader.load( 'img/earth_normal_2048.jpg' ),
   opacity: 0.7
});

chinaJson.features.forEach(elem => {
   // 定一个省份3D对象
   const province = new THREE.Object3D();
   // 每个的 坐标 数组
   const coordinates = elem.geometry.coordinates;
   // 循环坐标数组
   coordinates.forEach(multiPolygon => {

      multiPolygon.forEach(polygon => {
         const shape = new THREE.Shape();
         const lineMaterial = new THREE.LineBasicMaterial({
            color: '#15d0b1',
         });
         const lineGeometry = new THREE.Geometry();

         let boundingBox = {
            max: { x:undefined,y:undefined },
            min: { x:undefined,y:undefined }
         };

         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);
            lineGeometry.vertices.push(new THREE.Vector3(x, -y, 4.01));

            if(undefined==boundingBox.max.x) boundingBox.max.x = x;
            if(undefined==boundingBox.max.y) boundingBox.max.y = -y;
            if(undefined==boundingBox.min.x) boundingBox.min.x = x;
            if(undefined==boundingBox.min.y) boundingBox.min.y = -y;
            if(x > boundingBox.max.x) boundingBox.max.x = x;
            if(-y > boundingBox.max.y) boundingBox.max.y = -y;
            if(x < boundingBox.min.x) boundingBox.min.x = x;
            if(-y < boundingBox.min.y) boundingBox.min.y = -y;
         }

         let width = Math.abs( boundingBox.max.x - boundingBox.min.x );
         let height = Math.abs( boundingBox.max.y - boundingBox.min.y );

         const extrudeSettings = {
            depth: 4,
            bevelEnabled: false,
            UVGenerator : {

               generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {  },

               generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {

               }
            }
         };
     
         const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);


         const mesh = new THREE.Mesh(geometry, [material, material1]);
         const line = new THREE.Line(lineGeometry, lineMaterial);
         mesh.userData.oldMaterial = true;
         province.add(mesh);
         province.add(line)
      })

   })

 
   province.properties = elem.properties;
   if (elem.properties.contorid) {
      const [x, y] = projection(elem.properties.contorid);
      province.properties._centroid = [x, y];
   }

   _this.map.add(province);

   if (elem.properties.center) {
      const [x, y] = projection(elem.properties.center);
      const center = new THREE.Vector3(x, -y, 4.01);
  
      _this.maptext.push( {
         pos:center,
         text:elem.properties.name
      } );
   }
   if (elem.properties.name == "北京市") {
      const [x, y] = projection(elem.properties.center);
      const center = new THREE.Vector3(x, -y, 4.01);
      pintArr.push(center.clone())
   }
})

this.scene.add(this.map);
this.loadFont(_this.maptext);
_this.ctrlBarDatas( true,'bar','北京市' );

相关推荐
BYSJMG2 小时前
计算机毕设选题做什么好?基于大数据的用户健身行为数据分析与可视化系统,Hadoop+Spark处理
大数据·人工智能·hadoop·数据分析·spark·课程设计
知见漫记5 小时前
AI 桌面 Agent 本地执行能力技术对照:沙箱机制与权限模式拆解
大数据·人工智能
xcl09257 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
cspttty7 小时前
国际经济与贸易专业考什么证对就业有帮助
大数据
足球魅力7 小时前
哪款足球软件能分析凯利指数大数据?
大数据·业界资讯
xwz小王子8 小时前
机器人的“最后一毫米”: 新加坡南洋理工大学Facet-0如何教会基础模型“感受”自己的动作?
大数据·人工智能·机器人
腾视科技-AI8 小时前
腾视科技AIBOX双版本重磅发布!本地安全与全球适配,解锁视频智能新可能
大数据·人工智能·科技·安全·大模型·腾视科技·ai算力盒
姜穆澜9 小时前
OneID 从 0 到 1 完整生产案例(五)
大数据·notepad++
geneculture9 小时前
《融智学:终结信息定义纷争的时代范式》 拓展分析述评
大数据·人工智能·信息科学·融智学的重要应用·哲学与科学统一性·融智时代(杂志)·比较分析
刘同学的 AI学习手记9 小时前
每日 AI PM 情报 · 2026-08-31
大数据·人工智能