最近在使用百度地图API的点聚合时遇到一个问题
当将自定义的Marker(含有Label)通过MarkerClusterer 管理的时候,当地图发生任何移动、缩放 的时候,Marker 的Label 就会自动消失。
这个问题主要是由于百度的点聚合API<script type="text/javascript" src="http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
的bug造成的。其实诱发这个问题的原因是在于API代码中的map.removeOverlay(marker),在这句话执行的时候,会自动将marker.label =null;
我们可以在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);
在点聚合的页面中将
http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js替换为下面的MakerClusterer.js即可
修改过的MakerClusterer.js代码:
1 var BMapLib = window.BMapLib = BMapLib || {}; (function() { 2 var getExtendedBounds = function(map, bounds, gridSize) { 3 bounds = cutBoundsInRange(bounds); 4 var pixelNE = map.pointToPixel(bounds.getNorthEast()); 5 var pixelSW = map.pointToPixel(bounds.getSouthWest()); 6 pixelNE.x += gridSize; 7 pixelNE.y -= gridSize; 8 pixelSW.x -= gridSize; 9 pixelSW.y += gridSize; 10 var newNE = map.pixelToPoint(pixelNE); 11 var newSW = map.pixelToPoint(pixelSW); 12 return new BMap.Bounds(newSW, newNE) 13 }; 14 var cutBoundsInRange = function(bounds) { 15 var maxX = getRange(bounds.getNorthEast().lng, -180, 180); 16 var minX = getRange(bounds.getSouthWest().lng, -180, 180); 17 var maxY = getRange(bounds.getNorthEast().lat, -74, 74); 18 var minY = getRange(bounds.getSouthWest().lat, -74, 74); 19 return new BMap.Bounds(new BMap.Point(minX, minY), new BMap.Point(maxX, maxY)) 20 }; 21 var getRange = function(i, mix, max) { 22 mix && (i = Math.max(i, mix)); 23 max && (i = Math.min(i, max)); 24 return i 25 }; 26 var isArray = function(source) { 27 return '[object Array]' === Object.prototype.toString.call(source) 28 }; 29 var indexOf = function(item, source) { 30 var index = -1; 31 if (isArray(source)) { 32 if (source.indexOf) { 33 index = source.indexOf(item) 34 } else { 35 for (var i = 0, 36 m; m = source[i]; i++) { 37 if (m === item) { 38 index = i; 39 break 40 } 41 } 42 } 43 } 44 return index 45 }; 46 var MarkerClusterer = BMapLib.MarkerClusterer = function(map, options) { 47 if (!map) { 48 return 49 } 50 this._map = map; 51 this._markers = []; 52 this._clusters = []; 53 var opts = options || {}; 54 this._gridSize = opts["gridSize"] || 60; 55 this._maxZoom = opts["maxZoom"] || 18; 56 this._minClusterSize = opts["minClusterSize"] || 2; 57 this._isAverageCenter = false; 58 if (opts['isAverageCenter'] != undefined) { 59 this._isAverageCenter = opts['isAverageCenter'] 60 } 61 this._styles = opts["styles"] || []; 62 var that = this; 63 this._map.addEventListener("zoomend", 64 function() { 65 that._redraw() 66 }); 67 this._map.addEventListener("moveend", 68 function() { 69 that._redraw() 70 }); 71 var mkrs = opts["markers"]; 72 isArray(mkrs) && this.addMarkers(mkrs) 73 }; 74 MarkerClusterer.prototype.addMarkers = function(markers) { 75 for (var i = 0, 76 len = markers.length; i < len; i++) { 77 this._pushMarkerTo(markers[i]) 78 } 79 this._createClusters() 80 }; 81 MarkerClusterer.prototype._pushMarkerTo = function(marker) { 82 var index = indexOf(marker, this._markers); 83 if (index === -1) { 84 marker.isInCluster = false; 85 this._markers.push(marker) 86 } 87 }; 88 MarkerClusterer.prototype.addMarker = function(marker) { 89 this._pushMarkerTo(marker); 90 this._createClusters() 91 }; 92 MarkerClusterer.prototype._createClusters = function() { 93 var mapBounds = this._map.getBounds(); 94 var extendedBounds = getExtendedBounds(this._map, mapBounds, this._gridSize); 95 for (var i = 0, 96 marker; marker = this._markers[i]; i++) { 97 if (!marker.isInCluster && extendedBounds.containsPoint(marker.getPosition())) { 98 this._addToClosestCluster(marker) 99 } 100 } 101 }; 102 MarkerClusterer.prototype._addToClosestCluster = function(marker) { 103 var distance = 4000000; 104 var clusterToAddTo = null; 105 var position = marker.getPosition(); 106 for (var i = 0, 107 cluster; cluster = this._clusters[i]; i++) { 108 var center = cluster.getCenter(); 109 if (center) { 110 var d = this._map.getDistance(center, marker.getPosition()); 111 if (d < distance) { 112 distance = d; 113 clusterToAddTo = cluster 114 } 115 } 116 } 117 if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) { 118 clusterToAddTo.addMarker(marker) 119 } else { 120 var cluster = new Cluster(this); 121 cluster.addMarker(marker); 122 this._clusters.push(cluster) 123 } 124 }; 125 MarkerClusterer.prototype._clearLastClusters = function() { 126 for (var i = 0, 127 cluster; cluster = this._clusters[i]; i++) { 128 cluster.remove() 129 } 130 this._clusters = []; 131 this._removeMarkersFromCluster() 132 }; 133 MarkerClusterer.prototype._removeMarkersFromCluster = function() { 134 for (var i = 0, 135 marker; marker = this._markers[i]; i++) { 136 marker.isInCluster = false 137 } 138 }; 139 MarkerClusterer.prototype._removeMarkersFromMap = function() { 140 for (var i = 0, 141 marker; marker = this._markers[i]; i++) { 142 marker.isInCluster = false; 143 tmplabel = marker.getLabel(); 144 this._map.removeOverlay(marker); 145 marker.setLabel(tmplabel) 146 } 147 }; 148 MarkerClusterer.prototype._removeMarker = function(marker) { 149 var index = indexOf(marker, this._markers); 150 if (index === -1) { 151 return false 152 } 153 tmplabel = marker.getLabel(); 154 this._map.removeOverlay(marker); 155 marker.setLabel(tmplabel); 156 this._markers.splice(index, 1); 157 return true 158 }; 159 MarkerClusterer.prototype.removeMarker = function(marker) { 160 var success = this._removeMarker(marker); 161 if (success) { 162 this._clearLastClusters(); 163 this._createClusters() 164 } 165 return success 166 }; 167 MarkerClusterer.prototype.removeMarkers = function(markers) { 168 var success = false; 169 for (var i = 0; i < markers.length; i++) { 170 var r = this._removeMarker(markers[i]); 171 success = success || r 172 } 173 if (success) { 174 this._clearLastClusters(); 175 this._createClusters() 176 } 177 return success 178 }; 179 MarkerClusterer.prototype.clearMarkers = function() { 180 this._clearLastClusters(); 181 this._removeMarkersFromMap(); 182 this._markers = [] 183 }; 184 MarkerClusterer.prototype._redraw = function() { 185 this._clearLastClusters(); 186 this._createClusters() 187 }; 188 MarkerClusterer.prototype.getGridSize = function() { 189 return this._gridSize 190 }; 191 MarkerClusterer.prototype.setGridSize = function(size) { 192 this._gridSize = size; 193 this._redraw() 194 }; 195 MarkerClusterer.prototype.getMaxZoom = function() { 196 return this._maxZoom 197 }; 198 MarkerClusterer.prototype.setMaxZoom = function(maxZoom) { 199 this._maxZoom = maxZoom; 200 this._redraw() 201 }; 202 MarkerClusterer.prototype.getStyles = function() { 203 return this._styles 204 }; 205 MarkerClusterer.prototype.setStyles = function(styles) { 206 this._styles = styles; 207 this._redraw() 208 }; 209 MarkerClusterer.prototype.getMinClusterSize = function() { 210 return this._minClusterSize 211 }; 212 MarkerClusterer.prototype.setMinClusterSize = function(size) { 213 this._minClusterSize = size; 214 this._redraw() 215 }; 216 MarkerClusterer.prototype.isAverageCenter = function() { 217 return this._isAverageCenter 218 }; 219 MarkerClusterer.prototype.getMap = function() { 220 return this._map 221 }; 222 MarkerClusterer.prototype.getMarkers = function() { 223 return this._markers 224 }; 225 MarkerClusterer.prototype.getClustersCount = function() { 226 var count = 0; 227 for (var i = 0, 228 cluster; cluster = this._clusters[i]; i++) { 229 cluster.isReal() && count++ 230 } 231 return count 232 }; 233 function Cluster(markerClusterer) { 234 this._markerClusterer = markerClusterer; 235 this._map = markerClusterer.getMap(); 236 this._minClusterSize = markerClusterer.getMinClusterSize(); 237 this._isAverageCenter = markerClusterer.isAverageCenter(); 238 this._center = null; 239 this._markers = []; 240 this._gridBounds = null; 241 this._isReal = false; 242 this._clusterMarker = new BMapLib.TextIconOverlay(this._center, this._markers.length, { 243 "styles": this._markerClusterer.getStyles() 244 }) 245 } 246 Cluster.prototype.addMarker = function(marker) { 247 if (this.isMarkerInCluster(marker)) { 248 return false 249 } 250 if (!this._center) { 251 this._center = marker.getPosition(); 252 this.updateGridBounds() 253 } else { 254 if (this._isAverageCenter) { 255 var l = this._markers.length + 1; 256 var lat = (this._center.lat * (l - 1) + marker.getPosition().lat) / l; 257 var lng = (this._center.lng * (l - 1) + marker.getPosition().lng) / l; 258 this._center = new BMap.Point(lng, lat); 259 this.updateGridBounds() 260 } 261 } 262 marker.isInCluster = true; 263 this._markers.push(marker); 264 var len = this._markers.length; 265 if (len < this._minClusterSize) { 266 this._map.addOverlay(marker); 267 return true 268 } else if (len === this._minClusterSize) { 269 for (var i = 0; i < len; i++) { 270 tmplabel = this._markers[i].getLabel(); 271 this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]); 272 this._markers[i].setLabel(tmplabel) 273 } 274 } 275 this._map.addOverlay(this._clusterMarker); 276 this._isReal = true; 277 this.updateClusterMarker(); 278 return true 279 }; 280 Cluster.prototype.isMarkerInCluster = function(marker) { 281 if (this._markers.indexOf) { 282 return this._markers.indexOf(marker) != -1 283 } else { 284 for (var i = 0, 285 m; m = this._markers[i]; i++) { 286 if (m === marker) { 287 return true 288 } 289 } 290 } 291 return false 292 }; 293 Cluster.prototype.isMarkerInClusterBounds = function(marker) { 294 return this._gridBounds.containsPoint(marker.getPosition()) 295 }; 296 Cluster.prototype.isReal = function(marker) { 297 return this._isReal 298 }; 299 Cluster.prototype.updateGridBounds = function() { 300 var bounds = new BMap.Bounds(this._center, this._center); 301 this._gridBounds = getExtendedBounds(this._map, bounds, this._markerClusterer.getGridSize()) 302 }; 303 Cluster.prototype.updateClusterMarker = function() { 304 if (this._map.getZoom() > this._markerClusterer.getMaxZoom()) { 305 this._clusterMarker && this._map.removeOverlay(this._clusterMarker); 306 for (var i = 0, 307 marker; marker = this._markers[i]; i++) { 308 this._map.addOverlay(marker) 309 } 310 return 311 } 312 if (this._markers.length < this._minClusterSize) { 313 this._clusterMarker.hide(); 314 return 315 } 316 this._clusterMarker.setPosition(this._center); 317 this._clusterMarker.setText(this._markers.length); 318 var thatMap = this._map; 319 var thatBounds = this.getBounds(); 320 this._clusterMarker.addEventListener("click", 321 function(event) { 322 thatMap.setViewport(thatBounds) 323 }) 324 }; 325 Cluster.prototype.remove = function() { 326 for (var i = 0, 327 m; m = this._markers[i]; i++) { 328 var tmplabel = this._markers[i].getLabel(); 329 this._markers[i].getMap() && this._map.removeOverlay(this._markers[i]); 330 this._markers[i].setLabel(tmplabel) 331 } 332 this._map.removeOverlay(this._clusterMarker); 333 this._markers.length = 0; 334 delete this._markers 335 } 336 Cluster.prototype.getBounds = function() { 337 var bounds = new BMap.Bounds(this._center, this._center); 338 for (var i = 0, 339 marker; marker = this._markers[i]; i++) { 340 bounds.extend(marker.getPosition()) 341 } 342 return bounds 343 }; 344 Cluster.prototype.getCenter = function() { 345 return this._center 346 } 347 })();
转载 http://www.cnblogs.com/chenjiahong/p/3917528.html