美文网首页GISgiswebGIS
高德地图二次封装组件库(三维视图)

高德地图二次封装组件库(三维视图)

作者: WebGis学习笔记 | 来源:发表于2019-03-21 15:19 被阅读25次

    公司最近做了一个关于环保的项目有很多地方要求强烈的可视化,如果使用公司之前技术ArcGis表示有点寸步难行,所以我就提出可以使用高德地图试试,结果效果还挺好,对高德地图的一些可视化UI和语法熟悉之后,就想,东西都在这里了,码来码去也是这几句代码为何不将通用组件抽离出来呢,后来我就将组件一块一块封装成了我们系统风格的通用组件,要哪个用哪个个人感觉还挺不错嘻嘻嘻,不足之处还请大佬们见谅。
    -------------------------------------文章原创转载请注明出处!----------------------------------

    函数目录:

    Amap:
           test: test, //1.测试方法(可变参数)
           district: district, //2.区域掩模(区域名称{佛山},[中心值])
           flight: flight, //3.飞行(1.地图实例2.飞行前位置3.飞行后位置、4.飞行后缩放级别,5.回调函数);
           addDragRoute: addDragRoute, //4.绘制消防路线(1.地图实例2.终点位置3.起点位置4.起点名称5.起点图片路径)
           ArrayDragRoute: ArrayDragRoute, //5.数据集合
           getDragRoute: (id) => ArrayDragRoute[id], //6.通过ID获取消防路线对象
           removerDragRoute: removerDragRoute, //7.删除路线    
           addScan: addScan, //8.添加扫描动画
           removerScan: removerScan, //9.删除扫描动画
           showScan: showScan, //10,显示扫描动画
           hideScan: hideScan, //11.隐藏扫描动画
           addCircle: addCircle, //12.添加扫描区
           rotate: rotate, //13.旋转地图
           addDiffuse: addDiffuse ,//14.扩散
           Srotate : Srotate//15.旋转
    Autil:
          randomNum: randomNum, //获取随机数(最小值,最大值)
           voice: voice //语音播报(百度AI)
    

    使用效果:

    广州地块(区域掩模+自定义底图)

    广州地块(区域掩模+自定义底图)
    /**
     * add by Javan 2018-11-21 通过exports,define二次封装高德地图接口
     */
    (function(root, mapfactory, utilfactory) {
        if (typeof define === 'function' && define.amd) {
            console.dir("----- AMD. Register as an anonymous module. -----")
            // AMD. Register as an anonymous module.
            define([], mapfactory);
        } else if (typeof module === 'object' && module.exports) {
            console.log(
                "----- Node. Does not work with strict CommonJS, butonly CommonJS-like environments that support module.exports,like Node. -----"
            )
            // Node. Does not work with strict CommonJS, but
            // only CommonJS-like environments that support module.exports,
            // like Node.
            module.exports = mapfactory();
        } else {
            console.log("----- Browser globals (root is window) -----")
            // Browser globals (root is window)
            root.Amap = mapfactory();
            root.Autil = utilfactory();
        }
    })(this, function() {
        //定义一些常量
        var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
        //1.区域掩模划分行政区参数
        var opts = {
            subdistrict: 0,
            extensions: 'all',
            level: 'district'
        };
    
        //圆形文字配置
        var map_circleType = function(center) {
            return [{
                "center": center,
                "radius": 700,
                "fillColor": "blue",
                "strokeWeight": 1,
                "strokeColor": "white",
                "fillOpacity": 0.05,
                "isHide": false
            }, {
                "center": center,
                "radius": 500,
                "fillColor": "blue",
                "strokeWeight": 1,
                "strokeColor": "white",
                "fillOpacity": 0.05,
                "isHide": false
            }, {
                "center": center,
                "radius": 300,
                "fillColor": "blue",
                "strokeWeight": 1,
                "strokeColor": "white",
                "fillOpacity": 0.05,
                "isHide": false
            }];
        }
    
        //消防数据数组
        let ArrayDragRoute = {};
        //扫描3Dlayer
        let ArrayScan = {};
        //圆形数组
        let ArrayCircle = {};
    
    
        /**
         * 测试方法
         */
        var test = function test() {
            var s = '';
            var numargs = arguments.length; // 获取实际被传递参数的数值。
            s += (numargs + "个参数。");
    
            s += "\n\n"
            for (i = 0; i < numargs; i++) { // 获取参数内容。
                s += " 第" + i + "个参数是:" + arguments[i] + "\n";
            }
            return (s); // 返回参数列表。
        };
    
    
        //1.利用行政区查询获取边界构建mask路径
        var district = function district(Aarea, f, Af) {
            var district = new AMap.DistrictSearch(opts);
            var bounds;
            var map;
            district.search(Aarea, function(status, result) {
                bounds = result.districtList[0].boundaries;
                //删除龙岗区部分
                //bounds.splice(1, 1);
                var mask = []
                for (var i = 0; i < bounds.length; i += 1) {
                    mask.push([bounds[i]])
                }
                map = f(mask);
                //添加高度面
                var object3Dlayer = new AMap.Object3DLayer({
                    zIndex: 1
                });
                map.add(object3Dlayer)
    
                var height = -8000;
                var color = '#0088ffcc'; //侧边颜色
                var wall = new AMap.Object3D.Wall({
                    path: bounds,
                    height: height,
                    color: color
                });
                wall.transparent = true
                object3Dlayer.add(wall)
    
    
                //添加描边
                for (var i = 0; i < bounds.length; i += 1) {
                    new AMap.Polyline({
                        path: bounds[i],
                        strokeColor: '#99ffff', //边线颜色
                        strokeWeight: 4,
                        map: map
                    })
                }
                //添加业务回调
                Af();
            });
        }
    
        //飞行定位
        //1.地图实例
        //2.飞行前位置
        //3.飞行后位置、
        //4.飞行后缩放级别
        //5.回调函数
        var flight = function flight(Amap, AoldCoord, AnewCoord, AideaZoom, AzoomFuncaiton) {
            var zoom = Amap.getZoom() - 1;
            var flag = false;
            //循环执行,每隔1秒钟执行一次 1000 
            var t1 = window.setInterval(function() {
                if (!flag) {
                    Amap.setZoomAndCenter(zoom, AoldCoord); //同时设置地图层级与中心点
                    zoom = zoom - 1;
                    if (zoom <= 11) {
                        flag = true;
                        AzoomFuncaiton();
                    }
                } else {
                    Amap.setZoomAndCenter(zoom, AnewCoord); //同时设置地图层级与中心点
                    zoom = zoom + 1;
                }
                if (zoom >= AideaZoom) {
                    clearInterval(t1);
                }
            }, 300);
        }
    
        //旋转浏览地图
        //1.地图实例
        //2.飞行前位置
        //3.飞行后位置、
        //4.飞行后缩放级别
        //5.回调函数
        var rotate = function rotate(Amap, AoldCoord, AnewCoord, AideaZoom, AzoomFuncaiton, Arotate) {
            var zoom = Amap.getZoom() - 1;
            var flag = false;
            console.log("当前zoom" + zoom + "," + AideaZoom)
            //      var num = 0;//运行次数
            //      if(zoom > 11){
            //          num = zoom - 11;
            //          num += (AideaZoom - 11);
            //      console.log(num)
            //      }else{
            //          num = 11 - zoom;
            //          num += (AideaZoom -11);
            //      }
            //      //角度差值
            //      console.log("差值"+Amap.getPitch()/num+","+Amap.getPitch()+","+num)
    
            //循环执行,每隔1秒钟执行一次 1000 
            var t1 = window.setInterval(function() {
                if (!flag) {
                    Amap.setZoomAndCenter(zoom, AoldCoord); //同时设置地图层级与中心点
                    zoom = zoom - 1;
    
                    if (zoom <= 11) {
                        flag = true;
                        Amap.setPitch(50); //设置角度
                        AzoomFuncaiton();
                    }
                } else {
                    Amap.setZoomAndCenter(zoom, AnewCoord); //同时设置地图层级与中心点
                    zoom = zoom + 1;
                }
                var pitch = Amap.getPitch()
                //          if(pitch > 50){
                //              Amap.setPitch(pitch - num);
                //          }else{
                //              Amap.setPitch(pitch + num);
                //          }
                console.log(pitch)
                if (zoom >= AideaZoom) {
                    clearInterval(t1);
                    Arotate();
                }
            }, 500);
        }
        var ff = true;
        //旋转
        //1.地图实例
        //2.是否一直旋转
        //3.回调
        var Srotate = function(Amap,flag,f) {
            //console.log(ff)
            let i = 0;
            if(ff){
                ff = false;
                var t1 = window.setInterval(function() {
                    var rotation = Amap.getRotation();
                    Amap.setRotation(rotation + 1);
                    if (rotation >= 355 && !flag) {
                        ff = true;
                        Amap.setRotation(0);
                        clearInterval(t1);
                        f();
                    }
                }, 5);          
            }
        }
    
    
        //3.绘制消防路线
        //0.id
        //1.地图实例
        //2.终点位置
        //3.起点位置
        //4.起点名称
        //5.起点图片路径
        var addDragRoute = function shwoDragRoute(Aid, Amap, Azj_coord, Axf_coord, Axf_name, Axf_url) {
            var path = [];
            var obj = {};
            path.push(Axf_coord);
            path.push(Azj_coord);
            Amap.plugin("AMap.DragRoute", function() {
                //REAL_TRAFFIC 考虑实时路况
                //LEAST_TIME   最快捷模式
                //LEAST_FEE    最经济模式
                //LEAST_DISTANCE 最短距离模式
                obj.route = new AMap.DragRoute(Amap, path, AMap.DrivingPolicy.REAL_TRAFFIC); //构造拖拽导航类
                obj.route.search(); //查询导航路径并开启拖拽导航
    
            });
            obj.fire_control = new AMap.Marker({
                icon: Axf_url, //'../../images/home/fire_control.png',
                offset: new AMap.Pixel(-32, -54),
                position: Axf_coord,
                map: Amap,
            })
            obj.fire_control_text = new AMap.Text({
                text: Axf_name,
                position: [Axf_coord[0], Axf_coord[1] - 0.00009],
                map: Amap,
                style: {
                    'background-color': '#ccccff',
                    'border-color': 'white',
                    'font-size': '12px'
                }
            })
            //赋值
            ArrayDragRoute[Aid] = obj;
            console.log("----- 增加路线:" + Aid + "成功 -----")
        }
    
        //remover通过ID删除消防路线
        //1.地图实例
        //2.id
        var removerDragRoute = function removerDragRoute(Amap, Aid) {
            let obj = ArrayDragRoute[Aid];
            obj.route.destroy();
            Amap.remove(obj.fire_control);
            Amap.remove(obj.fire_control_text);
            delete ArrayDragRoute[Aid];
            console.log("----- 删除路线:" + Aid + "成功 -----")
        }
    
        //扫描附件敏感建筑
        //1.id
        //2.地图实例
        //3.中心点
        //4.回调函数
        //  var addPlaceSearch = function addPlaceSearch(Aid,Amap,Adata,Acall_back) {
        //      AMap.service(["AMap.PlaceSearch"], function() {
        //          var APlaceSearch;
        //          //构造地点查询类
        //          APlaceSearch = new AMap.PlaceSearch({
        //              //汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|
        //              //医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|交通设施服务|
        //              //金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
        //              type: '购物服务|医疗保健服务|风景名胜|政府机构及社会团体', // 兴趣点类别
        //              pageSize: 5, // 单页显示结果条数
        //              pageIndex: 1, // 页码
        //              city: "佛山", // 兴趣点城市
        //              citylimit: true, //是否强制限制在设置的城市内搜索
        //              map: Amap, // 展现结果的地图实例
        //              panel: "panel", // 结果列表将在此容器中进行展示。
        //              autoFitView: false // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
        //          });
        //          var cpoint = Adata; //中心点坐标
        //          APlaceSearch.searchNearBy('', cpoint, 1000, Acall_back);
        //          ArrayPlaceSearch[Aid] = APlaceSearch;
        //      });
        //  }   
    
        //添加扫描图形
        //0.id
        //1.地图实例
        //2.3D图层
        //3.中心坐标点
        //4.时候定位到扫描点
        var addScan = function addScan(Aid, Amap, data, AcenterFlag) {
            var obj = {};
            if (AcenterFlag) {
                Amap.setZoomAndCenter(16, data);;
            }
            var buildRadar = function() {
                object3Dlayer = new AMap.Object3DLayer();
                Amap.add(object3Dlayer);
                radar = new AMap.Object3D.Mesh();
                radar.transparent = true;
                radar.backOrFront = 'front';
                var geometry = radar.geometry;
                var radius = 1000; //米
                radius = radius / Amap.getResolution(data, 20);
                var unit = 1;
                var range = 200;
                var count = range / unit;
                for (var i = 0; i < count; i += 1) {
                    var angle1 = i * unit * Math.PI / 180;
                    var angle2 = (i + 1) * unit * Math.PI / 180;
                    var p1x = Math.cos(angle1) * radius;
                    var p1y = Math.sin(angle1) * radius;
                    var p2x = Math.cos(angle2) * radius;
                    var p2y = Math.sin(angle2) * radius;
                    geometry.vertices.push(0, 0, 0);
                    geometry.vertices.push(p1x, p1y, 0);
                    geometry.vertices.push(p2x, p2y, 0);
                    var opacityStart = getOpacity(i / count);
                    var opacityEnd = getOpacity((i + 1) / count);
                    geometry.vertexColors.push(0, 1, 0.2, opacityStart);
                    geometry.vertexColors.push(0, 1, 0.2, opacityStart);
                    geometry.vertexColors.push(0, 1, 0.2, opacityEnd);
                }
                radar.position(data);
                object3Dlayer.add(radar);
                obj.radar = radar;
                obj.object3Dlayer = object3Dlayer;
                ArrayScan[Aid] = obj
            };
    
            function getOpacity(scale) {
                return 1 - Math.pow(scale, 0.3);
            }
    
            function scan() {
                radar.rotateZ(-2);
                AMap.Util.requestAnimFrame(scan);
            }
            buildRadar();
            scan();
        }
    
        //删除扫描图形
        var removerScan = function removerScan(Aid) {
            var obj = ArrayScan[Aid];
            if (obj) {
                obj.object3Dlayer.remove(obj.radar);
                delete ArrayScan[Aid];
            }
        }
    
        //显示扫描图形
        var showScan = function showScan(Aid) {
            var obj = ArrayScan[Aid];
            if (obj) {
                obj.object3Dlayer.show();
            }
        }
    
        //隐藏扫描图形
        var hideScan = function hideScan(Aid) {
            var obj = ArrayScan[Aid];
            if (obj) {
                obj.object3Dlayer.hide();
            }
    
        }
    
        //添加圆
        var addCircle = function addCircle(Aid, Amap, data) {
            var array = [];
            data = map_circleType(data);
            $.each(data, function(i, item) {
                var obj = {};
                obj.Circle = new AMap.Circle({
                    map: Amap,
                    center: item.center,
                    radius: item.radius,
                    fillColor: item.fillColor,
                    strokeWeight: item.strokeWeight,
                    strokeColor: item.strokeColor,
                    fillOpacity: item.fillOpacity
                })
                //          if (item.isHide == true) {
                //              map_arrayCircle[i].hide();
                //          }
                obj.Text = new AMap.Text({
                    text: 300 + (i * 200) + '米',
                    // - 0.0027
                    // - 0.0045
                    // - 0.0063
                    // - 0.0018
                    position: [item.center[0], (item.center[1] - 0.0027) - (i * 0.0018)],
                    height: 0,
                    clickable: true, //设置可单击
                    verticalAlign: 'bottom',
                    map: Amap,
                    style: {
                        'background-color': '#00BFFF',
                        'border-color': 'white',
                        'font-size': '12px'
                    }
                })
                array[i] = obj;
            })
            ArrayCircle[Aid] = array;
        }
    
        var arrayDiffuse = {};
        //添加范围动画
        var addDiffuse = (Aid, Amap, data) => {
            /*
             * 添加Canvas图层
             */
            var canvas = document.createElement('canvas');
            canvas.width = canvas.height = 200;
            var context = canvas.getContext('2d')
            context.fillStyle = 'rgb(0,100,255)';
            context.strokeStyle = 'white';
            context.globalAlpha = 1;
            context.lineWidth = 2;
            var radious = 0;
    
    
            var canvasLayer = new AMap.CanvasLayer({
                canvas: canvas,
                bounds: new AMap.Bounds(
                    //114.429656, 22.62341
                    [data[0] - 0.01, data[1] - 0.01], [data[0] + 0.01, data[1] + 0.01]
                ),
                zooms: [3, 18],
            });
            canvasLayer.setMap(Amap);
            var draw = (argument) => {
                context.clearRect(0, 0, 200, 200)
                context.globalAlpha = (context.globalAlpha - 0.01 + 1) % 1;
                radious = (radious + 1) % 100;
    
                context.beginPath();
                context.arc(100, 100, radious, 0, 2 * Math.PI);
                context.fill();
                context.stroke();
                canvasLayer.reFresh() //2D视图时可以省略
                AMap.Util.requestAnimFrame(draw)
            }
            draw();
            arrayDiffuse[Aid] = canvasLayer;
        }
    
        return {
            test: test, //1.测试方法(可变参数)
            district: district, //2.区域掩模(区域名称{佛山},[中心值])
            flight: flight, //3.飞行(1.地图实例2.飞行前位置3.飞行后位置、4.飞行后缩放级别,5.回调函数);
            addDragRoute: addDragRoute, //4.绘制消防路线(1.地图实例2.终点位置3.起点位置4.起点名称5.起点图片路径)
            ArrayDragRoute: ArrayDragRoute, //5.数据集合
            getDragRoute: (id) => ArrayDragRoute[id], //6.通过ID获取消防路线对象
            removerDragRoute: removerDragRoute, //7.删除路线    
            addScan: addScan, //8.添加扫描动画
            removerScan: removerScan, //9.删除扫描动画
            showScan: showScan, //10,显示扫描动画
            hideScan: hideScan, //11.隐藏扫描动画
            addCircle: addCircle, //12.添加扫描区
            rotate: rotate, //13
            addDiffuse: addDiffuse ,//14.扩散
            Srotate : Srotate//15.旋转
        }
    }, function() {
        //获取随机数
        var randomNum = function randomNum(minNum, maxNum) {
            switch (arguments.length) {
                case 1:
                    return parseInt(Math.random() * minNum + 1, 10);
                    break;
                case 2:
                    return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
                    break;
                default:
                    return 0;
                    break;
            }
        }
    
        /**
         * 播放语音
         * 0.ID
         * 1.项目路径
         * 2.播放内容
         * 3.文件名称
         * 4.回显函数
         */
        var voice = function voice(id, serviceUrl, v_text, v_filename, f) {
            //v_text += "发生火灾,已为大鹏新区公安消防支队规划出最近路线!附件人员聚集地多处,风向东南,风力四级
            var param = {};
            param.text = v_text;
            param.aue = "3";
            param.filename = v_filename;
    
            param = JSON.stringify(param);
            $.ajax({
                url: serviceUrl + "/pc/asr/generate",
                //url:serviceUrl,
                type: 'post',
                headers: {
                    "Content-Type": "application/json;charset=UTF-8"
                },
                data: param,
                dataType: "json",
                cache: false,
                async: true,
                success: function(data) {
                    //playSyntheticVoice(id)
                    f($("#" + id), serviceUrl + "/mp3/" + v_filename + ".mp3");
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    //playSyntheticVoice(id)
                    f($("#" + id), serviceUrl + "/mp3/" + v_filename + ".mp3");
                }
            });
        }
    
    
    
    
        return {
            randomNum: randomNum, //获取随机数(最小值,最大值)
            voice: voice
        }
    })
    

    使用说明 :

    <!DOCTYPE HTML>
    <html>
        <head>
            <meta name="viewport" content="width=device-width initial-scale=1.0 maximum-scale=1.0 user-scalable=0">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <title>高德二次封装Demo</title>
            <style>
                body,
                html,
                #container {
                    margin: 0;
                    width: 100%;
                    height: 100%
                }
            </style>
        </head>
        <body>
            <div id="container"></div>
            <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
                    <!-- 高德地图组件库:用到什么就需要引入什么 -->
            <script src="https://webapi.amap.com/maps?v=1.4.10&key=d9c57d1198a6e6b21b5117d4fb4b296e&plugin=Map3D,AMap.DistrictSearch"></script>
            <!-- 二次封装组件库 -->
            <script type="application/javascript" src="js/main.js"></script>
            <script language="javascript">
                var map = {};
                //利用行政区查询获取边界构建mask路径
                //也可以直接通过经纬度构建mask路径
                var bounds = Amap.district('深圳', function(f) {
                    map.map = new AMap.Map('container', {
                        center: [114.157547,22.613086],//中心点位置
                        mask: f,//边界信息,库中获取
                        resizeEnable: true,
                        rotateEnable: true,
                        pitchEnable: true,
                        buildingAnimation: true, //楼块出现是否带动画
                        expandZoomRange: true,
                        viewMode: '3D', //三维地图
                        labelzIndex: 130,
                        pitch: 40, //倾斜度
                        zoom: 10,//缩放级别
                        skyColor: '#41A863', //指定天空颜色
                        mapStyle: 'amap://styles/blue' //添加自定义样式
                    });
                    return map.map;
                }, function() {
                    //给地图绑定单击事件,单击地图地图开始围绕屏幕中心点旋转
                    map.map.on('click', function(e) {
                        console.log(e)
                        Amap.Srotate(map.map, true, function() {
                            console.log("旋转回调!")
                        });
                    });
                });
            </script>
        </body>
    </html>
    

    代码效果:

    深圳三维底图+点击底图旋转浏览

    文章原创转载请注明出处!

    相关文章

      网友评论

        本文标题:高德地图二次封装组件库(三维视图)

        本文链接:https://www.haomeiwen.com/subject/vsngmqtx.html