2

I'm using OpenLayers 3 and attempting to display a layer based on a custom tile grid in a custom projection (EPSG:4202) on a standard projection map (EPSG:3785). The layer is essentially a photo of a map that I took, and then split it into a tile grid of images. I have successfully created the directory structure and image files, and OpenLayers can see them and display them, putting all the tiles together in the right sequence relative to each other.

However, the layer is displayed much, much smaller than it should be. The origin is in the right place, but the image is tiny... all shrunk up towards the origin.

I guess I'm calculating the resolutions incorrectly. This also implied by the insane number of tiles that OpenLayers wants to fetch (and when zoomed out, the OpenLayers error that appears in the JavaScript console when zoomed out that says: Assertion Failed: reasonable number of tiles is required).

Eventually it displays a small rectangular image where the origin (top-left) of this image is in the correct location. But the image should be much larger and should extent much further down and to the right.

Complete code is below.

<!doctype html>
<html lang="en"><head>
    <link rel="stylesheet" href="ol/ol.css" type="text/css" />
    <link rel="stylesheet" href="map.css" type="text/css" />
    <script src="ol/ol-debug.js" type="text/javascript"></script>
    <script src="proj4/proj4.js" type="text/javascript"></script>
</head>
<body class="map">

<div id="map"></div>
<br/>
<div id="mouseposition"></div>

<script>

proj4.defs('EPSG:4202', '+proj=longlat +ellps=aust_SA +towgs84=-117.808,-51.536,137.784,0.303,0.446,0.234,-0.29 +no_defs ')

var tileGrid = new ol.tilegrid.TileGrid({
    minZoom:0,
    maxZoom:4,
    tileSizes:[[256,256],[256,256],[256,256],[256,256],[256,256]],
    resolutions:[0.00017674089784376154,8.8370448921880771e-05,4.4185224460940386e-05,2.2092612230470193e-05,1.1046306115235096e-05],
    origins:[[146.5,-41],[146.5,-41],[146.5,-41],[146.5,-41],[146.5,-41]],
//  extent: [146.5, -41.49986566362171, 146.99982325910216, -41.0],
});
var localSource = new ol.source.XYZ({
    url: 'http://nik.nixanz.com/Documents/Tamar100k/{z}/{x}/{y}.png',
    tileGrid: tileGrid,
    projection: 'EPSG:4202',
});

var defaultTileURLFunction = localSource.getTileUrlFunction();

localSource.setTileUrlFunction(function (tileCoord, pixelRatio, projection) {
    var tileURL = defaultTileURLFunction(tileCoord, pixelRatio, projection);
    console.log("TILE GRID URL:  " + tileURL);
    return tileURL;
});

localLayer = new ol.layer.Tile({
    source: localSource,
});

    
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({ source: new ol.source.OSM() }),
        localLayer,
    ],
    target: 'map',
    view: new ol.View({
        center: [16350000, -5030000],
        zoom: 10
    })
});

var mousePosition = new ol.control.MousePosition({
        coordinateFormat: ol.coordinate.createStringXY(2),
    projection: 'EPSG:4202',
        target: document.getElementById('mouseposition'),
        undefinedHTML: '&nbsp;'
      });

      map.addControl(mousePosition);

</script>

</body>
</html>

Here's how I calculated the resolutions (this is pseudo-code, not JavaScript):

resolution = ( imageExtentInLayerProjection[2] - imageExtentInLayerProjection[0] ) / imageWidth

Each subsequent resolution is:

resolution /= 2

(imageExtentInLayerProjection is the extent of the intended layer's spatial reference system that the original map image should cover. It is an array of the form: [minX, minY, maxX, maxY]. The values were taken from the map graticule labels. The actual values are: [146.5, -41.5, 147, -41]).

What am I doing wrong here?

2
  • What are the values of imageExtentInLayerProjection[2] and imageExtentInLayerProjection[0]? How did you get/calculate them?
    – TomazicM
    Apr 24, 2021 at 10:18
  • ah yes... good point. I've updated the question to clarify this now. Apr 25, 2021 at 9:56

1 Answer 1

2

I think I have this fixed now. It seems that I had the right idea of how to calculate the resolutions, but I made a blunder in the execution.

I was calculating the “first” resolution for the fully zoomed in (full-sized) image correctly. But of course the fully zoomed-in resolution should actually be the LAST resolution, not the first. Then the subsequent (or actually previous!) resolutions SHOULD have been *= 2 and not /= 2, of course. And then insert each subsequent (actually previous) resolution at the beginning of the resolutions array instead of appending to the end.

The reason I got it backwards, is that I was starting everything (including splitting the image into tiles) at the image's full-size (full resolution). But of course this is the last resolution. Whereas the resolutions array starts with zoom level "0" at the other (zoomed OUT) end and works in towards the fully zoomed in level at the END.

Based on this revised logic, my resolutions array is now:

[0.0028278543655001847,0.0014139271827500923,0.00070696359137504617,0.00035348179568752308,0.00017674089784376154]

Notice that the value from the beginning of my original array is now the value at the end of the new array. The values are all still each half of the previous value. Just working down towards that same value, instead of starting with it and then working down. Doh!

(It sort-of/nearly working now. The image is close to the correct size and shape. Not quite, so I'm not 100% sure of everything, but it's close enough to think that I have this particular problem solved, and there's something else I now have to figure out.)

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.