欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

百度地图做电子围栏总结

程序员文章站 2022-04-30 13:37:41
...

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

主要的难点(对于我而言)不在于画,而在于设置地图视野和围栏区域的中心点显示围栏名称,其实也不算难,主要是花比较多时间去看百度地图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()显示隐藏会快很多。

相关标签: 百度地图