1

When I create a layer using a vector source I can force the map to zoom to the layer using

//stuff including setting up defaultStyle
var vectorSource = new ol.source.GeoJSON({ url: geoJsonUrl, projection: 'EPSG:3857', extractStyles: false });
var vectorLayer = new ol.layer.Vector({ source: vectorSource, style: defaultStyle });
//stuff
vectorLayer.addEventListener("change", function () {
    map.getView().fitExtent(vectorSource.getExtent(), map.getSize());
}

This works well for me so I'm trying to replicate it with my WMS layer. The layer and source are defined as:

//stuff including setting up params and geoserverRoot
var wmsImageSource = new ol.source.ImageWMS({ url: geoserverRoot + 'wms', params: params });
var wmsImageLayer = new ol.layer.Image({ opacity: 0.3, source: wmsImageSource });

An ImageWMS source doesn't have a getExtent() method (unlike vector sources such as a GeoJSON source), but an Image layer does. So I tried to replicate the way I zoom vector sources with:

wmsImageLayer.addEventListener("change", function () {
    alert('change');
    map.getView().fitExtent(wmsImage.getExtent(), map.getSize());
});

However, the alert doesn't trigger. I have no idea why this is the case.

What is the best way to automatically zoom into an image layer produced by GeoServer? Additionally, why does the change event not fire for the image layer?

EDIT: I tried using GetCapabilities as per advice from user30184 My layer is generated from a parametrized PostGIS view and the URL I used was:

/geoserver/wms?service=WMS&request=GetCapabilities&layers=areas_for_type&viewparams=typecode:AdministrativeWard

This gives an XML response including:

<EX_GeographicBoundingBox>
    <westBoundLongitude>-1.0</westBoundLongitude>
    <eastBoundLongitude>0.0</eastBoundLongitude>
    <southBoundLatitude>-1.0</southBoundLatitude>
    <northBoundLatitude>0.0</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="CRS:84" minx="-1.0" miny="-1.0" maxx="0.0" maxy="0.0"/>
<BoundingBox CRS="EPSG:4326" minx="-1.0" miny="-1.0" maxx="0.0" maxy="0.0"/>

so the BB for the passed in parameter is not being calculated.

  • WMS is a service and the extents of the layers can be found from the GetCapabilities document of the service. For example demo.opengeo.org/geoserver/… – user30184 Nov 11 '14 at 8:01
  • @user30184, thanks. Unfortunately it's not working for me. This might be because the layer is generated using a parametrized PostGIS query rather than a static layer. I've edited my question accordingly. – Andy Nichols Nov 11 '14 at 9:19
  • Well, by the time when WMS user asks for GetCapabilities it is impossible to know what parameters will be used in the future as view parameters. Thus it is not possible to generate a dynamic and always correct BBOX into GetCapabities. The best you can do is to go to the layer settings with the admin utility and feed manually a Lat/Lon Bounding Box that makes more sense than the current one - maximum bbox that can occur with your data. For more accurate automatic zoom to layer you should use WFS and get the features and compute BBOX from the vectors. – user30184 Nov 11 '14 at 9:39
2

Answering my own question. Some of the images being created contained a large number of areas (up to 35,000) so I didn't want to load in separate layers. Also, as this is a database driven application where new geometries can be created I didn't want to enter the bounding box in geoserver - I needed it calculated.

In the end I did it with an AJAX call. The call ran a query on the Postgresql database of

SELECT ST_XMIN(extent) AS minx, ST_YMIN(extent) AS miny, ST_XMAX(extent) AS maxx, ST_YMAX(extent) AS maxy FROM (SELECT ST_EXTENT(shape) as extent from area where area_type_code = :typecode) a

which was surprisingly quick to run (around 60ms for 35,000 records). Then in my client side script I used the returned max and min x and y co-ordinates to create an extent. Then called fitExtent().

$.getJSON('@Url.RouteUrl("BoundingBoxForType")', { code: areaType }, function(bbdata) {
    if (bbdata != null) {
        var box = [bbdata.MinimumX, bbdata.MinimumY, bbdata.MaximumX, bbdata.MaximumY];
        var areaExtent = ol.extent.applyTransform(box, ol.proj.getTransform('EPSG:4326', 'EPSG:3857'));
        map.getView().fitExtent(areaExtent, map.getSize());
    }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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