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','北京市' );