采用threejs加载geojson案例
首先下载一套geojson数据,如: china.json
加载核心threejs脚本,官方文档 https://threejs.org/
定义核心变量
// 渲染器,相机,场景var renderer, camera, scene = null;// 包裹画布domconst 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;
// 初始化3Dfunction initThree() {// 初始化场景scene = new THREE.Scene();scene.rotation.x = -0.8;scene.add(mapGrop);//坐标轴辅助器,X,Y,Z长度100axes = 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 shapefunction 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.381819const 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, // 定义图形拉伸的深度,默认100steps: 0, // 拉伸面方向分为多少级,默认为1bevelEnabled: true, // 表示是否有斜角,默认为truebevelThickness: 0, // 斜角的深度,默认为6bevelSize: 0, // 表示斜角的高度,高度会叠加到正常高度bebelSegments: 0, // 斜角的分段数,分段数越高越平滑,默认为1curveSegments: 0 // 拉伸体沿深度方向分为多少段,默认为1};// 将shape转换为ExtrudeGeometryfunction 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);}// 绘制地图 shapefunction 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();};
