百度地图做电子围栏总结

2020-02-24 18:36:17

参考地址 百度地图做电子围栏总结

需求:在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。


主要的难点(对于我而言)不在于画,而在于设置地图视野和围栏区域的中心点显示围栏名称,其实也不算难,主要是花比较多时间去看百度地图api,还有动手实践。(所以还是那句老话百度找不到答案就去看api文档,答案都在里面)。

以下主要说一下思路:

1.引入百度地图还有鼠标绘制管理类库DrawingManager


2.以下主要贴部分代码说明:


var electronitFence = {


//此处代码省略...


tableData: {},//保存每次list请求返回的数据

overlayObj: {},//保存图形对象(map)

  labelObj: {},//保存label对象(map)

  path: '',//当前新增围栏图形path

  pointArray: [],//坐标点数组用于调整地图视野范围

styleOptions: {//图形样式

    enableClicking: false,

    strokeColor: "blue",    //边线颜色。

    fillColor: "red",      //填充颜色。当参数为空时,圆形将没有填充效果。

    strokeWeight: 2,       //边线的宽度,以像素为单位。

    strokeOpacity: 0.6,    //边线透明度,取值范围0 - 1。

    fillOpacity: 0.5,      //填充的透明度,取值范围0 - 1。

    strokeStyle: 'solid' //边线的样式,solid或dashed。

  },

  init: function () {

    //此处代码省略...


    this.mapInit();

    this.bindEvent();


   //此处代码省略...


  },

  bindEvent:function(){

    //新增围栏

    $('#overlayType li').on('click', function () {

      var index = $(this).index();

      drawingManager.open();//开启地图的绘制模式

      if (index == 0) {

        drawingManager.setDrawingMode(BMAP_DRAWING_RECTANGLE);//绘制矩形

      } else if (index == 1) {

        drawingManager.setDrawingMode(BMAP_DRAWING_CIRCLE);//绘制圆形

      } else {

        drawingManager.setDrawingMode(BMAP_DRAWING_POLYGON);//绘制多边形

      }

    });

    //全选

    $('#checkAll').on('change', function () {

      if ($(this).is(":checked")) {//全选

        $('#page-list .checkItem').prop("checked", true);

        self.pointArray.length = 0;//清空pointArray

        self.curPageOverlayAllShow();//显示全部

        map.setViewport(self.pointArray); //调整视野

      } else {

        $('#page-list .checkItem').prop("checked", false);

        self.curPageOverlayAllHide();//隐藏全部

      }

    });

    //单选

    $('#page-list').on('change', '.checkItem', function () {

      if ($(this).is(":checked")) {

        if (!$('#checkAll').is(":checked")) {

          $('#checkAll').prop("checked", true);

        }

        self.pointArray.length = 0;//清空pointArray

        self.overlayShow(+$(this).val());//显示

        map.setViewport(self.pointArray); //调整视野

      } else {

        self.overlayHide(+$(this).val());//隐藏

        if ($('.checkItem:checked').length == 0) {

          $('#checkAll').prop("checked", false);

        }

      }

    });

  },

  /**

   * map初始化

   */

  mapInit: function () {

    var self = electronitFence;

    map = new BMap.Map('mapBox', {minZoom: 4, maxZoom: 16});

    map.centerAndZoom(new BMap.Point(116.4035, 39.915), 5);

    map.enableScrollWheelZoom();

    //实例化鼠标绘制工具(我不需要工具栏所以直接注释了)

    drawingManager = new BMapLib.DrawingManager(map, {

      isOpen: false, //是否开启绘制模式

      //enableDrawingTool: false, //是否显示工具栏

      //drawingToolOptions: {

      //anchor: BMAP_ANCHOR_TOP_RIGHT, //位置

      //  offset: new BMap.Size(5, 5) //偏离值

      //},

      circleOptions: self.styleOptions, //圆的样式

      polygonOptions: self.styleOptions, //多边形的样式

      rectangleOptions: self.styleOptions //矩形的样式

    });

    //添加鼠标绘制工具监听事件,用于获取绘制结果

    drawingManager.addEventListener('overlaycomplete', electronitFence.overlayComplete);

  },

  overlayComplete: function (e) {

    var self = electronitFence;

    var path = {};

    var bs = e.overlay.getBounds();//覆盖物对象的地理区域范围

    if (e.drawingMode == BMAP_DRAWING_CIRCLE) {//圆形

      path.radius = e.overlay.getRadius();//半径

      path.center = {};//中心点坐标

      path.center.lng = e.overlay.getCenter().lng;

      path.center.lat = e.overlay.getCenter().lat;

      path.path = [bs.getSouthWest(), bs.getNorthEast()];//****这个是重点:用来保存圆形的地理区域范围(Bounds)东北角和西南角坐标,用于地图视野调整

    } else {//矩形或多边形

      path.data = e.overlay.getPath();

      path.center = bs.getCenter();//****这个是重点:用于在图形中心点显示围栏名称

    }

    self.path = JSON.stringify(path);//这个会传给后端保存,请求回围栏列表数据中会一起返回,用于画出对应的图形


    //此处代码省略...

  },


  //此处代码省略...



  /**

   * 在地图上新建图形

   * @param id

   * @param type

   * @returns {*}

   */

  newOverlay: function (id, type) {

    var self = electronitFence;

    var overlay = null;

    var path = JSON.parse(self.tableData[id].coordinate);//tableData[id]是围栏列表数据,coordinate保存的是上面的path 值

    if (type == 2) {//圆形

      var mPoint = new BMap.Point(path.center.lng, path.center.lat);

      overlay = new BMap.Circle(mPoint, path.radius, style);

      self.pointArray = self.pointArray.concat(path.path);

    } else {//矩形或四边形

      overlay = new BMap.Polygon(path.data, style);

      self.pointArray = self.pointArray.concat(path.data);

    }

    self.overlayObj[id] = {};

    self.overlayObj[id].overlay = overlay;//添加到overlayObj

    map.addOverlay(overlay);

    //创建label,显示围栏名称

    var opts = {position: path.center};

    var label = new BMap.Label(self.tableData[id].fenceName, opts);

    label.setStyle(self.labelStyle);

    label.addEventListener('click', function () {

      var carPath = JSON.parse(self.tableData[id].coordinate);//坐标点

      self.pointArray.length = 0;

      if (type == 2) {//圆

        self.pointArray = carPath.path;

      } else {

        self.pointArray = carPath.data;

      }

      map.setViewport(self.pointArray);    //调整视野

    });

    self.labelObj[id] = {};

    self.labelObj[id].label = label;

    map.addOverlay(label);

  },

  /**

   * 图形显示

   * @param id

   */

  overlayShow: function (id) {

    var self = electronitFence;

    var type = self.tableData[id].coordinateType;//图形类型

    var path = JSON.parse(self.tableData[id].coordinate);//坐标点

    if (self.overlayObj[id]) {//如果overlayObj中有就show

      self.overlayObj[id].overlay.show();

      self.labelObj[id].label.setContent(self.tableData[id].fenceName);

      self.labelObj[id].label.show();

      if (type != 2) {//圆

        self.pointArray = self.pointArray.concat(path.data);

      } else {

        self.pointArray = self.pointArray.concat(path.path);

      }

    } else {//如果overlayObj中无就new一个

      self.newOverlay(id, type);

    }

  },

  /**

   * 图形隐藏

   * @param id

   */

  overlayHide: function (id) {

    electronitFence.overlayObj[id].overlay.hide();

    electronitFence.labelObj[id].label.hide();

  },

/**

   * 显示当前页所有图形

   */

  curPageOverlayAllShow: function () {

    $('.checkItem').each(function () {

      electronitFence.overlayShow(+$(this).val());

    })

  },

  /**

   * 隐藏当前页所有图形

   */

  curPageOverlayAllHide: function () {

    var self = electronitFence;

    $('.checkItem').each(function () {

      var id = +$(this).val();

      if (self.overlayObj[id]) {

        self.overlayHide(id);

      }

    })

  },


 //此处代码省略...

}

