• vue 引入
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=123123123"></script><script type="text/javascript" src="<%BASE_URL%>utils/TextIconOverlay_min.js"></script>
<script type="text/javascript" src="<%BASE_URL%>utils/MarkerClusterer.js"></script>
  • 使用
createMap(res) {// 百度地图API功能let map = new BMap.Map("allmap");let [mapData, that] = [this.$store.state.map, this];map.centerAndZoom(new BMap.Point(mapData.position.jd, mapData.position.wd),mapData.scale);map.enableScrollWheelZoom();let markers = [];res.data.map(item => {let pt = new BMap.Point(item.Jd, item.Wd);// 监听点事件const [success, error] = [new BMap.Icon(require('@/assets/home/success.png'), new BMap.Size(36, 36)),new BMap.Icon(require('@/assets/home/error.png'), new BMap.Size(36, 36)),]let marker = nullif (item.CurrentEventState == '正常') {marker = new BMap.Marker(pt, { icon: success }); // 创建点} else {marker = new BMap.Marker(pt, { icon: error }); // 创建点}const attribute = () => {this.next(item);};marker.addEventListener("click", attribute);markers.push(marker);});// 获取地图缩放级别map.addEventListener("zoomend", function () {that.$store.commit("map", { scale: this.getZoom() });});// 获取拖拽后地图经纬度信息map.addEventListener("dragend", function () {let center = map.getCenter();that.$store.commit("map", {position: { jd: center.lng, wd: center.lat }});});// 生成一个marker数组,然后调用markerClusterer类即可let markerClusterer = new BMapLib.MarkerClusterer(map, {markers,gridSize: 30 // 聚合面积});
}
  • MarkerClusterer.js
