[GIS] Get/Define extent of ol.source.tile xyz

extentsopenlayerstileszoom

I have a series of tile sources equating to different map providers at specific resolutions and I would like to set an extent so that when the relevant layer is selected, the map pans and zooms to the extent of the tiles.

Following this example I've set the extent for each source. I'm also able to get the extent of the selected layer using this code in my layerswitcher control:

curExtent = map.getView().calculateExtent(map.getSize());
            if (extent != null) {
                extent = layers[s].getExtent();
            }
            else {
                extent = map.getView().calculateExtent(map.getSize());
            }
            layerZoom = layers[s].getProperties().minZoom;
            map.getView().fit(extent, map.getSize());
            layers[s].setVisible(true);

I'm able to get the resolution/zoom at this point but I'm not sure how to set the view to the minResolution/zoom property of each source. Can anyone please help?

Further to this I'm now able to get the map to pan and zoom but the layer tiles don't appear. I thought it was a projection issue but I'm in the right location and zoom. Do I need to delay loading of the tiles maybe?

Here is the amended code:

var curExtent = map.getView().calculateExtent(map.getSize());
if (title == selectedValue) {
            if (extent != []) {
                extent = layers[s].getExtent();
            }
            else {
                extent = curExtent;
            }
            console.log(extent);
            layerZoom = layers[s].getProperties().minZoom;
            var sourceCentre = ol.extent.getCenter(extent);
            console.log(sourceCentre);
            console.log(layerZoom);
            console.log(curExtent);              
            console.log(extent);               
            map.getView().setCenter(sourceCentre);
            map.getView().setZoom(layerZoom);
            layers[s].setVisible(true);
        }
        else {
            layers[s].setVisible(false);
        }

I've set up a simple fiddle which now seems to work although I'm struggling to get the extent of the other standard map layers and the functionality seems to break after the initial successful action.

Best Answer

So the solution I found to this was to add a check for another value on the layer. In this case, the value of 'sub'. This allowed me to perform a check as to whether the layer source had a defined extent. If the extent was found, I looked up the minZoom value, got the centre coordinate of the extent, then set the view to this.

The functionality seemed to break if I checked for the extent property on a non-defined source so the check for the 'sub' property negated this. It's been a long road from locating a quadkey function, working out how to apply this to a custom xyz url, finding out how to transform the projection of the extent then looking up the zoom and setting a new view; not to mention creating a select menu from the layers, but the effort was definitely worth it.

I'm sure my code looks a little ropey to most people and I'll have the opportunity to refine it later but thanks to anyone who helped along the way. @AlvinLindstam, @JonatasWalker and @Pavlos have all helped me to better understand how all of this fits together. For the benefit of anyone looking to do something similar, I'll post the code below and here is a link to the fiddle.

var sub = layers[s].get('sub'); // where layers[s] is the result of a layer search
var extent;
    if (title == selectedValue) {   
        if (sub == undefined) {
           layers[s].setVisible(true);
        }
        if (sub == 'premium') {
                var duration = 2000;
                var start = +new Date();
                var view = map.getView();
                var pan = ol.animation.pan({
                    duration: duration,
                    //easing: eval(ol.easing.inAndOut),
                    source: (view.getCenter()),
                    start: start
                });
                var bounce = ol.animation.bounce({
                    duration: duration,
                    resolution: 4 * view.getResolution(),
                    start: start
                });

                // Add animation to the render pipeline
                map.beforeRender(pan, bounce);

                extent = layers[s].getExtent();
                console.log(extent);
                layerZoom = layers[s].getProperties().minZoom;
                var sourceCentre = ol.extent.getCenter(extent);
                view.setCenter(sourceCentre);
                view.setZoom(layerZoom);
                layers[s].setVisible(true);
            }