$(function () {

  electronitFence.init();

});


总结:可能有人会问为什么不在newOverlay的时候getSouthWest(),getNorthEast(),getCenter()。一开始我也这么做但是根据返回的数据坐标点新建overlay生成的overlay.getBounds()执行报错。目前还不知道原因。。。隐藏overlay,很多人可能都喜欢用map.removeOverlay()的方法直接删掉overlay,下次显示再new。我发现如果overlay很多的时候会new得很慢,如果每次new的时候保存在一个对象里面,直接通过overlay.show(),overlay.hide()显示隐藏会快很多。



  • 2021-02-02 09:42:14

    nuxt.js抽去css文件css代码过多不利于seo

    关于nuxt.js的资料并不是很多,有时候遇到个很简单的问题,百度或者谷歌都不是很容易找到。 其实这个问题就很简单,但是也让我浪费了很多时间,所以在此共勉。

  • 2021-02-03 16:43:11

    Hbase简介

    HBase是一个开源的非关系型分布式数据库,它参考了谷歌的BigTable建模,实现的编程语言为Java。它是Apache软件基金会的Hadoop项目的一部分,运行于HDFS文件系统之上,为 Hadoop 提供类似于BigTable 规模的服务。因此,它可以容错地存储海量稀疏的数据。 作者:Michaelhbjian 链接:https://www.jianshu.com/p/53864dc3f7b4 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 2021-02-03 16:47:05

    use_framework头文件不提示

    1、之前没有用use_frameworks!添加swift库,其他库引用使用#import <xxxx.h> 2、使用use_frameworks!添加swift库后,其他库引用使用#import "xxxx.h"

  • 2021-02-03 16:52:27

    ios静态库和动态库区别

    Framework 是 Cocoa/Cocoa Touch 程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件(nib/xib、图片、国际化文本)、说明文档等集中在一起,方便开发者使用。Framework 其实是资源打包的方式,和静态库动态库的本质是没有什么关系。

  • 2021-02-03 16:57:34

    iOS中的动态库和静态库分析

    由于最近研究组件化后调试时二进制映射源码的功能,发现需要对开发中的动态库和静态库需要有一些了解。所以就有了这篇文章,由于只是了解,并没有深入到编译层面,所以本篇文章只是简单了解一些库的知识,并不深入。

  • 2021-02-03 16:58:39

    iOS静态库与动态库的区别与打包

    这篇主要是记录一下 iOS 下静态库与动态库的打包流程,以便以后用到时快速查阅,供自己也供大家学习记录。同时也简述了一下 动态库 与 静态库 的区别。

  • 2021-02-03 16:59:59

    iOS 静态库和动态库全分析

    库就是程序代码的集合,将 N 个文件组织起来,是共享程序代码的一种方式。从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。