td-edge td-edge -4 years ago 113
Javascript Question

Magnifying Tiles in OpenLayers 2 or Increasing MaxZoom Without Distorting Projection

I am using OpenLayers2 with Bing. My customer requires a deeper zoom level to interact with the maps. Currently, the max zoom level I can achieve is 19 which I tested with the getZoom() function. I have tried to set the "numZoomLevels" in the map constructor to a higher number, but Bing/OL just seems to ignore it. I was wondering if there is a way to force the tiles to a lower zoom level or if I could simply magnify the existing tiles so that I can see larger images even if the details are a bit blurry. It is crucial, however, that I don't modify the projection because having correct lat/lon values is paramount to the customer's function.

map = new OpenLayers.Map('map', {
allOverlays: false,
numZoomLevels: 20,
controls: [
new OpenLayers.Control.Navigation({
dragPanOptions: {
enableKinetic: true
}
}),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.Zoom({
zoomInId: "customZoomIn",
zoomOutId: "customZoomOut"
})
]});

var aerial = new OpenLayers.Layer.Bing({
name: "Aerial",
key: apiKey,
type: "Aerial"
});


I did stumble across an OL3 magnify example, but it is written for OL3 and a bit beyond what I can convert since I need the magnify option to be embedded as a zoom level, not just a context overlay. Also, I don't have a ton of experience with canvas. Any help is appreciated!

Answer Source

I figured it out, and it's actually quite simple. First, the numZoomLevels should have been on the layer level, not the map level. If you want to be able to zoom in beyond what Bing provides you, you must set fractionalZoom to true as shown below:

    map = new OpenLayers.Map('map', {
    allOverlays: false,
    fractionalZoom: true,
    controls: [
        new OpenLayers.Control.Navigation({
            dragPanOptions: {
                enableKinetic: true
            }
        }),
        new OpenLayers.Control.LayerSwitcher(),
        new OpenLayers.Control.Zoom({
            zoomInId: "customZoomIn",
            zoomOutId: "customZoomOut"
        })
    ]});

Then, on each layer, you need to set an array of resolutions. You will need to create a value for each zoom level you list under your numZoomLevels. I needed 22 zoom levels.

    var aerial = new OpenLayers.Layer.Bing({
      name: "Aerial",
      key: apiKey,
      type: "Aerial",
      numZoomLevels: 22,
      resolutions: bingResolutions,
      serverResolutions: bingServerResolutions,
      transitionEffect: 'resize'
    });

In the source code for OpenLayers.Layer.Bing already had a resolution block defined which maps to their values at: https://msdn.microsoft.com/en-us/library/aa940990.aspx

var bingResolutions = [156543.03390625, 78271.516953125, 39135.7584765625,
19567.87923828125, 9783.939619140625, 4891.9698095703125,
2445.9849047851562, 1222.9924523925781, 611.4962261962891,
305.74811309814453, 152.87405654907226, 76.43702827453613,
38.218514137268066, 19.109257068634033, 9.554628534317017,
4.777314267158508, 2.388657133579254, 1.194328566789627,
0.5971642833948135, 0.29858214169740677, 0.14929107084870338,
0.07464553542435169];

var bingServerResolutions = [156543.03390625, 78271.516953125, 39135.7584765625,
19567.87923828125, 9783.939619140625, 4891.9698095703125,
2445.9849047851562, 1222.9924523925781, 611.4962261962891,
305.74811309814453, 152.87405654907226, 76.43702827453613,
38.218514137268066, 19.109257068634033, 9.554628534317017,
4.777314267158508, 2.388657133579254, 1.194328566789627,
0.5971642833948135];

The server resolutions are the tile resolutions from Bing itself. The additional resolutions (0.29858214169740677, 0.14929107084870338, 0.07464553542435169) are my fractional zoom levels that just zoom in on the layer 19 tile.

Here is the working example from OpenLayers for an OSM layer.

Hope this helps someone else!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download