采用threejs加载geojson案例
首先下载一套geojson数据,如: china.json
加载核心threejs脚本,官方文档 https://threejs.org/
定义核心变量
// 渲染器,相机,场景
var renderer, camera, scene = null;
// 包裹画布dom
const dom = document.getElementById('container');
// 地图正面颜色
const faceColor = '#345fa6';
// 地图侧边颜色
const sideColor = '#1e90ff';
// orbit 对象
let orbitcontrols = null;
// 地图缩放比例
const shapeScaleSize = 1;
// 中国经纬度对象
let shapeGeometry = {};
let mapGrop = new THREE.Group();
let axes;
// 初始化3D
function initThree() {
// 初始化场景
scene = new THREE.Scene();
scene.rotation.x = -0.8;
scene.add(mapGrop);
//坐标轴辅助器,X,Y,Z长度100
axes = new THREE.AxesHelper(100);
this.scene.add(axes);
// 初始化相机
camera = new THREE.PerspectiveCamera(60, dom.clientWidth / dom.clientHeight, 1, 10000);
// 设置相机位置
camera.position.set(22, -7, 136);
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true
});
// 设置窗口尺寸
renderer.setSize(dom.clientWidth, dom.clientHeight);
// 初始化控制器
orbitcontrols = new THREE.OrbitControls(camera, renderer.domElement);
dom.appendChild(renderer.domElement);
// 绘制地图
drapMapShape();
// 渲染
render();
window.addEventListener('resize', function () {
// 重绘之前先将原先的移除
clearShape();
// 重新初始化尺寸
camera.aspect = dom.clientWidth / dom.clientHeight;
renderer.setSize(dom.clientWidth, dom.clientHeight);
// 重绘地图
drapMapShape();
});
}
// 清空 map shape
function clearShape() {
// mapGrop.traverse(function(child){
// if (child.isMesh){
// mapGrop.remove(child);
// }
// });
scene.remove(mapGrop);
mapGrop = new THREE.Group();
scene.add(mapGrop);
}
// 获取中国经纬度信息函数
function getShapeGeometry() {
fetch('/resources/china.json').then(res => res.json()).then(data => {
//返回数据根据结果进行相应的处理
shapeGeometry = data;
initThree();
});
}
// 绘制地图
function drapMapShape() {
// 绘制中国地图
shapeGeometry.features.forEach(function (worldItem, worldIndex) {
const length = worldItem.geometry.coordinates.length;
const multipleBool = length > 1 ? true : false;
//这里指的是原点缩定位的位置 109.01373,34.381819
const averageX = 109.01373;
const averageY = 34.381819;
worldItem.geometry.coordinates.forEach(function (worldChildItem, wordItemIndex) {
if (multipleBool) {
// 值界可以使用的经纬度信息
if (worldChildItem.length && worldChildItem[0].length == 2) {
shapeTo3D(drawShape(worldChildItem, averageX, averageY), '' + worldIndex + wordItemIndex);
}
// 需要转换才可以使用的经纬度信息
if (worldChildItem.length && worldChildItem[0].length > 2) {
worldChildItem.forEach(function (countryItem, countryIndex) {
shapeTo3D(drawShape(countryItem, averageX, averageY), '' + worldIndex + wordItemIndex + countryIndex);
});
}
} else {
let countryPos = null;
if (worldChildItem.length > 1) {
countryPos = worldChildItem;
} else {
countryPos = worldChildItem[0];
}
if (countryPos) {
shapeTo3D(drawShape(countryPos, averageX, averageY), '' + worldIndex + wordItemIndex);
}
}
});
});
}
// ExturdeGeometry配置参数
const options = {
depth: 3, // 定义图形拉伸的深度,默认100
steps: 0, // 拉伸面方向分为多少级,默认为1
bevelEnabled: true, // 表示是否有斜角,默认为true
bevelThickness: 0, // 斜角的深度,默认为6
bevelSize: 0, // 表示斜角的高度,高度会叠加到正常高度
bebelSegments: 0, // 斜角的分段数,分段数越高越平滑,默认为1
curveSegments: 0 // 拉伸体沿深度方向分为多少段,默认为1
};
// 将shape转换为ExtrudeGeometry
function shapeTo3D(shapeObj, identify) {
const geometry = new THREE.ExtrudeGeometry(shapeObj, options);
const matFace = new THREE.MeshBasicMaterial({
color: faceColor,
transparent: true,
opacity: 0.5
});
const matEdge = new THREE.MeshBasicMaterial({
color: sideColor,
transparent: true,
opacity: 1
});
// 绘制地图
const mapShape = new THREE.Mesh(geometry, [matFace, matEdge]);
mapShape.name = identify;
// 将地图加入场景
mapGrop.add(mapShape);
}
// 绘制地图 shape
function drawShape(pos, averageX, averageY) {
// debugger;
const shape = new THREE.Shape();
// 计算平均每格占比
let average = 0;
if (dom.clientWidth > dom.clientHeight) {
average = dom.clientHeight / 180;
} else {
average = dom.clientWidth / 360;
}
shape.moveTo(((pos[0][0] - averageX) * average) / shapeScaleSize, ((pos[0][1] - averageY) * average) / shapeScaleSize);
pos.forEach(function (item) {
shape.lineTo(((item[0] - averageX) * average) / shapeScaleSize, ((item[1] - averageY) * average) / shapeScaleSize);
});
return shape;
}
// 执行函数
function render() {
renderer.render(scene, camera);
orbitcontrols.update();
requestAnimationFrame(render);
}
// 页面资源加载完毕之后执行创建
window.onload = function () {
getShapeGeometry();
};