[OpenLayers-Users] Using GeoWebCache with OpenLayers2 - Only certain zoom levels are hit

jimmyfishbean immy1509 at gmail.com
Thu Feb 25 07:51:37 PST 2016


Hi All,

This is my first post so please bear with me and apologies if this is the
wrong group…

Versions: GeoServer 2.6.1 / GeoWebCache 1.6.1 / OpenLayers2 and 3

I have 2 applications, one a legacy OL2 website and the other a web
application utilising the OL3 library.  Three new raster base maps (250K,
50K and 25K) were added to GeoServer and cached using the caching interface
in GeoServer using the EPSG:27700 gridset (I reside in the UK and the
requirement is to display mapping data using this gridset / projection). 
The layers were all cached without any errors.  

The requirement is to display only a single base raster layer depending on
the current zoom / resolution.  The OL2 website currently only displays
vector shape files, whereas the OL3 application currently only displays the
base maps (this application was developed as a proof of concept to see if
the GeoWebCache could be used for loading tiled raster data).

The OL3 application works fine.  I am able to create an ol.tileGrid.TileGrid
object and set this on my ol.source.TileWMS object.  The origin property of
the TileGrid is set to the minX and minY values from the EPSG:27700 gridset
used to generate the tiles, and the resolutions property matches the
resolutions also from the EPSG:27700 gridset.  Basically, on start up I load
the 250K layer.  Then using the map moveend event, I detect if a different
base layer is to be loaded before unloading the current layer using
map.setTarget(null); and then calling the loadMap() again so the required
layer may be loaded and displayed.  The following is some of my OL3 code: 

function loadMap(baseLayerName) {
    // Resolutions of the EPSG:27700 gridset (Scales taken from GeoServer
Gridset screen and converted to resolutions using OL2
OpenLayers.Util.getResolutionFromScale() helper method)
    var resolutions = [
            2616.091417243591,
            1308.0457086217955,
            654.0228543108977,
            327.01142715544887,
            163.50571357772444,
            81.75285678886222,
            40.87642839443111,
            20.438214197215554,
            10.219107098607777,
            5.109553549303889,
            2.5547767746519443,
            1.2773883873259722,
            0.6386941936629861,
            0.31934709683149304,
            0.15967354841574652,
            0.07983677420787326
    ];

    // Create a mouse position control to relay the XY coordinates. Will use
the default map/view projection if the projection not specified.
    var mousePositionControl = new openLayers.control.MousePosition({
        coordinateFormat: openLayers.coordinate.createStringXY(0),
        projection: 'EPSG:27700',
        className: 'custom-mouse-position',
        target: document.getElementById('mouseposition'),
        undefinedHTML: ' '
    });

    // "Direct integration with GeoServer WMS" is enabled in GeoServer
Caching Defaults, so no 
    // need to specify URL to point to GWC location. The TileGrid origin
matches the minX and minY 
    // values from the EPSG:27700 gridset
    var baseLayer = new openLayers.layer.Tile({
        source: new openLayers.source.TileWMS({
            url: 'http://X.X.X.X:8080/geoserver/wms',
            params: {
                'LAYERS': 'BaseLayerWorkspaceName:’ + baseLayerName,
                'TILED': true
            },
            // The TileGrid origin matches the minX and minY values from the
EPSG:27700 gridset
            tileGrid: new openLayers.tilegrid.TileGrid({
                origin: [1346.748175220855, 7097.996956234318],
                resolutions: resolutions
            })
        })
    });

    // Add the map control
    var map = new openLayers.Map({
        target: 'map',
        layers: [
            baseLayer
        ],
        controls: openLayers.control.defaults({
            attributionOptions: ({
                collapsible: false
            })
        }).extend([
            mousePositionControl
        ]),
        view: new openLayers.View({
            projection: 'EPSG:27700',
            resolutions: resolutions,
            center: [393674, 289141],
            zoom: (currentZoomLevel) ? currentZoomLevel : 0
        })
    });
}

When I attempt to implement the above using OL2, I am unable to do so with
success.  I cannot determine how to implement the TileGrid on my base layers
(I believe this is crucial), or find any resources on this.  When checking
the HTTP response headers using Chrome developer tools the following is
displayed:

Content-Disposition: inline;
filename=BASE_RASTER_25K_HEWMS:BASE_RASTER_25K_HEWMS
Content-Type: image/png
Date: Thu, 25 Feb 2016 15:13:14 GMT
geowebcache-cache-result: MISS
geowebcache-miss-reason: request does not align to grid(s) 'EPSG:27700'
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
 
