百度地图做电子围栏总结

先上图:
这里写图片描述
需求:在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。
这里写图片描述
这里写图片描述
主要的难点(对于我而言)不在于画,而在于设置地图视野和围栏区域的中心点显示围栏名称,其实也不算难,主要是花比较多时间去看百度地图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()显示隐藏会快很多。

猜你喜欢

转载自blog.csdn.net/liangrongliu1991/article/details/80582060