x

Re: OpenLayers.Strategy.Cluster Performance beim Reinzoomen


Geschrieben von ikonor (Gast) am 27. September 2012 15:17:47: [flux]

Als Antwort auf: OpenLayers.Strategy.Cluster Performance beim Reinzoomen geschrieben von chrisMein (Gast) am 26. September 2012 11:40:

chrisMein wrote:

Ich habe mal eine Openlayerkarte neben eine Googlekarte gestellt um das Problem zu verdeutlichen.
=> http://www.webxvideo.de/cluster/
Interessanterweise ist die Googlekarte in den kleineren Zoomstufen lahmer und bei Openlayer verhält es sich genau andersherum.

Schönes Beispiel und interessanter Vergleich.

So wie ich das sehe, liegt der Unterschied in der Implementierung des Clusterings:
- Beim markerclusterer.js für Google Maps werden in "createClusters_" nur die Marker berücksichtigt, die im aktuellen Kartenausschnitt liegen.
- In OpenLayers.Strategy.Cluster.cluster werden dagegen immer alle Features verarbeitet. Bei steigendem Zoom Level werden es daher immer mehr Cluster und entsprechend mehr Schleifendurchläufe in der cluster Funktion.

Folgende Debug-Ausgabe verdeutlicht das (addFeatures wird innerhalb von cluster aufgerufen):

addFeatures:␣44ms
cluster:␣44ms
features:␣2001,␣clusters:␣7,␣zoom:␣4
addFeatures:␣6ms
cluster:␣17ms
features:␣2001,␣clusters:␣20,␣zoom:␣5
addFeatures:␣19ms
cluster:␣29ms
features:␣2001,␣clusters:␣66,␣zoom:␣6
addFeatures:␣58ms
cluster:␣85ms
features:␣2001,␣clusters:␣222,␣zoom:␣7
addFeatures:␣94ms
cluster:␣168ms
features:␣2001,␣clusters:␣661,␣zoom:␣8
addFeatures:␣200ms
cluster:␣377ms
features:␣2001,␣clusters:␣1326,␣zoom:␣9
addFeatures:␣269ms
cluster:␣509ms
features:␣2001,␣clusters:␣1770,␣zoom:␣10
addFeatures:␣249ms
cluster:␣498ms
features:␣2001,␣clusters:␣1937,␣zoom:␣11
addFeatures:␣291ms
cluster:␣578ms
features:␣2001,␣clusters:␣1982,␣zoom:␣12
addFeatures:␣252ms
cluster:␣509ms
features:␣2001,␣clusters:␣1995,␣zoom:␣13

Hier der dazu eingefügte Code (vor $(document).ready(init);):

clusterOrig␣=␣OpenLayers.Strategy.Cluster.prototype.cluster;
OpenLayers.Strategy.Cluster.prototype.cluster␣=␣function(event)␣{
console.time("cluster");
clusterOrig.apply(this,␣arguments);
console.timeEnd("cluster");
console.log("features:␣"␣+␣(this.features␣&&␣this.features.length)␣+␣",␣clusters:␣"␣+␣(this.clusters␣&&␣this.clusters.length)␣+␣",␣zoom:␣"␣+␣this.layer.map.getZoom());
};
addFeaturesOrig␣=␣OpenLayers.Layer.Vector.prototype.addFeatures;
OpenLayers.Layer.Vector.prototype.addFeatures␣=␣function(features,␣options)␣{
console.time("addFeatures");
addFeaturesOrig.apply(this,␣arguments);
console.timeEnd("addFeatures");
};

Zur Optimierung müsste man also die Features auf den aktuellen Anzeigebereich begrenzen.

Eine einfache Lösung für bereits geladene Features fällt mir aber gerade nicht ein. Die BBOX Strategy sendet beim HTTP Protocol nur einen Query String, damit eine server-seitige Komponente danach filtern kann. Evtl. könnte man BBOX.triggerRead in einer eigenen Unterklasse überschreiben und die in einer globalen Variable gespeicherten Features selbst filtern. Oder eben gleich die Cluster Strategy entsprechend erweitern/ändern.

Gruß,
Norbert