OpenLayers cluster strategy active state depending of current map scale.

Posted by – Monday 2013-01-07

1. The arena.

Among the strategies that OpenLayers has, a very important one is the cluster strategy (class OpenLayers.Strategy.Cluster). As explained in a OpenGeo workshop about OpenLayers [1]:

Loosely speaking, the OpenLayers.Strategy classes tie together the layer and the protocol. Strategies deal with when to make requests for data (or when to send modifications). Strategies can also determine how to prepare features before they end up in a layer.

The cluster strategy will pack together near features in a single one (clustering) before they are sent to the vector layer and rendered. The clustering threshold can be set by pixels or by distance.

OpenLayers cluster strategy example

This strategy is very useful when we have to deal with the task of showing a layer with a large number of features and we want offer users a clear presentation. Typically, this problem will happen at low zoom levels or, equivalently, at high map scale values. In this situation, most of the features, if not all, will lie in the map extent corresponding to the viewport.

On the other hand, at high zoom levels we would also like to get the actual features shown. Sometimes, using the aforementioned pixel and distance theshold parameters might not be enough to accomplish it. Instead, we need to dynamically activate or deactivate the cluster strategy depending on the current map zoom level.

2. OpenLayers code example.

In our example, our OpenLayers based map viewer covers the island of Manhattan (state of New York, United States of America).

The map has two layers: the base one, of WMS type, and a vectorial layer showing landmarks, each having have a polygon geometry. At low zoom levels we would like to display clusters of these landmarks, while at high zoom levels we would like to display the polygons representing them.

var CLUSTER_SCALE_THRESHOLD = 432550;

var map;

var previousMapScale;

function init() {
    var mapOptions = {
        controls: [
            new OpenLayers.Control.Navigation(),
            new OpenLayers.Control.PanZoomBar(),
            new OpenLayers.Control.LayerSwitcher()
        ]
    };

    map = new OpenLayers.Map('map', mapOptions);

    var baseLayer = new OpenLayers.Layer.WMS(
        'OpenLayers WMS', 
        'http://maps.opengeo.org/geowebcache/service/wms',
        {layers: 'openstreetmap', format: 'image/png'}
    );

    var strategies = [
        new OpenLayers.Strategy.BBOX(), 
        new OpenLayers.Strategy.Cluster()
    ];
    var wfsLayer = new OpenLayers.Layer.Vector('landmarks', {
        strategies: strategies,
        protocol: new OpenLayers.Protocol.WFS({
            url: 'http://demo.opengeo.org/geoserver/wfs',
            featureType: 'poly_landmarks',
            featureNS: 'http://www.census.gov'
        })
    });

    map.addLayers([baseLayer, wfsLayer]);

    map.zoomTo(2);

    previousMapScale = map.getScale();

    map.events.register('zoomend', map, function() {
        var lyr = this.getLayersByName('landmarks')[0];

        if ((previousMapScale > CLUSTER_SCALE_THRESHOLD) && (this.getScale() < CLUSTER_SCALE_THRESHOLD)) { 
            lyr.strategies[1].deactivate();
            lyr.refresh({force: true});
        }

        if ((previousMapScale < CLUSTER_SCALE_THRESHOLD) && (this.getScale() > CLUSTER_SCALE_THRESHOLD)) {
            lyr.strategies[1].activate();
            lyr.refresh({force: true});
        }

        previousMapScale = this.getScale();
    });
}

The code that activates or deactivates the cluster strategy lies between lines #43 and #57. On map event ‘zoomend’ the current map scale value is compared to the previous one. In case the current map scale exceeds (or lies below) the map scale threshold – variable CLUSTER_SCALE_THRESHOLD -, the cluster strategy is activated (or deactivated). After changing strategy active status, refreshing the layer is needed (lines #48 and #53).

3. Cluster strategy screenshots.

In the first screenshot it can be seen that the whole Manhattan landmarks are clustered in a single point. This makes sense, because we are seeing the map at world scale. Note that showing polygons at this scale would make little sense from the point of view of map readibility, beacuse the user would hardly see a set of very small points.

OpenLayers cluster strategy, screenshot #0

At a higher zoom level, the landmarks are grouped in four clusters.

OpenLayers cluster strategy, screenshot #1

Finally, when the zoom level is high enough, cluster strategy is deactivated and the actual landmarks are displayed.

OpenLayers cluster strategy, screenshot #2


references

[1] OpenGeo’s Introduction to OpenLayers, Working with Vector Layers: http://goo.gl/OcFMM

1 Comment on OpenLayers cluster strategy active state depending of current map scale.

Respond

Respond

Comments

Comments