完美解决百度mapMarkerClusterer 移动map时,Marker 的Label 丢失的有关问题
原文:http://www.cnblogs.com/jicheng1014/p/3143859.html
这篇文章来自http://www.cnblogs.com/jicheng1014 不好意思,那些rss 站太生猛了。
先吐槽一下百度地图的开发者,其实这个问题我绝对不是第一个遇到的人
很多人把这个问题提交到了百度Map贴吧,没有人回复,
我记得我几个月前也通过微薄向@百度地图API 反映过这个问题 当时他回复了下去看看,之后就没下文了。
ok,描述下症状
当将自定义的Marker(含有Label)通过MarkerClusterer 管理的时候,当地图发生任何移动、缩放 的时候,Marker 的Label 就会自动消失
关于解决方案
网上我找到了这个解决方案Nautilus 同学的一个解决方案 http://blog.sina.com.cn/s/blog_484d87770101empl.html
屏蔽了Cluster.prototype.remove 中的
this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]); 这句话
但是其实这句话的调用是 _redraw 当中的_clearLastClusters 里清除Cluster用的,其他操作的时候并没有走这个,所以就导致了他说的“不完美”解决,偶尔还是会出现这个问题。
而且实际上removeOverlay 这个语句本身是有意义的,屏蔽了这个代码会造成clusterer 出现了,但是marker 不消失的问题(偶尔出现,未仔细测试)。
其实诱发这个问题的原因是在于
map.removeOverlay(marker),在这句话执行的时候,会自动将marker.label =null, 由于Map 这个js 是百度自身摇匀了的,不是太好分析,但是我们可以在Clusterer 处理的所有地方都先读出来Label,等remove完毕之后再将这个Maker.setLabel 过去就ok了
tmplabel = this._markers[i].getLabel();
this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]);
this._markers[i].setLabel(tmplabel);
知道了诱因,就ok了,我在所有的removeOverlay Marker 都加入了上面的语句,之后 就可以“完美解决”这个问题了。ps 想用map的RemoveOverlay 事件,但是在他响应这个事件的时候,label 已经空了,所以不行
最后,贴上我修改之后的MarkClusterer.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 用来解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能
|