/*** @fileoverview MarkerClusterer标记聚合器用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。* 主入口类是<a href="symbols/BMapLib.MarkerClusterer.html">MarkerClusterer</a>,* 基于Baidu Map API 1.2。** @author Baidu Map Api Group * @version 1.2*//** * @namespace BMap的所有library类均放在BMapLib命名空间下*/
var BMapLib = window.BMapLib = BMapLib || {};
(function () {/*** 获取一个扩展的视图范围,把上下左右都扩大一样的像素值。* @param {Map} map BMap.Map的实例化对象* @param {BMap.Bounds} bounds BMap.Bounds的实例化对象* @param {Number} gridSize 要扩大的像素值** @return {BMap.Bounds} 返回扩大后的视图范围。*/var getExtendedBounds = function (map, bounds, gridSize) {bounds = cutBoundsInRange(bounds);var pixelNE = map.pointToPixel(bounds.getNorthEast());var pixelSW = map.pointToPixel(bounds.getSouthWest());pixelNE.x += gridSize;pixelNE.y -= gridSize;pixelSW.x -= gridSize;pixelSW.y += gridSize;var newNE = map.pixelToPoint(pixelNE);var newSW = map.pixelToPoint(pixelSW);return new BMap.Bounds(newSW, newNE);};/*** 按照百度地图支持的世界范围对bounds进行边界处理* @param {BMap.Bounds} bounds BMap.Bounds的实例化对象** @return {BMap.Bounds} 返回不越界的视图范围*/var cutBoundsInRange = function (bounds) {var maxX = getRange(bounds.getNorthEast().lng, -180, 180);var minX = getRange(bounds.getSouthWest().lng, -180, 180);var maxY = getRange(bounds.getNorthEast().lat, -74, 74);var minY = getRange(bounds.getSouthWest().lat, -74, 74);return new BMap.Bounds(new BMap.Point(minX, minY), new BMap.Point(maxX, maxY));};/*** 对单个值进行边界处理。* @param {Number} i 要处理的数值* @param {Number} min 下边界值* @param {Number} max 上边界值* * @return {Number} 返回不越界的数值*/var getRange = function (i, mix, max) {mix && (i = Math.max(i, mix));max && (i = Math.min(i, max));return i;};/*** 判断给定的对象是否为数组* @param {Object} source 要测试的对象** @return {Boolean} 如果是数组返回true,否则返回false*/var isArray = function (source) {return '[object Array]' === Object.prototype.toString.call(source);};/*** 返回item在source中的索引位置* @param {Object} item 要测试的对象* @param {Array} source 数组** @return {Number} 如果在数组内,返回索引,否则返回-1*/var indexOf = function (item, source) {var index = -1;if (isArray(source)) {if (source.indexOf) {index = source.indexOf(item);} else {for (var i = 0, m; m = source[i]; i++) {if (m === item) {index = i;break;}}}}return index;};/***@exports MarkerClusterer as BMapLib.MarkerClusterer*/var MarkerClusterer =/*** MarkerClusterer* @class 用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能* @constructor* @param {Map} map 地图的一个实例。* @param {Json Object} options 可选参数,可选项包括:<br />*    markers {Array<Marker>} 要聚合的标记数组<br />*    girdSize {Number} 聚合计算时网格的像素大小,默认60<br />*    maxZoom {Number} 最大的聚合级别,大于该级别就不进行相应的聚合<br />*    minClusterSize {Number} 最小的聚合数量,小于该数量的不能成为一个聚合,默认为2<br />*    isAverangeCenter {Boolean} 聚合点的落脚位置是否是所有聚合在内点的平均值,默认为否,落脚在聚合内的第一个点<br />*    styles {Array<IconStyle>} 自定义聚合后的图标风格,请参考TextIconOverlay类<br />*/BMapLib.MarkerClusterer = function (map, options) {if (!map) {return;}this._map = map;this._markers = [];this._clusters = [];var opts = options || {};this._gridSize = opts["gridSize"] || 1000 / map.getZoom();this._maxZoom = opts["maxZoom"] || 18;this._minClusterSize = opts["minClusterSize"] || 3;this._isAverageCenter = false;if (opts['isAverageCenter'] != undefined) {this._isAverageCenter = opts['isAverageCenter'];}this._styles = opts["styles"] || [];var that = this;var mkrs = opts["markers"];this._map.addEventListener("zoomend", function (lv) {let lvl = lv.target.getZoom();that._gridSize = 1000 / lvl;that._redraw();});this._map.addEventListener("moveend", function () {that._redraw();});isArray(mkrs) && this.addMarkers(mkrs);};/*** 添加要聚合的标记数组。* @param {Array<Marker>} markers 要聚合的标记数组** @return 无返回值。*/MarkerClusterer.prototype.addMarkers = function (markers) {for (var i = 0, len = markers.length; i < len; i++) {this._pushMarkerTo(markers[i]);}this._createClusters();};/*** 把一个标记添加到要聚合的标记数组中* @param {BMap.Marker} marker 要添加的标记** @return 无返回值。*/MarkerClusterer.prototype._pushMarkerTo = function (marker) {// var index = indexOf(marker, this._markers);//if (index === -1) {marker.isInCluster = false;this._markers.push(marker); //Marker拖放后enableDragging不做变化,忽略// }};/*** 添加一个聚合的标记。* @param {BMap.Marker} marker 要聚合的单个标记。* @return 无返回值。*/MarkerClusterer.prototype.addMarker = function (marker) {this._pushMarkerTo(marker);this._createClusters();};/*** 根据所给定的标记,创建聚合点,并遍历所有聚合点* @return 无返回值*/MarkerClusterer.prototype._createClusters = function () {var mapBounds = this._map.getBounds();var extendedBounds = getExtendedBounds(this._map, mapBounds, this._gridSize);let temp = [];for (var i = 0, marker; marker = this._markers[i]; i++) {if (extendedBounds.containsPoint(marker.getPosition())) {if (!marker.isInCluster) {temp.push(marker);}}}let bd = new Date();if (temp.length > 0) {for (var j = 0, mk; mk = temp[j]; j++) {this._addToClosestCluster(mk);}}var len = this._clusters.length;for (var i = 0; i < len; i++) {if (this._clusters[i]) {this._clusters[i].render();}}};/*** 根据标记的位置,把它添加到最近的聚合中* @param {BMap.Marker} marker 要进行聚合的单个标记** @return 无返回值。*/MarkerClusterer.prototype._addToClosestCluster = function (marker) {//var distance = 4000000;var dis2 = 16000000000000, d1, d2, d;var clusterToAddTo = null;var position = marker.getPosition();for (var i = 0, cluster; cluster = this._clusters[i]; i++) {var center = cluster.getCenter();if (center) {d1 = center.lng - position.lng;d2 = center.lat - position.lat;d = d1 * d1 + d2 * d2;if (d < dis2) {dis2 = d;clusterToAddTo = cluster;}// var d = this._map.getDistance(center, position);// if (d < distance) {//   distance = d;//   clusterToAddTo = cluster;// }}}if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {clusterToAddTo.addMarker(marker);} else {var cluster = new Cluster(this);cluster.addMarker(marker);this._clusters.push(cluster);}};/*** 清除上一次的聚合的结果* @return 无返回值。*/MarkerClusterer.prototype._clearLastClusters = function () {for (var i = 0, cluster; cluster = this._clusters[i]; i++) {cluster.remove();}this._clusters = []; //置空Cluster数组this._removeMarkersFromCluster(); //把Marker的cluster标记设为false};/*** 清除某个聚合中的所有标记* @return 无返回值*/MarkerClusterer.prototype._removeMarkersFromCluster = function () {for (var i = 0, marker; marker = this._markers[i]; i++) {marker.isInCluster = false;}};/*** 把所有的标记从地图上清除* @return 无返回值*/MarkerClusterer.prototype._removeMarkersFromMap = function () {for (var i = 0, marker; marker = this._markers[i]; i++) {marker.isInCluster = false;this._map.removeOverlay(marker);}};/*** 删除单个标记* @param {BMap.Marker} marker 需要被删除的marker** @return {Boolean} 删除成功返回true,否则返回false*/MarkerClusterer.prototype._removeMarker = function (marker) {var index = indexOf(marker, this._markers);if (index === -1) {return false;}this._map.removeOverlay(marker);this._markers.splice(index, 1);return true;};/*** 删除单个标记* @param {BMap.Marker} marker 需要被删除的marker** @return {Boolean} 删除成功返回true,否则返回false*/MarkerClusterer.prototype.removeMarker = function (marker) {var success = this._removeMarker(marker);if (success) {this._clearLastClusters();this._createClusters();}return success;};/*** 删除一组标记* @param {Array<BMap.Marker>} markers 需要被删除的marker数组** @return {Boolean} 删除成功返回true,否则返回false*/MarkerClusterer.prototype.removeMarkers = function (markers) {var success = false;for (var i = 0; i < markers.length; i++) {var r = this._removeMarker(markers[i]);success = success || r;}if (success) {this._clearLastClusters();this._createClusters();}return success;};/*** 从地图上彻底清除所有的标记* @return 无返回值*/MarkerClusterer.prototype.clearMarkers = function () {this._clearLastClusters();this._removeMarkersFromMap();this._markers = [];};/*** 重新生成,比如改变了属性等* @return 无返回值*/MarkerClusterer.prototype._redraw = function (mkrs) {this._clearLastClusters();this._createClusters();};/*** 获取网格大小* @return {Number} 网格大小*/MarkerClusterer.prototype.getGridSize = function () {return this._gridSize;};/*** 设置网格大小* @param {Number} size 网格大小* @return 无返回值*/MarkerClusterer.prototype.setGridSize = function (size) {this._gridSize = size;this._redraw();};/*** 获取聚合的最大缩放级别。* @return {Number} 聚合的最大缩放级别。*/MarkerClusterer.prototype.getMaxZoom = function () {return this._maxZoom;};/*** 设置聚合的最大缩放级别* @param {Number} maxZoom 聚合的最大缩放级别* @return 无返回值*/MarkerClusterer.prototype.setMaxZoom = function (maxZoom) {this._maxZoom = maxZoom;this._redraw();};/*** 获取聚合的样式风格集合* @return {Array<IconStyle>} 聚合的样式风格集合*/MarkerClusterer.prototype.getStyles = function () {return this._styles;};/*** 设置聚合的样式风格集合* @param {Array<IconStyle>} styles 样式风格数组* @return 无返回值*/MarkerClusterer.prototype.setStyles = function (styles) {this._styles = styles;this._redraw();};/*** 获取单个聚合的最小数量。* @return {Number} 单个聚合的最小数量。*/MarkerClusterer.prototype.getMinClusterSize = function () {return this._minClusterSize;};/*** 设置单个聚合的最小数量。* @param {Number} size 单个聚合的最小数量。* @return 无返回值。*/MarkerClusterer.prototype.setMinClusterSize = function (size) {this._minClusterSize = size;this._redraw();};/*** 获取单个聚合的落脚点是否是聚合内所有标记的平均中心。* @return {Boolean} true或false。*/MarkerClusterer.prototype.isAverageCenter = function () {return this._isAverageCenter;};/*** 获取聚合的Map实例。* @return {Map} Map的示例。*/MarkerClusterer.prototype.getMap = function () {return this._map;};/*** 获取所有的标记数组。* @return {Array<Marker>} 标记数组。*/MarkerClusterer.prototype.getMarkers = function () {return this._markers;};/*** 获取聚合的总数量。* @return {Number} 聚合的总数量。*/MarkerClusterer.prototype.getClustersCount = function () {var count = 0;for (var i = 0, cluster; cluster = this._clusters[i]; i++) {cluster.isReal() && count++;}return count;};/*** @ignore* Cluster* @class 表示一个聚合对象,该聚合,包含有N个标记,这N个标记组成的范围,并有予以显示在Map上的TextIconOverlay等。* @constructor* @param {MarkerClusterer} markerClusterer 一个标记聚合器示例。*/function Cluster(markerClusterer) {this._markerClusterer = markerClusterer;this._map = markerClusterer.getMap();this._minClusterSize = markerClusterer.getMinClusterSize();this._isAverageCenter = markerClusterer.isAverageCenter();this._center = null; //落脚位置this._markers = []; //这个Cluster中所包含的markersthis._gridBounds = null; //以中心点为准,向四边扩大gridSize个像素的范围,也即网格范围this._isReal = false; //真的是个聚合this._clusterMarker = new BMapLib.TextIconOverlay(this._center, this._markers.length, {"styles": this._markerClusterer.getStyles()});//this._map.addOverlay(this._clusterMarker);}/*** 向该聚合添加一个标记。* @param {Marker} marker 要添加的标记。* @return 无返回值。*/Cluster.prototype.addMarker = function (marker) {if (this.isMarkerInCluster(marker)) {return false;}//也可用marker.isInCluster判断,外面判断OK,这里基本不会命中if (!this._center) {this._center = marker.getPosition();this.updateGridBounds(); //} else {if (this._isAverageCenter) {var l = this._markers.length + 1;var lat = (this._center.lat * (l - 1) + marker.getPosition().lat) / l;var lng = (this._center.lng * (l - 1) + marker.getPosition().lng) / l;this._center = new BMap.Point(lng, lat);this.updateGridBounds();} //计算新的Center}marker.isInCluster = true;this._markers.push(marker);};/*** 进行dom操作* @return 无返回值*/Cluster.prototype.render = function () {var len = this._markers.length;if (len < this._minClusterSize) {for (var i = 0; i < len; i++) {this._map.addOverlay(this._markers[i]);}} else {this._map.addOverlay(this._clusterMarker);this._isReal = true;this.updateClusterMarker();}}/*** 判断一个标记是否在该聚合中。* @param {Marker} marker 要判断的标记。* @return {Boolean} true或false。*/Cluster.prototype.isMarkerInCluster = function (marker) {if (this._markers.indexOf) {return this._markers.indexOf(marker) != -1;} else {for (var i = 0, m; m = this._markers[i]; i++) {if (m === marker) {return true;}}}return false;};/*** 判断一个标记是否在该聚合网格范围中。* @param {Marker} marker 要判断的标记。* @return {Boolean} true或false。*/Cluster.prototype.isMarkerInClusterBounds = function (marker) {return this._gridBounds.containsPoint(marker.getPosition());};Cluster.prototype.isReal = function (marker) {return this._isReal;};/*** 更新该聚合的网格范围。* @return 无返回值。*/Cluster.prototype.updateGridBounds = function () {var bounds = new BMap.Bounds(this._center, this._center);this._gridBounds = getExtendedBounds(this._map, bounds, this._markerClusterer.getGridSize());};/*** 更新该聚合的显示样式,也即TextIconOverlay。* @return 无返回值。*/Cluster.prototype.updateClusterMarker = function () {if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) {this._clusterMarker && this._map.removeOverlay(this._clusterMarker);for (var i = 0, marker; marker = this._markers[i]; i++) {this._map.addOverlay(marker);}return;}if (this._markers.length < this._minClusterSize) {this._clusterMarker.hide();return;}this._clusterMarker.setPosition(this._center);this._clusterMarker.setText(this._markers.length);var thatMap = this._map;var thatBounds = this.getBounds();this._clusterMarker.addEventListener("click", function (event) {thatMap.setViewport(thatBounds);});};/*** 删除该聚合。* @return 无返回值。*/Cluster.prototype.remove = function () {for (var i = 0, m; m = this._markers[i]; i++) {this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]);} //清除散的标记点this._map.removeOverlay(this._clusterMarker);this._markers.length = 0;delete this._markers;}/*** 获取该聚合所包含的所有标记的最小外接矩形的范围。* @return {BMap.Bounds} 计算出的范围。*/Cluster.prototype.getBounds = function () {var bounds = new BMap.Bounds(this._center, this._center);for (var i = 0, marker; marker = this._markers[i]; i++) {bounds.extend(marker.getPosition());}return bounds;};/*** 获取该聚合的落脚点。* @return {BMap.Point} 该聚合的落脚点。*/Cluster.prototype.getCenter = function () {return this._center;};
})();

百度地图点聚合优化重写相关推荐

  1. 百度地图点聚合MarkerClusterer性能优化

    公司要求做个百度地图点聚合的性能优化,需一次性加载9万条数据. 记录下自己的优化过程.(只想看优化代码的可直接移步:步骤三) 一.引入百度地图 vue项目中,在index.html文件中用script ...

  2. 百度地图点聚合提高效率

    百度的点聚合算法 是基于方格和距离的聚合算法,即开始的时候地图上没有任何已知的聚合点,然后遍历所有的点,去计算点的外包正方形(由gridSize指定),若此点的外包正方形与现有的聚合点的外包正方形不相 ...

  3. 百度地图 点聚合_强强联合聚能网约车场景 首汽约车为百度地图“站台”

    人与出行的关系在不断刷新,关于地图的重新定义也正在进行时.12月10日,2019百度地图生态大会在京召开,"新一代人工智能地图"生态全景首次公布,百度地图成为中国最大的智能化位置服 ...

  4. 百度地图 标记聚合器MarkerClusterer结合TextIconOverlay,根据标记点的属性更换聚合器的样式

    一.问题 公司的项目中在百度地图上生成了成千上万的点,所以使用了标记聚合器MarkerClusterer来处理海量点,但是每个点根据异常类型,分为正常(绿色)和异常(红色),这时如果用了聚合器,只有没 ...

  5. 百度地图点聚合功能php,百度地图js lite api 支持点聚合

    百度地图lite api 是专门为h5 绘制海量点设计的,但是偏偏忽略掉了点聚合的需求,所以需要自己动手,做一次二次改造. 我们知道点聚合需要引入开源库: MarkerClusterer:  http ...

  6. 百度地图点聚合功能如何提高性能

    点聚合提高加载效率 百度示例上面的点聚合功能加载到一万个点就有点卡了,下面进入代码部分 map_juhe.html <!DOCTYPE html> <html lang=" ...

  7. vue百度地图引入聚合,点击聚合,label被清理掉问题解决。同步异步问题

    如果你是同步请求 建议先看我上篇文章 我的上篇文章 直接在index.html里面加 <script type="text/javascript" src="htt ...

  8. 百度地图 - 点聚合方式批量渲染坐标点

    最近在做一个大数据人员分布的系统,需要能够在地图上渲染数据库中的坐标点,大概有四万个坐标点,普通的渲染方式会导致客户端崩溃的,或者是坐标点太过于密集,用户体验差.于是使用了百度地图的点聚合方式,特此记 ...

  9. 解决 百度地图多点聚合卡顿问题

    由于百度地图提供的MarkerClusterer_min.js 比较卡顿 特此提供加速后的MarkerClusterer_min.js 源码如下 /*** @fileoverview MarkerCl ...

最新文章

  1. matlab添加多个legend
  2. 安全操作中心之于SDN
  3. Android热更新方案Robust
  4. Android运行Socket项目时出现错误 Error: ShouldNotReachHere()
  5. String,StringBuffer,StringBuilder简单对比
  6. vlookup练习_那个vlookup,我总是学不会啊
  7. Mongodb源码分析--Mongos之分布式锁
  8. 案例实操-Top10热门品类
  9. PyCharm下载及使用
  10. PCB Web版SI9000阻抗计算器
  11. TCP/IP、HTTP、HTTPS
  12. 电脑系统声音怎么录制 如何录制电脑内部音频
  13. Android Studio 之万恶 gradle
  14. unity3d 中能画出漂亮图案的函数之玫瑰图案
  15. 2020版idea ij 创建web项目和以往稍有不同。
  16. 微信域名防封防屏蔽 微信APP下载链接如何做防封防屏蔽
  17. 多柱汉诺塔问题Hanoi 动态规划求解方案数
  18. 两台笔记本电脑共享屏幕(其中一台电脑当做另外一台电脑的扩展屏幕,多屏显示)
  19. c语言中如何求双胞胎素数,征求好的算法:输出十万以内的双胞胎素数
  20. java报错Non Zero Exit Code?其实是在不断读入数据,留有条件终止读入即可

热门文章

  1. K_A02_003 基于单片机驱动8位数码管模块(MAX7219) 0-7静态显示+滚动显示
  2. 【智能制造】全球人工智能与制造业融合的现状及思考
  3. 看不到inter信息服务器,解决win10系统internet信息服务(iis)管理器找不到的方法
  4. 华为 OSPF基本概念与基础配置
  5. 计算机体系结构2030:未来15年的研究愿景*Mark Hill
  6. 《程序员》 -- 技术团队新官上任之高层篇
  7. 数字电路3-8译码器
  8. 云师大计算机调剂,云南师范大学2020考研调剂公告
  9. 从两道基础二分算法题谈check函数的写法
  10. Python把mp4视频转化成gif动图