ThreeJS读取GeoJson文件,绘制地图板
从网上大神那儿找来的代码,稍微修改了一下,ThreeJS感觉好难用,文档写的太简单了,不好下手
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>3D</title> <link href="./css/index.css" rel="stylesheet"> <script type="text/javascript" src="./js/jquery.min.js"></script> <script type="text/javascript" src="./js/three.min.js"></script> <script type="text/javascript" src="./js/OrbitControls.js"></script> <script src="js/THREE.MeshLine.js"></script> <style type="text/css"> #three-frame { z-index: 998; opacity:1; background: #ffffff !important; } </style> </head> <body> <div id="three-frame"></div> </body> <script> // 渲染器 var renderer = null; // 相机 var camera = null; // 场景 var scene = null; // 包裹画布dom var dom = document.getElementById("three-frame"); // 地图正面颜色 var faceColor = '#F8F8FF'; // 地图侧边颜色 var sideColor = '#D3D3D3'; // orbitcontrols对象参数 var orbitcontrols = null; // 地图缩放比例 var shapeScaleSize = 1; // three中shapeGeometry对象数组 var shapeGeometryObj = {}; // 中国经纬度对象 var shapeGeometry = {}; var axes; // 绘制地图函数 var drawShape = function (pos, averageX, averageY) { debugger var shape = new THREE.Shape(); // let lineMaterial = new THREE.LineBasicMaterial({ color: 0x333333 }); // let linGeometry = new THREE.Geometry() // 计算平均每格占比 var 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; } // ExturdeGeometry配置参数 var options = { depth: 0.3, // 定义图形拉伸的深度,默认100 steps: 0, // 拉伸面方向分为多少级,默认为1 bevelEnabled: true, // 表示是否有斜角,默认为true bevelThickness: 0, // 斜角的深度,默认为6 bevelSize: 0, // 表示斜角的高度,高度会叠加到正常高度 bebelSegments: 0, // 斜角的分段数,分段数越高越平滑,默认为1 curveSegments: 0 // 拉伸体沿深度方向分为多少段,默认为1 }; // 将shape转换为ExtrudeGeometry var transition3d = function (shapeObj, identify) { var geometry = new THREE.ExtrudeGeometry(shapeObj, options); var material1 = new THREE.MeshBasicMaterial({ color: faceColor, transparent: true, opacity: 0.5 }); var material2 = new THREE.MeshBasicMaterial({ color: sideColor, transparent: true, opacity: 1 }); // 绘制地图 shapeGeometryObj['shapeGeometry' + identify] = new THREE.Mesh(geometry, [material1, material2]); // 将地图加入场景 scene.add(shapeGeometryObj['shapeGeometry' + identify]) } // 计算绘制地图参数函数 var drawShapeOptionFun = function () { // 绘制中国地图 shapeGeometry.features.forEach(function (worldItem, worldIndex) { var length = worldItem.geometry.coordinates.length; var multipleBool = length > 1 ? true : false; //这里指的是原点缩定位的位置 var averageX = 120.64383939800007; var averageY = 30.12268928300005; worldItem.geometry.coordinates.forEach(function (worldChildItem, wordItemIndex) { if (multipleBool) { // 值界可以使用的经纬度信息 if (worldChildItem.length && worldChildItem[0].length == 2) { transition3d(drawShape(worldChildItem, averageX, averageY), '' + worldIndex + wordItemIndex); } // 需要转换才可以使用的经纬度信息 if (worldChildItem.length && worldChildItem[0].length > 2) { worldChildItem.forEach(function (countryItem, countryIndex) { transition3d(drawShape(countryItem, averageX, averageY), '' + worldIndex + wordItemIndex + countryIndex); }) } } else { var countryPos = null; if (worldChildItem.length > 1) { countryPos = worldChildItem; } else { countryPos = worldChildItem[0]; } if (countryPos) { transition3d(drawShape(countryPos, averageX, averageY), '' + worldIndex + wordItemIndex); } } }) }) } // 执行函数 var render = function () { scene.rotation.x = -0.8; renderer.render(scene, camera); orbitcontrols.update(); requestAnimationFrame(render); } // 初始化函数 var initThree = function () { // 初始化场景 scene = new THREE.Scene(); //坐标轴辅助器,X,Y,Z长度100 axes = new THREE.AxesHelper(100); this.scene.add(axes); // 初始化相机 camera = new THREE.PerspectiveCamera(20, dom.clientWidth / dom.clientHeight, 1, 100000); // 设置相机位置 // camera.position.set(10, 39, 300); camera.position.set(0,-2,13); 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); // 绘制地图 drawShapeOptionFun(); // 渲染 render(); } // 清空绘图函数 var clearShape = function () { for (var shapeGeometry in shapeGeometryObj) { scene.remove(shapeGeometryObj[shapeGeometry]); } } // 获取中国经纬度信息函数 var getshapeGeometry = function () { $.ajax({ type : "GET", //提交方式 url : "./code/area.json", async: false, success : function(response) {//返回数据根据结果进行相应的处理 shapeGeometry = response; } }) } // 页面资源加载完全执行函数 window.onload = function () { getshapeGeometry(); initThree(); } // 窗口resize事件 window.onresize = function () { // 重绘之前先将原先的移除 clearShape(); // 重新初始化尺寸 camera.aspect = dom.clientWidth / dom.clientHeight renderer.setSize(dom.clientWidth, dom.clientHeight) // 重绘地图 drawShapeOptionFun(); } </script> </html>
效果:
ThreeJS使用右手坐标系,辅助轴AxesHelper中红、绿、蓝线段分别表示x、y、z三个轴