百度地图做电子围栏总结

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



  • 2020-12-15 20:06:43

    更多WebTorrent例子

    WebTorrent是第一个运行在浏览器的Torrent客户端。是的,没错。就是浏览器! 它完全是用JavaScript编写的,并使用WebRTC实现了真正的点对点传输。不需要浏览器插件、扩展或安装。 使用开放的Web标准,WebTorrent将网站用户连接在一起,形成一个分布式的、分散的Browser-to-browser网络,以实现高效的文件传输。

  • 2020-12-16 06:43:06

    WebRTC 实现Android点到点互连(含Demo)

    WebRTC被誉为是web长期开源开发的一个新启元,是近年来web开发的最重要创新。WebRTC允许Web开发者在其web应用中添加视频聊天或者点对点数据传输,不需要复杂的代码或者昂贵的配置。目前支持Chrome、Firefox和Opera,后续会支持更多的浏览器,它有能力达到数十亿的设备。

  • 2020-12-16 22:04:03

    基于本地代理的边下边播技术分析

    我们熟知的边下边播技术,是迅雷提供的,还有之前的快播、快车等工具,它们使用的技术基本上都是P2P下载技术。 P2P下载技术,本质上它并不是C-S的架构,P2P----> Peer to Peer,实际上它将各个客户端的资源调度起来,给上传资源种子,方便后续的下载者可以快速有效的下载资源,这种方式需要服务器整合各个Client,在有用户需要下载的情况下,服务器能及时调度资源,开始给下载者提供资源信息,保证下载者下载资源越快越好。P2P的下载方式后面我们专门介绍一下。这儿不继续展开了。

  • 2020-12-16 22:07:44

    Android视频点播-边播边缓存

    一些知名的视频app客户端(优酷,爱奇艺)播放视频的时候都有一些缓存进度(二级进度缓存),qq,微信有关的小视频,还有一些短视频app,都有边播边缓的处理。还有就是当文件缓存完毕了再次播放的话就不再请求网络了直接播放本地文件了。既节省了流程又提高了加载速度。 今天我们就是来研究讨论实现这个边播边缓存的框架,因为它不和任何的业务逻辑耦合。

  • 2020-12-16 22:46:44

    基于coturn项目的stun/turn服务器搭建

    webrtc是google推出的基于浏览器的实时语音-视频通讯架构。其典型的应用场景为:浏览器之间端到端(p2p)实时视频对话,但由于网络环境的复杂性(比如:路由器/交换机/防火墙等),浏览器与浏览器很多时候无法建立p2p连接,只能通过公网上的中继服务器(也就是所谓的turn服务器)中转。示例图如下:

  • 2020-12-16 23:06:05

    Rocket.Chat推送信息

    Rocket.Chat推送消息 Rocket.Chat是一个开源实时通讯平台, 支持Windows, Mac OS, Linux. 支持聊天, 文件上传, 视频通话, 语音通话功能. 向Rocket.Chat推送消息 以下示例可以转为别的语言的版本, 本示例使用Linux平台的curl测试, curl非常强大. 登陆 首先需要登陆Rocket.Chat服务器

  • 2020-12-17 09:01:23

    对BitTorrent Tracker源码分析

    tracker服务器是BT下载中必须的角色。一个BT client 在下载开始以及下载进行的过程中,要不停的与 tracker 服务器进行通信,以报告自己的信息,并获取其它下载client的信息。这种通信是通过 HTTP 协议进行的,又被称为 tracker HTTP 协议,它的过程是这样的: client 向 tracker 发一个HTTP 的GET请求,并把它自己的信息放在GET的参数中;这个请求的大致意思是:我是xxx(一个唯一的id),我想下载yyy文件,我的ip是aaa,我用的端口是bbb。。。