ThreeJS读取GeoJson文件,绘制地图板

Posted 昜木辰 de ブログ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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三个轴

 

以上是关于ThreeJS读取GeoJson文件,绘制地图板的主要内容,如果未能解决你的问题,请参考以下文章

百度地图threejs相关

是否可以在 R 中读取 geoJSON 或 topoJSON 文件来绘制等值线图?

gis和threejs的学习资料

采用threejs加载geojson案例

使用python的bokeh包及geojson数据绘制地图

THREE.JS学习使用THREEJS加载GeoJSON地图数据