Lat/lon to map tile
Find which web map tile contains a point: 51.5074, -0.1278 at zoom 12 falls in tile 12/2046/1362, column 2046 and row 1362. You also get the tile's edges and a ready z/x/y path. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Latitude in decimal degrees
- 51.5074
- Longitude in decimal degrees
- -0.1278
- Zoom
- 12
- N
- 4,096
- X
- 2,046
- Y
- 1,362
- Z
- 12
Map tile calculators answer a daily GIS question: given a point on Earth and a zoom level, which square of the global Web Mercator pyramid contains that point? This tool takes decimal latitude and longitude plus an integer zoom, then returns the slippy-map tile X and Y indices used by OpenStreetMap, Mapbox, Leaflet, and most XYZ tile servers. The math is the standard projection: scale longitude linearly across two to the power of zoom columns, and map latitude through the inverse hyperbolic sine of the tangent so the mercator y axis matches the same square grid. You also receive the geographic bounds of that tile and a ready-made z/x/y path string for URLs and caches.
How lat/lon becomes a slippy-map tile index
Web Mercator, often labeled EPSG three eight five seven, flattens the globe onto a square that doubles in resolution at every zoom step. At zoom zero a single tile covers the whole projected world. At zoom one the square splits into a two-by-two grid, at zoom two into four-by-four, and in general the axis length n equals two raised to the zoom.
Longitude maps linearly: add one hundred eighty degrees, divide by three hundred sixty, multiply by n, and take the floor to obtain the column index x. Latitude is not linear in degrees; the mercator y coordinate uses the inverse hyperbolic sine of the tangent of latitude in radians, or the equivalent natural log of tangent plus secant. After normalizing that mercator value into the unit interval from zero at the north edge to one at the south edge, multiply by n and floor to obtain the row index y.
Indices run from zero inclusive through n minus one inclusive on each axis, matching the familiar z slash x slash y URL pattern of OpenStreetMap and compatible tile CDNs. Because tan of latitude diverges at the poles, Web Mercator only admits latitudes inside about plus or minus eighty-five point zero five one one degrees; this calculator rejects values outside that closed band rather than clamping without warning. Longitude must stay inside the closed interval from negative one hundred eighty to positive one hundred eighty degrees.
Zoom must be a non-negative integer no greater than thirty so that two to the zoom stays a practical integer tile count.
What you send and what you get back
Send three required finite numbers under the fields latitude, longitude, and zoom. Latitude must lie inside the Web Mercator closed range of approximately negative eighty-five point zero five one one through positive eighty-five point zero five one one degrees with north positive. Longitude must lie in the closed interval from negative one hundred eighty to positive one hundred eighty degrees with east positive.
Classic checks include London near fifty-one point five zero seven four north, zero point one two seven eight west at zoom twelve, and verifying that the returned x and y match known OpenStreetMap tile inspectors. Wire the free browser form for debugging map layers and classroom demos, then call the identical contract from scripts when you need bulk tile key generation or cache warm-up lists.
Where lat/lon to map-tile conversion shows up in real work
Front-end map engineers constantly convert GPS fixes and geocoder results into tile coordinates so they can request the right raster or vector tile, debug missing imagery, and compare cache keys across CDNs. Backend services that pre-warm tile caches or shard geospatial workloads by pyramid cell need a trusted closed form that matches Leaflet, OpenLayers, and Mapbox GL without pulling a full projection library into a worker.
Curriculum authors teaching GIS and web mapping want students to see the mercator formulas produce integer indices and readable tile bounds without a silent clamp at the poles. Logistics and IoT pipelines that store only coarse tile keys for privacy or storage reasons still need the forward conversion from precise coordinates at ingest time. If you later need the inverse problem of tile center or full quadkey encoding, ellipsoid geodesics, or great-circle destination points, treat those as separate search intents and landings rather than overloading this slippy-map tile index page.
What you can do with it
Debug map layers and tile URLs
Turn a GPS or geocoder lat/lon plus zoom into z/x/y so you can open the exact OSM or XYZ tile URL and compare cache keys across environments.
Pre-warm and shard tile caches
Batch-convert waypoint lists into pyramid cell indices for CDN warm-up jobs, regional shards, and privacy-preserving coarse geohash-style storage.
FAQ
What tile scheme does this calculator use?
Compatible with OpenStreetMap, Mapbox, Leaflet, and most XYZ servers.
Why is latitude limited to about ±85.0511°?
Web Mercator is singular at the poles. The closed range is arctan(sinh(π)) ≈ ±85.05112878°.
What happens if zoom is negative?
Zoom must be a non-negative integer in [0, 30]. Negative or fractional zoom is not a valid slippy-map pyramid level.
Does the response include the tile’s geographic bounds?
Yes. Besides x, y, z and the z/x/y path string, you get west, south, east, and north edges in decimal degrees for the selected tile square.
What does it cost?
The browser tool is free and runs locally.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/geo/tile-from-latlon \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"latitude":51.5074,"longitude":-0.1278,"zoom":12}'const res = await fetch("https://api.kit.forhosting.com/geo/tile-from-latlon", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"latitude": 51.5074,
"longitude": -0.1278,
"zoom": 12
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/geo/tile-from-latlon",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"latitude": 51.5074,
"longitude": -0.1278,
"zoom": 12
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/geo/tile-from-latlon", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"latitude":51.5074,"longitude":-0.1278,"zoom":12}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"latitude":51.5074,"longitude":-0.1278,"zoom":12}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/geo/tile-from-latlon", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"latitude": 51.5074,
"longitude": -0.1278,
"zoom": 12
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "geo.tile_from_latlon",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Negative zoom, non-integer zoom, latitudes beyond the mercator limit near eighty-five degrees, and longitudes outside plus or minus one hundred eighty fail with a clear invalid_input message instead of inventing a silent wrap.
What you send and what you get back
Zoom must be an integer greater than or equal to zero and at most thirty; negative zoom, fractional zoom, and absurdly large zoom levels fail with invalid_input and are not charged. Common aliases such as lat, lon, lng, and z are accepted at parse time while the response always echoes the canonical field names. On success the response returns cleaned latitude, longitude, and zoom, the axis length n equals two to the zoom, integer tile indices x and y, a mirrored z field, a tile path string in z slash x slash y form, a bounds object with west, south, east, and north edges of that tile in degrees, the max_mercator_lat constant, the method tag web_mercator_slippy, and a compact formula string for documentation. Pricing for successful API calls is the published base of $0.002 per item; validation failures do not consume prepaid balance.
Where lat/lon to map-tile conversion shows up in real work
Because this capability is a pure parse engine, API pricing is the published base of $0.002 per successful item and failed validation does not consume balance.
Integration use cases
GIS homework and golden fixtures
Generate stable tile X/Y and bounds for textbook landmarks so instructors, auto-graders, and regression suites share one Web Mercator ground truth.