惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
博客园 - Franky
The Cloudflare Blog
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
B
Blog
Y
Y Combinator Blog
V
V2EX
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
博客园 - 司徒正美
IT之家
IT之家
G
Google Developers Blog
C
Check Point Blog
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How a map works, Mercator, tiles, and your GPS pin
I Want To Learn Programming · 2026-06-23 · via DEV Community

I Want To Learn Programming

You drag a map, it loads more map. You drop a pin, it lands exactly where you tapped. This feels like one seamless thing, but underneath, every "slippy map", Google Maps, OpenStreetMap, the map in a thousand apps, is built from two pieces of math: a way to flatten a round Earth onto a flat screen, and a way to chop that flat image into loadable squares. Both fit in a few lines of Python.

Learn them and your blue dot stops being magic: you will be able to take a latitude and longitude and compute exactly which image tile it falls in and where inside that tile the pin goes.

The one idea: the Earth is round and your screen is not

A screen is a flat grid of pixels. The Earth is a sphere. To draw one on the other you need a projection: a rule that turns (longitude, latitude) into (x, y). There are many, each lying about the Earth in a different way (you cannot flatten a sphere without distortion). Web maps almost all use one, Web Mercator, because it has a property that makes interactive maps possible: it is conformal, it preserves angles and local shape, so north is always up and a small square of ground stays square. The price is area: Greenland looks the size of Africa. For navigation, keeping shapes and directions right is the trade everyone makes.

Step one: flatten the globe

Longitude is the easy axis, it maps straight to x. Latitude is the interesting one: Mercator stretches it more and more toward the poles (that is the Greenland effect), using a logarithm.

import math

def mercator(lon, lat):
    x = math.radians(lon)
    y = math.log(math.tan(math.pi / 4 + math.radians(lat) / 2))
    return x, y

print(mercator(0, 0))      # (0.0, 0.0)        equator / prime meridian
print(mercator(0, 60))     # (0.0, 1.317...)   60N is pushed far from the equator

That log(tan(...)) is the whole Mercator projection. The reason a degree of latitude near the pole takes more vertical space than a degree at the equator is exactly that logarithm growing. Everything else is rescaling this into pixels.

Step two: chop it into tiles

A world map at full zoom is billions of pixels, you cannot download it. So the projected world is cut into a quadtree of 256×256-pixel tiles. At zoom 0 the whole world is one tile. At zoom 1 it is a 2×2 grid (four tiles). At zoom z it is a 2^z × 2^z grid. Each tile has an address (x, y, z), and that is literally the URL the map requests: .../z/x/y.png.

Here is the standard formula that turns a coordinate into the tile that contains it:

def lonlat_to_tile(lon, lat, z):
    n = 2 ** z
    x = int((lon + 180.0) / 360.0 * n)
    lat_rad = math.radians(lat)
    y = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
    return x, y

print(lonlat_to_tile(-0.1276, 51.5072, 12))   # London -> (2047, 1362)

Two details that matter:

  • asinh(tan(lat)) is the Mercator y in disguise. asinh(tan(θ)) equals log(tan(π/4 + θ/2)) from step one, the same projection, just written so it normalizes neatly into the 0..1 range that the tile grid needs.
  • int(...) picks the tile; the fractional part picks the spot inside it. Keep the fraction instead of truncating and you get where in the tile the point lands, the pixel your pin sits on. Drag the map and the viewer just computes which (x, y, z) tiles overlap the screen and fetches them. That is the entire "slippy" mechanism.

Step three: where the blue dot comes from

Your device's GPS gives a raw (latitude, longitude). The map runs exactly the math above: project to Web Mercator, figure out which tiles are on screen and where they sit, then place the marker at the projected position. The blue dot is mercator(lon, lat) rescaled to screen pixels, nothing more. (How the GPS got that lat/lon in the first place, trilateration from satellite timing, is its own beautiful story for another post.)

Why this is worth knowing

Maps feel like a solved, sealed product, but they are just a projection plus a tiling scheme, and both are short. Once you have written them you can do things that otherwise look like wizardry: pre-compute which tiles a region needs, place markers without a mapping library, reason about why two map providers' tiles line up (they agree on Web Mercator and the z/x/y scheme), or debug why a point is "slightly off" (usually someone mixed up a projection).

This is the recurring payoff of building the primitive yourself: the product stops being opaque. A degree of latitude, a logarithm, a quadtree of squares, that is a world map. If you want to go further, distances on a sphere, projections and their trade-offs, spatial indexing, GPS trilateration, that is the path through the geospatial track, where you build the map from the coordinates up.