百度地图做电子围栏总结

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()显示隐藏会快很多。



  • 2017-09-14 10:18:25

    15分钟成为Git专家

    不管是以前使用过 Git 还是刚开始使用这个神奇的版本控制工具的开发者,阅读了本文以后都会收获颇丰。如果你是应一名有经验的 GIT 使用者,你会更好的理解 checkout -> modify -> commit 这个过程。如果你刚开始使用 Git,本文将给你一个很好的开端。

  • 2017-09-28 16:42:57

    Linux vmstat命令实战详解

    vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令,一个是Linux/Unix都支持,二是相比top,我可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。

  • 2017-10-13 16:21:29

    Activity的四种launchMode

    launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。

  • 2017-10-16 16:45:45

    Android开发技巧:Application和Instance

    在开发过程中,我们经常会需要用到一些全局的变量或者全局的“管理者”,例如QQ,需要有一个“全局的管理者“保存好友信息,各个activity即可直接通过该”管理者“来获取和修改某个好友信息,显然,这样的一个好友信息,保存到某一个具体的activity里面,然后依靠activity的intent来传递参数是不合适。我们有两种方法来实现这样一个全局的管理者,一种是使用C++/Java中常用的单例模式,另一种是利用Android的Application类,下面一一阐述。

  • 2017-11-01 01:30:45

    解决第三方包内jar包冲突

    这个问题就是因为引入jar包的冲突,这时我们可以在build.gradle中添加如下代码,下方单独的是添加的代码

  • 2017-11-06 01:00:17

    撤销git add

    如何撤销git add,不小心执行了git add . 操作,但是又不能提交所有的文件,因为对应不同的分支,现在怎么样可以将git add 撤销回来

  • 2017-11-10 00:06:15

    CORS: credentials mode is 'include'

    XMLHttpRequest cannot load http://localhost/Foo.API/token. The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:5000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.