Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I want to deactivate the cluster strategy after zoom level 16. The Cluster strategy gets deactivated and I also change the style of the original features and redraw the layer. But still it takes the styles defined for the clusters instead of taking the newly defined styles.

var test_style = new OpenLayers.Style({
    'fillColor': '#CC66CC',
    'fillOpacity': .8
});
var test_style_map = new OpenLayers.StyleMap({
    'default':test_style
});                  
var test_layer_name=clusterStrategy.layer;
if(zoom_level>16) {
    clusterStrategy.deactivate();
    test_layer_name.styleMap=test_style_map;
    test_layer_name.redraw();
}
share|improve this question

5 Answers 5

Each feature also has a reference to the layer it's on. That layer has a stylemap, most likely the old one. (you can check in your DOM inspector) An easy sollution would be to call

test_layer_name.removeFeatures(test_layer_name.features);

before you redraw. That way features get added with all the new layer properties. (you should check if features get removed by disabeling the strategy)

Another way would be to add context to your stylemap and check on feature.cluster That way you don't have to keep changing the stylemaps.

share|improve this answer

A brute force and simple solution can be removing the layer from the map and, after that, adding a new one with the same name which, besides, would use a different style map and would not feature the cluster strategy.

share|improve this answer

I've came across a similar problem on my own. To display infoWindows for each unit on the map, I got some trouble if that features was clustered, so I zoomed in to that feature. If those features are very close, they could still be clustered. So I wanted to disable the clustering from a certain zoomlevel.

I allready had some trouble disabling the clustering, so I've came up with this:

If you set the threshold of the clustering strategy to the total features + 1 there is no clustering. If you have such a toggle function, you can register it to the zoomend event.

I've used this allready in a toggle function. I only added some ugly if statements to check who's calling the toggle function. The register function calls the listener with an object.

So after creating the layer and strategy:

myMap.map.events.register("zoomend", "zoom", toggleCluster);

(I've no idea what the second parameter does....) The myMap object holds the map the myUnit object holds a reference to the layer and also the toggle function.

toggleCluster: function(status) {
    if (myUnit.layer.strategies[0].features != null){
        var max = myUnit.layer.strategies[0].features.length;
    } else {
        // no features, don't care
        return;
    }

    if (status && status.type == "zoomend") {
        if (myMap.map.zoom > myUnit.zoomThreshold-1 ) {
            console.log("cluster off");
            myUnit.layer.strategies[0].threshold = max + 1;
        } else {
            console.log("cluster on");
            myUnit.layer.strategies[0].threshold = myUnit.clusterThreshold;
        }
    } else {
        if (myUnit.layer.strategies[0].threshold == myUnit.clusterThreshold) {
            myUnit.layer.strategies[0].threshold = max + 1;
        } else {
            myUnit.layer.strategies[0].threshold = myUnit.clusterThreshold;    
        }
    }
    myUnit.layer.removeFeatures(tbUnit.layer.features);
    myUnit.layer.redraw();

},
share|improve this answer

Looking back I see that your question was related to the code I'm writing.

Try this experimental code:

var clusterStrategy = new CustomCluster({
  zoomSettings: [{zoomRange: [17, 99], settings:{enabled: false}}]
});

where customCluster is:

var CustomCluster = OpenLayers.Class(OpenLayers.Strategy.Cluster, {
    enabled: true,
    zoomSettings: null,
    defaultSettings: null,
    initialize: function() {
        OpenLayers.Strategy.Cluster.prototype.initialize.apply(this, arguments);
        this.defaultSettings = OpenLayers.Util.applyDefaults(
            this.defaultSettings, {
                distance: this.distance,
                threshold: this.threshold,
                enabled: this.enabled
            }
        );
    },
    cacheFeatures: function(event) {
        if (this.clustering) { return; }
        if (this.enabled) {
            return OpenLayers.Strategy.Cluster.prototype
                                          .cacheFeatures.apply(this, arguments);
        } else if (this.features) {
            this.uncluster();
        }
    },
    cluster: function(event) {
        if (event && event.zoomChanged) {
            var zoomSettings = this.zoomSettings,
                zoomLevel = this.layer.map.getZoom();
            OpenLayers.Util.extend(this, this.defaultSettings);
            for (var i=0, len = zoomSettings.length; i<len; i++) {
                var item = zoomSettings[i];
                if (zoomLevel >= item.zoomRange[0] && zoomLevel <= item.zoomRange[1]) {
                    OpenLayers.Util.extend(this, item.settings);
                    break;
                }
            }
        }
        if (this.enabled) {
            if (!this.features) {
                this.features = this.layer.features.slice();
            }
            OpenLayers.Strategy.Cluster.prototype.cluster.apply(this, arguments);
        } else {
            if (this.features) {
                this.uncluster();
            }
        }
    },
    uncluster: function() {
        // Warning: methods that call this function should monitor that `this.features` has value.
        var features = this.features.slice();
        this.clearCache();
        this.clustering = true;
        this.layer.removeAllFeatures();
        this.layer.addFeatures(features);
        this.clustering = false;
    }
});
share|improve this answer

You can also follow this Howto: OpenLayers cluster strategy active state depending of current map scale. I refactored it a bit, the important code is

clusteringThreshold: 9, 
previousZoom: 0,

// init: function () {  
    // ...
    // register callbacks at initilization
    this.map.events.register("zoomend", this, this.dontClusterAtLowestZoom);
    // ...
// }


dontClusterAtLowestZoom: function () {
    if ( this.comingFromBelowClusterThreshold() && this.clusterThresholdReached() ) {
        this.vectorLayer.strategies[0].deactivate();
        this.vectorLayer.refresh({force: true});
    }

    if ( !this.comingFromBelowClusterThreshold() && !this.clusterThresholdReached() ) {
        this.vectorLayer.strategies[0].activate();
        this.vectorLayer.refresh({force: true});
    }

    this.previousZoom = this.map.getZoom();        
},

comingFromBelowClusterThreshold: function () {
    return this.previousZoom < this.clusteringThreshold;        
},

clusterThresholdReached: function () {
    var currentZoom = this.map.getZoom();
    return currentZoom >= this.clusteringThreshold;
},
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.