2

Is there a method to convert the normal {z}/{x}/{y} endpoints you would get from a tile service into an OpenLayers TileGrid tile?

Here is a mercator tile with coords:

enter image description here

However in OpenLayers the getTile(z,x,y) does not correspond to these coordinates, there is an internal TileGrid created I believe on the source data that pulls the specific tile instead of using the z,x,y from the normal mercator/slippy map tile endpoints.

For example the OL tile grid coord for another tile being [6,22,21] is something like [18,x,y] in mercator coordinates.

5
  • see updated comment above.
    – Malcolm
    Nov 16, 2023 at 18:02
  • OL has no tile grid of it's own. It's tile grid for Mercator projection is the same as standard tile grid for EPSG:3857 (Pseudo-Mercator or Spherical Mercator). The above situation could happen if tile layer is reprojected by OL on the fly to fit the different view projection.
    – TomazicM
    Nov 16, 2023 at 19:26
  • In the internals OL calls a function getTile(z,x,y) where z,x,y are not Merc coordinates but something else - that's what I'm looking for - I think it's some type of tile index or something
    – Malcolm
    Nov 16, 2023 at 20:06
  • They are tile grid coordinates of tile layer in its projection, whatever it is. If you have code where they are different, please provide reproducible sample.
    – TomazicM
    Nov 16, 2023 at 21:00
  • It's something like this - though the returned image covers slightly more area than what is shown on the map - const tile = tileGrid.getTileCoordForCoordAndZ(mapCoordinate, tileGridResolution); const img = source.getTile(t[0], t[1], t[2]); img.load();
    – Malcolm
    Nov 17, 2023 at 13:28

2 Answers 2

2

I'm not able to reproduce behavior you describe, where tile coordinates differ from internal OL tile coordinates.

For example, this click event processing function:

map.on('singleclick', function (evt) {
  const coordinate = evt.coordinate;
  const tileCoord = sourceOSM.getTileGrid().getTileCoordForCoordAndZ(coordinate, map.getView().getZoom());
  content.innerHTML = '<p>Tile coords:</p><code>' + tileCoord + '</code>';
  overlay.setPosition(coordinate);
  const tile = sourceOSM.getTile(tileCoord[0], tileCoord[1], tileCoord[2]);
  tile.load();
  const img = tile.getImage();
  container.appendChild(img);
});

gives this result:

enter image description here

1
  • This is great - I also got here from some comments in the OL repo. The only issue I have now is that the tile I get from my GeoTIFF does not match the Mercator boundaries - in the OL thread I was pointed to the idea that the GeoTIFF is not using the same grid which does not make sense to me. I'll post another question maybe and mark this as answered in terms of getting the proper tile for the merc grid. See this for what I am referring to - github.com/openlayers/openlayers/issues/…
    – Malcolm
    Nov 19, 2023 at 13:07
1

Slippy map tiles

The system to load tiles using the {zoom}/{x}/{y}.png filenames is called 'slippy map'. You can calculate the x and y values from the geographical coordinates (WGS84) using these functions:

function lon2tile(lon,zoom) {
    return (
        Math.floor((lon+180)/360*Math.pow(2,zoom))
    );
}

function lat2tile(lat,zoom) {
    return (
        Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) +
        1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))
    );
}

The reverse calculations look like this:

function tile2long(x,z) {
    return (
        x/Math.pow(2,z)*360-180
    );
}

function tile2lat(y,z) {
    var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
    return (
        180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n)))
    );
}

To get to and from other coordinate systems you willl have to reproject.

Source: wiki.openstreetmap.org/wiki/Slippy_map_tilenames

1
  • Thanks but I want the image from the internal TileGrid index for a raster, which is a grid of the source images. It looks like there is no straightforward conversion from the map tile to the internal grid coordinates.
    – Malcolm
    Nov 17, 2023 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.