Get map tiles bounding box
Asked Answered
I

2

7

Is it possible to get tiles LngLat bounding box? (and center/width if possible)

I.e given any tile "id" (e.g 6/33/24), calculate wanted coordinates. I'm so desperate to get an answer that I don't even care in what language it's written.


Context

Tile "id" has 3 parts: 6/33/24 (z/x/y).

z being floored zoom (0-24) and x/y tile number from left/top origin point.

When zoom is 1, whole map is divided into 4 equal tiles (shown in graphic). Every time zoom (z) increases, each tile is subdivided into 4 equal tiles (e.g zoom 2 = 16 tiles).

 _______________________
|          |           |
|  1/0/0   |   1/1/0   |
|          |           |
|__________|___________|
|          |           |
|  1/0/1   |   1/1/1   |
|          |           |
|__________|___________|

Why?

I want to implement client-side marker cache and binding them to tiles seems to be the most reasonable solution. I know how to get tiles (loop over sourceCaches tiles or use few transform methods) but I have no idea how to get LngLat data from tile matrices or tile IDs.

Super basic JavaScript concept of marker cache (for context):

const markerCache = {
  cache: {},

  getMarkersForTile: function(key) { // tiles have unique keys
    if (this.cache[key]) {
      return Promise.resolve(this.cache[key]);
    }

    // ??? what should be in "getTileBounds"?
    const bounds = getTileBounds(key);
    
    return fetchMarkersForTile(bounds).then(markers => {
      this.cache[key] = markers;
      return markers;
    });
  }
};
Incendiary answered 29/12, 2020 at 15:57 Comment(2)
Where is the id data coming from?Dungdungan
I believe your question was answered by Alvin Lindstam here: #32047101. The formula you are looking for, in Javascript, is in his answer.Warila
M
8

I believe you are looking for this library:

https://github.com/mapbox/tilebelt

It includes the tileToBBOX(tile) function, which will return you a bounding box for the given tile.

usage:

var tilebelt = require('@mapbox/tilebelt');

var tile = [10,15,8] // x,y,z

var bbox = tilebelt.tileToBBOX(tile);
Matherne answered 7/1, 2021 at 11:10 Comment(0)
D
3

I believe you are looking for the Slippy Map Tilenames specs as mentioned in https://docs.mapbox.com/api/maps/vector-tiles/

There are many programming languages implementations in the link

Java Example

  class BoundingBox {
    double north;
    double south;
    double east;
    double west;   
  }

  BoundingBox tile2boundingBox(final int x, final int y, final int zoom) {
    BoundingBox bb = new BoundingBox();
    bb.north = tile2lat(y, zoom);
    bb.south = tile2lat(y + 1, zoom);
    bb.west = tile2lon(x, zoom);
    bb.east = tile2lon(x + 1, zoom);
    return bb;
  }

  static double tile2lon(int x, int z) {
     return x / Math.pow(2.0, z) * 360.0 - 180;
  }

  static double tile2lat(int y, int z) {
    double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
    return Math.toDegrees(Math.atan(Math.sinh(n)));
  }
Dungdungan answered 5/1, 2021 at 22:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.