5

我正在通过 MarkerClustererPlus 绘制几十万个点,我想根据一些外部属性(而不是基于表示的标记数量)设置集群图标(颜色)组。

我能想到的唯一方法是创建多个 MarkerClusterer 对象并传入不同的options对象,但我觉得这样做会对性能造成很大影响。有没有更好的办法?

Marker Clusterer Plus 具有不同大小的图标,可缩放以适应。

鉴于上图,我希望 139、24 和 5 为黄色,而 213、25、30 和 2 为红色;如果可能的话,通过 setOptions 更新他们的样式/选项:
mc.group[0].setOptions({"url": imgPath +lookupThreshold(severity)+ '.svg' });
mc.group[1].setOptions({"url": imgPath +lookupThreshold(severity)+ '.svg' });

PS如果有人感兴趣,我调整了lib,通过提供一个svg图像并增加选项对象的宽度和高度,集群图标缩放到它的大小†</sup>:

var mcOptions = {
  "styles": [{
    "height": 19,
    "url": img/map/clusters/",
    "width": 19
  },{
    "height": 24,
    "url": img/map/clusters/",
    "width": 24
  }, {…}]
};
for ( var s = mcOptions.styles.length-1; s >= 0; s-- )
{ mcOptions.styles[s].url += lookupThreshold(severity) + '.svg'; }
// lookupThreshold switches severity and returns a string: red, orange, …

然后将以下内容添加到markerclusterer.js

line 275: this.backgroundSize_ = style.backgroundSize || "contain";
line 300: style.push('background-size:' + this.backgroundSize_ + ';');

†</sup> 适用于 Ffx 19.0.2、Chrome 26.x、Chrome Canary 28.x、Safari 6.0.2、IE 9.0.8(但不适用于 Opera 12.15)。

编辑创建多个 MarkerClusterer 实例似乎对性能没有太大影响;但是,似乎传递给 MC 的属性/选项对象在 MC的实例之间是共享的。

解决了我必须修改第 665 行附近的 MarkerClusterPlus 库以进行克隆opt_options(该库使用引用,这导致所有以前的 opt_options 都被最新/最后一个传递的选项覆盖)。

4

1 回答 1

2

所以事实证明,问题出在MarkerClustererPlus 库本身:

656:  function MarkerClusterer(map, opt_markers, opt_options) {
…
665:    opt_options = opt_options || {};

665行创建对现有对象的引用,而不是新副本。我不能MarkerClusterer.prototype.extend从第1539行开始使用,因为它不会进行深层复制(并且它仅扩展对象的原型)。

因此,我编写了自己的深拷贝函数(jsfiddle),我将其设为全局可用(而不是将其添加到ArrayObject的原型中):

function deepCopy(obj) {  
  this.cloneArr = function (arr) {
    var newArr = [];
    for ( var i = arr.length-1; i >= 0; i-- ) newArr[i] = this.evalObj( arr[i] );
    return newArr;
  };
  this.cloneObj = function(obj) {
    var newObj = {};
    for ( var prop in obj ) newObj[prop] = this.evalObj( obj[prop] );
    return newObj;
  };
  this.evalObj = function(obj) {
    switch ( typeof obj ) {
      case 'object':
        if ( Array.isArray( obj ) ) return this.cloneArr( obj );
        if ( obj instanceof Date === false ) return this.cloneObj( obj );
        // pass thru dates, strings, numbers, booleans, and functions
      default: return obj; // primitive
    }
  };
  return this.evalObj(obj);
}

然后我将MarkerClustererPlus.js更改为以下内容:

656:  function MarkerClusterer(map, opt_markers, opt_optionsG) {
…
665:    var opt_options = deepCopy( opt_optionsG ) || {};

我测试了 5 个 MarkerClusterPlus 实例(每个实例有 5000 个标记,总共 25000 个),与单个 MC+ 实例相比,没有明显的性能影响。

MarkerClusterPlus 多个实例的屏幕截图

于 2013-05-10T18:10:13.047 回答