0

I have own tiles (.png) of 512x512 pixels and I would like to display them in OpenLayers 3 without projection (for now). Therefore I found a way to use the ZOOMIFY projection but with a "ol.layer.Tile"-Layer. (original source: https://groups.google.com/forum/#!topic/ol3-dev/VVdNXHwiZEk)

So far it works more or less, but I am encountering problems providing the right extent of the layer. I have a map DIV of 1024x512 pixels and strangely for zoom level 0: only the left tile is displayed (the right one is missing).

Zoom level 0 has a resolution of 2 (check the variable resolutions) and therefore I thought that I need an extent of 2048(x) and 1024(y) to display 2 tiles of zoom level 0. [1][2]

My guess is that the provided extent causes the problems.

Any ideas how to improve on this?

Here's a jsfiddle: http://jsfiddle.net/vb53xz20/

[1]tile1: services.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer/tile/0/0/0.png

[2]tile2: services.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer/tile/0/0/1.png

And the code:

tileSize = 512;

projection = new ol.proj.Projection({
    code: 'ZOOMIFY',
    units: 'pixels',
    extent: [0, 0, 1024, 1024]
});

projectionExtent = projection.getExtent();

var maxResolution = ol.extent.getWidth(projectionExtent) / tileSize;
window.resolutions = [];
for (var z = 0; z <= 10; z++) {
    resolutions[z] = maxResolution / Math.pow(2, z);

}

urlTemplate = 'http://services.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer/tile/{z}/{y}/{x}';

tileLayer = new ol.layer.Tile({
    source: new ol.source.TileImage({
        tileUrlFunction: function(tileCoord, pixelRatio, projection) {
            tileCoordGlobal = tileCoord;

            return urlTemplate
                .replace('{z}', (tileCoord[0]).toString())
                .replace('{x}', (tileCoord[1]).toString())
                .replace('{y}', (((-tileCoord[2])-1)).toString())
            ;
        },
        wrapX: true,
        projection: projection,
        tileGrid: new ol.tilegrid.TileGrid({
            origin: ol.extent.getTopLeft(projectionExtent),
            resolutions: resolutions,
            tileSize: tileSize
        }),
    }),
    extent: projectionExtent        
});

view = new ol.View ({
    projection: projection,
    center: [1024, 512],
    extent: projectionExtent,
    zoom: 0,
    resolutions: resolutions
});

window.map = new ol.Map({
    layers: [tileLayer],
    target: 'map',
    view: view
});
0

Alrighty, I finally found out how to set the parameters. The problems were due to the resolution and the extent arrays.

I) The resolution array needed a "z+1" instead of "z":

for (var z = 0; z <= 16; z++) {
    resolutions[z] = maxResolution / Math.pow(2, z+1);
}

(btw: the number of z in the for-loop defines the number of available zoom levels)


II) And the extent array some adaptions.

The 4 values of the extent array are: [MinX, MinY, MaxX, MaxY]. We can start with 0s for both min-values. The max values depend on:

a) the number of tiles
b) the resolutions
c) the tilesize

I found that this formula worked well for my purposes:
MaxX(MaxY) = No of tiles x resolution[0] x tilesize

For the example above this would mean:

MaxX = 2 x 2 x 512 = 2048
MaxY = 1 x 2 x 512 = 1024

var minX = 0;
var minY = 0;
var maxX = 2048;
var maxY = 1024;

extent: [minX, minY, maxX, maxY]


III) The center can be set to [MaxX/2, MaxY/2]

center: [maxX/2, maxY/2]


Here is the updated jsfiddle: http://jsfiddle.net/vb53xz20/2/

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.