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