SlippyTiles

Web-Mercator (slippy-map) tile ↔ geographic conversions, shared by the MVT and OSM-Buildings layers and the bulk-retrieval drivers so the projection math lives in exactly one place. Tiles follow the standard 256-px OSM/XYZ scheme: x grows east, y grows south (y = 0 is north), with n = 2^zoom tiles per axis. Latitude is clamped to ±maxLatitudeDegrees.

This is the single source of truth for the Web-Mercator projection: MercatorSector (the earth.worldwind.util.LevelSet-backed render quadtree's warped extent) delegates its gudermannian math to mercatorYToLatRadians / latRadiansToMercatorY here, so the scalar hot-path kernel and the object-model tiling can never drift.

Properties

Link copied to clipboard

Web-Mercator latitude limit in degrees; slippy servers/clients clamp to ±this.

Link copied to clipboard

Web-Mercator latitude limit in radians — atan(sinh(π)) (≈ 85.0511°), where the projection becomes square.

Functions

Link copied to clipboard

Web-Mercator inverse projection: latitude in radians → normalized Mercator-Y in [-1, 1].

Link copied to clipboard
fun latToTileY(latDegrees: Double, zoom: Int): Int

Slippy row (0 = north) for latDegrees at zoom, clamped to Mercator bounds and pyramid height.

Link copied to clipboard
fun lonLatToTile(lonDegrees: Double, latDegrees: Double, zoom: Int): Pair<Int, Int>

Slippy (x, y) containing lonDegrees/latDegrees at zoom.

Link copied to clipboard
fun lonToTileX(lonDegrees: Double, zoom: Int): Int

Slippy column for lonDegrees at zoom, clamped to the pyramid width.

Link copied to clipboard

Web-Mercator forward projection: normalized Mercator-Y in [-1, 1] → latitude in radians (y = +1 → north limit).

Link copied to clipboard
fun tileToSector(zoom: Int, x: Int, y: Int): Sector

Geographic bounds of slippy tile (zoom, x, y) (y slippy, 0 = north).

Link copied to clipboard
fun tileXToLonDegrees(tileX: Double, tilesPerAxis: Double): Double

Longitude (degrees) at fractional slippy column tileX (integer tile + in-tile fraction), where tilesPerAxis = 2^zoom. Split out so per-vertex unprojection (e.g. MVT geometry) shares the same projection as tileToSector while hoisting tilesPerAxis out of its loop.

Link copied to clipboard
fun tileYToLatDegrees(tileY: Double, tilesPerAxis: Double): Double

Latitude (degrees, row 0 = north) at fractional slippy row tileY, where tilesPerAxis = 2^zoom.

Link copied to clipboard
fun zoomForResolution(resolution: Angle): Int

Slippy zoom whose resolution best matches resolution, mirroring earth.worldwind.util.LevelSet.levelForResolution's nearest-neighbor rounding so a resolution range selects the same levels here as it does for raster/elevation layers. Never negative; callers clamp the upper bound to the deepest available zoom.