As the subject to this post states, I am able to load from GeoWebCache
certain zoom level tiles, but most of the zoom levels report the above error
/ reason for failure and zero tiles get loaded from GeoWebCache.  The zoom
levels that work are:

•	Zoom 3 – 250K map.  The 250K map should be visible between zoom levels 0
and 5.
•	Zoom 5 – 50K map.  The 50K map should be visible only for zoom levels 6.
•	Zoom 6 – 25K map.  The 25K map should be visible between zoom levels 7 and
8.
•	The map loads at zoom level 9, meaning no base map is visible at start up. 
Only when the user zooms out to level 8 does the 25 K map load.

My gut feeling is the layer in OL2 needs to know the gridset it should use,
just as I create and add a layer using a TileGrid in OL3.  I have this
feeling because I encountered the same error messages when I provided origin
values other than the minX and minY

Some other things to note:
•	The OL2 application loads vector data on top of the base data.  Upon first
load, the map zooms to the extent of the vector data.
•	When the zoom level changes, unlike the OL3 application,
map.setTarget(null); is not called.  Instead,
this.map.setBaseLayer(baseLayers); is called to display the required base
layer and hide the others.  NOTE: The OL2 application creates instances of
each base layer upon startup and stores the layers in an array ready for use
when required.
•	No interaction occurs with the map or the viewport when zooming in or out
(i.e. the viewport bounds are not being changed by the user by expanding the
size of the map etc.).


The following is snippets of the OL2 code (not exact as refactored slightly
for this post – but I can assure you it runs!):

// Set the map extent for OpenLayers using the map boundary box
var mapExtent = new OpenLayers.Bounds(
    mapOptions.bounds.left, mapOptions.bounds.bottom,
    mapOptions.bounds.right, mapOptions.bounds.top
);

// Map options
var options = {
    controls: [],
    maxExtent: mapExtent,
    resolutions: [
        2616.091417243591,
        1308.0457086217955,
        654.0228543108977,
        327.01142715544887,
        163.50571357772444,
        81.75285678886222,
        40.87642839443111,
        20.438214197215554,
        10.219107098607777,
        5.109553549303889,
        2.5547767746519443,
        1.2773883873259722,
        0.6386941936629861,
        0.31934709683149304,
        0.15967354841574652,
        0.07983677420787326
    ],
    projection: 'EPSG:27700',
    units: 'm',
    theme: null
};

// Get the map
var map = new OpenLayers.Map(self.mapElementId, options);

// Draw the map layers (this will also call createBaseLayer() to create the
base layers and add to array)
self.drawMapLayers(mapOptions.layers);

// Get the element in which scale and location will be displayed
var scale = document.getElementById(self.options.scaleElementId);
var location = document.getElementById(self.options.locationElementId);

// Build up all the map controls
map.addControl(new OpenLayers.Control.PanZoomBar({
    position: new OpenLayers.Pixel(2, 2)
}));
map.addControl(new OpenLayers.Control.Navigation());
map.addControl(new OpenLayers.Control.ZoomBox());
map.addControl(new OpenLayers.Control.Attribution());
map.addControl(new OpenLayers.Control.ScaleLine());
map.addControl(new OpenLayers.Control.Scale(scale));
map.addControl(new OpenLayers.Control.MousePosition({ element: location,
numDigits: 2, emptyString: "" }));

map.zoomToExtent(mapExtent);

// Create the base layer
var createBaseLayer = function (title, rasterLayerName) {
    var layer = new OpenLayers.Layer.WMS(
        title,
        self.serviceUrl,
        {
            LAYERS: rasterLayerName,
            format: "image/png",
            tiled: true,
            tilesOrigin: map.maxExtent.left + ',' + map.maxExtent.bottom
            // NOTE: The tilesOrigin value is having no effect on loading
data from cache (i.e. the same zoom levels get hit and the same are missed)
            //tilesOrigin: 1346.748175220855 + ',' + 7097.996956234318 //
>From gridset in GeoServer
        },
        {
            buffer: self.config.bufferSize,
            displayOutsideMaxExtent: true,
            isBaseLayer: true,
            yx: yx,
            attribution: self.config.copyright,
            tileOptions: { maxGetUrlLength: 2000 }
        }
    );

    // Add to base layers array
    self.baseLayers.push(layer);

    return layer;
};


Many thanks in advance.  

Regards,

Imran




--
View this message in context: http://osgeo-org.1560.x6.nabble.com/Using-GeoWebCache-with-OpenLayers2-Only-certain-zoom-levels-are-hit-tp5252874.html
Sent from the OpenLayers Users mailing list archive at Nabble.com.


More information about the Users mailing list