Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding Tile-Based Mapping Systems

Tech 1

A tile-based mapping system stitches to gether small image tiles to display a complete map. Each tile is typically 256x256 pixels, and tiles are fetched from a server using a URL with parameters like x, y, and z. For example, a tile URL might look like: http://mt2.google.cn/vt/lyrs=m@167000000&hl=zh-CN&gl=cn&x=420&y=193&z=9&s=Galil.

Key URL parameters include:

  • x: The horizontal tile index, starting at 0 from the leftmost tile and increasing rightward.
  • y: The vertical tile index, starting at 0 from the topmost tile and increasing downward.
  • z: The zoom level, where 0 is the most zoomed-out view, increasing for more detailed levels.

Maps use the Web Mercator projection, which transforms the Earth's surface into a square plane. The map bounds in meters are [-20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892], with the center at (0,0). Each zoom level n has a resolution calculated as:

resolution = 20037508.3427892 * 2 / 256 / (2^n)

This resolution represents the geographic length per pixel at that level.

Given a map center point, zoom level, and viewport size, the visible bounds can be computed:

leftBound = centerX - resolution * viewportWidth / 2
bottomBound = centerY - resolution * viewportHeight / 2
rightBound = centerX + resolution * viewportWidth / 2
topBound = centerY + resolution * viewportHeight / 2

At zoom level n, the world map is divided into 4^n tiles, each 256x256 pixels. For example, level 0 uses 1 tile, level 1 uses 4 tiles, and so on.

To render tiles, calculate the indices of tiles within the viewport. Let mapBounds be the full map bounds, viewBounds the visible bounds, res the resolution, and tileSize as 256. The tile indices are:

startTileX = floor((viewBounds.left - mapBounds.left) / res / tileSize)
startTileY = floor((viewBounds.top - mapBounds.top) / res / tileSize)
endTileX = floor((viewBounds.right - mapBounds.right) / res / tileSize)
endTileY = floor((viewBounds.bottom - mapBounds.bottom) / res / tileSize)

The first tile URL is constructed with x=startTileX, y=startTileY, z=zoomLevel. Tiles between the start and end indices are fetched by iterating over x and y.

To position tiles on the screen, compute the geographic coordinates of the top-left corner of the starting tile:

tileCornerX = mapBounds.left + (startTileX * tileSize * res)
tileCornerY = mapBounds.top - (startTileY * tileSize * res)

Then, calculate the pixel offsets from the viewport's top-left corner:

offsetX = (viewBounds.left - tileCornerX) / res
offsetY = (tileCornerY - viewBounds.top) / res

The starting tile is placed at coordinates (-offsetX, -offsetY) relative to the viewport origin. Subsequent tile are positioned by adding multiples of tileSize to these offsets.

This algorithm applies to tile-based maps using Web Mercator projection, such as those from Google, Bing, and similar services.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.