TileUtils#
- class rapidtools.data_sources.TileUtils[source]#
Bases:
objectUtility methods for Web Mercator/Mapbox Vector Tile operations.
This class provides static helpers for:
Converting between WGS84 (lat/lon) and XYZ tile coordinates
Converting Mapbox Vector Tile (MVT) local coordinates to WGS84
Determining zoom levels and tile coverage for bounding boxes
Converting millisecond timestamps to UTC dates
All geographic coordinates are assumed to be:
Latitude in degrees, in the range [-85.05112878, 85.05112878]
Longitude in degrees, in the range [-180, 180]
Example
>>> from rapidtools.core import BoundingBox >>> from rapidtools.data_sources import TileUtils >>> >>> bbox = BoundingBox(-118.251, 34.050, -118.250, 34.051) >>> tiles = TileUtils.bbox_to_mapbox_tiles(bbox, zoom=16) >>> all(z == 16 for _, _, z in tiles) True
Methods
Compute XYZ tiles that cover a bounding box.
Find the highest zoom where the bounding box fits inside one tile.
Convert latitude/longitude to fractional XYZ tile coordinates.
Convert a millisecond UNIX timestamp to a UTC date string.
Convert MVT local tile coordinates to WGS84 (longitude, latitude).
- static latlon_to_tile(lat: float, lon: float, z: int) tuple[float, float][source]#
Convert latitude/longitude to fractional XYZ tile coordinates.
Uses the Web Mercator tiling scheme where: at zoom level
zthere are2^ztiles in both X and Y.- Parameters:
lat – Latitude in degrees.
lon – Longitude in degrees.
z – Zoom level (e.g., 0-22).
- Returns:
A tuple
(xtile, ytile)of fractional tile coordinates at zoomz. The integer partsfloor(xtile)andfloor(ytile)are the tile indices; the fractional parts represent the position within that tile.
Example
>>> TileUtils.latlon_to_tile(0.0, 0.0, 1) (1.0, 1.0)
- static mvt_to_wgs84(shape_x: int, shape_y: int, tile_x: int, tile_y: int, tile_z: int, extent: int = 4096) tuple[float, float][source]#
Convert MVT local tile coordinates to WGS84 (longitude, latitude).
The local coordinates
shape_xandshape_yare integers in the coordinate space of a single Mapbox Vector Tile (commonly0..extent). The enclosing tile is specified by global XYZ tile indices.- Parameters:
shape_x – X coordinate in the MVT local coordinate space (0 to
extent).shape_y – Y coordinate in the MVT local coordinate space (0 to
extent).tile_x – Global tile X index at zoom
tile_z.tile_y – Global tile Y index at zoom
tile_z.tile_z – Zoom level of the tile.
extent – Resolution of the local tile coordinate grid. Defaults to 4096 (typical for Mapbox Vector Tiles).
- Returns:
A tuple
(lon, lat)where –lonis longitude in degrees (WGS84).latis latitude in degrees (WGS84).
Example
>>> lon, lat = TileUtils.mvt_to_wgs84(0, 0, 0, 0, 0) >>> lon, round(lat, 6) (-180.0, 85.051129)
- static ms_to_date_utc(timestamp_ms: int) str[source]#
Convert a millisecond UNIX timestamp to a UTC date string.
The input timestamp is interpreted as milliseconds since the Unix epoch (1970-01-01T00:00:00Z). The function converts it to a UTC date and returns an ISO 8601 formatted string (YYYY-MM-DD).
- Parameters:
timestamp_ms – Timestamp in milliseconds since Unix epoch (UTC).
- Returns:
A Unicode string representing the UTC date in ISO format (YYYY-MM-DD).
Example
>>> TileUtils.ms_to_date_utc(0) '1970-01-01' >>> TileUtils.ms_to_date_utc(1_700_000_000_000) '2023-11-14'
- static get_enclosing_zoom(bbox: BoundingBox) int[source]#
Find the highest zoom where the bounding box fits inside one tile.
This method searches zoom levels from 22 down to 14 and returns the maximum zoom level at which the entire bounding box is contained within a single XYZ tile. If the bounding box spans multiple tiles at all zooms in that range, 14 is returned.
The bounding box is expected to provide Shapely-like bounds in the order
(min_lon, min_lat, max_lon, max_lat).- Parameters:
bbox – Bounding box object with a
shapelygeometry exposing a.boundsattribute.- Returns:
The highest integer zoom level in the range [14, 22] at which the bounding box fits into a single tile. Returns 14 if no higher zoom level satisfies this condition.
Example
>>> from rapidtools.core import BoundingBox >>> # A very large box never fits in one tile above zoom 14: >>> TileUtils.get_enclosing_zoom(BoundingBox(-120, 30, -110, 40)) 14
- static bbox_to_mapbox_tiles(bbox: BoundingBox, zoom: int | None = None) list[tuple[int, int, int]][source]#
Compute XYZ tiles that cover a bounding box.
The bounding box is given in WGS84 coordinates via the
bbox.boundsattribute. Tiles are computed using the standard Web Mercator XYZ scheme.If
zoomis not provided, the highest zoom at which the entire bounding box fits into a single tile (as returned byget_enclosing_zoom()) is used. In that case the result is often a single tile.- Parameters:
bbox – Bounding box object with a
shapelygeometry exposing a.boundsattribute in the order(min_lon, min_lat, max_lon, max_lat).zoom – Zoom level at which to compute coverage. If
None, the zoom level is determined byget_enclosing_zoom().
- Returns:
A list of tile coordinates
(x, y, z)covering the bounding box, including all integer tiles frommin_x..max_xandmin_y..max_yinclusive.
Example
>>> from rapidtools.core import BoundingBox >>> TileUtils.bbox_to_mapbox_tiles(BoundingBox(-1, -1, 1, 1), zoom=1) [(0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 1)]