openlayers 3 zoom to combined extent

user1697335 picture user1697335 · May 8, 2015 · Viewed 14k times · Source

I'm using openlayers 3 to create a map with vector features on top. So far, so good.

I have several vector layers, grouped in a variable called projecten.

var projecten = new ol.layer.Group({

            title: 'Projecten',
            layers: [

                new ol.layer.Vector({
                title: 'EVZ Den Dungen',
                source: new ol.source.GeoJSON(
                            /** @type {olx.source.GeoJSONOptions} */ ({
                              object: EVZDenDungen,
                              projection: 'EPSG:3857'
                        })),
                style: function(feature, resolution) {
                    return lookup[feature.get('landschapselement')];
                }
                }),

                new ol.layer.Vector({
                title: 'EVZ Croy',
                source: new ol.source.GeoJSON(
                            /** @type {olx.source.GeoJSONOptions} */ ({
                              object: EVZCroy,
                              projection: 'EPSG:3857'
                        })),
                style: function(feature, resolution) {
                    return lookup[feature.get('landschapselement')];
                }
                }),

                new ol.layer.Vector({
                title: 'Natuurcompensatie Gasselsbroek',
                source: new ol.source.GeoJSON(
                            /** @type {olx.source.GeoJSONOptions} */ ({
                              object: NatuurcompensatieGasselsbroek,
                              projection: 'EPSG:3857'
                        })),
                style: function(feature, resolution) {
                    return lookup[feature.get('landschapselement')];
                }
                }),

                new ol.layer.Vector({
                title: 'Ebben',
                source: new ol.source.GeoJSON(
                            /** @type {olx.source.GeoJSONOptions} */ ({
                              object: Ebben,
                              projection: 'EPSG:3857'
                        })),
                style: function(feature, resolution) {
                    return lookup[feature.get('landschapselement')];
                }
                }),

                new ol.layer.Vector({
                title: 'Zionsburg',
                source: new ol.source.GeoJSON(
                            /** @type {olx.source.GeoJSONOptions} */ ({
                              object: Zionsburg,
                              projection: 'EPSG:3857'
                        })),
                style: function(feature, resolution) {
                    return lookup[feature.get('landschapselement')];
                }
                })


            ]
})

Now I want to somehow loop through the projecten variables, loop through its layers one by one, get the extent of each feature layer, and stop when the last layer has been reached. Then I want to zoom to this combined extent.

This is my basic setup (I'm not good with javascript and loops):

projecten.getLayers()
     for (var i = 0, ii = layers.length; i < ii; ++i) {
         layer = layers[i];
         ol.extent.boundingExtend(extent, layer.getBounds());
     }
    map.getView().fitExtent(extent,map.getSize());

Any ideas on how I can get this to work?

Answer

Tim Schaub picture Tim Schaub · May 8, 2015

You should be able to do this:

var extent = ol.extent.createEmpty();
projecten.getLayers().forEach(function(layer) {
  ol.extent.extend(extent, layer.getSource().getExtent());
});
map.getView().fitExtent(extent, map.getSize());

Use the ol.extent.createEmpty() function to initialize your extent. Then loop through the collection of layers and use ol.extent.extend() to generate an extent that includes all features in all of your vector sources. Finally, fit the map view to this extent.

There are a few things to note here. The group.getLayers() method returns an ol.Collection of layers. This is similar to a regular JavaScript Array except that it is observable. You can use the collection.forEach() method to iterate through each layer in the collection.

Also note that you should call source.getExtent() to get the extent of all currently loaded features in a source.

Finally, the links above are relevant for the 3.5.0 release and above. You'll need to adapt your code to work with ol.source.Vector objects instead of the experimental (and now removed) ol.source.GeoJSON objects. See the 3.5.0 release notes for details on upgrading to the new vector API.