Skip to main content
A tile table stores a pyramid of raster images. Each image covers a rectangular geographic area and is identified by three integers: column (x), row (y), and zoom level (z). As the zoom level increases, more tiles cover the same area at higher resolution — following the same scheme used by web map services such as XYZ/TMS.

Key classes

TileDao

The primary access object for a tile table. Obtained from geoPackage.getTileDao(tableName). Provides query methods by coordinate, zoom level, and bounding box.

TileRow

A single tile returned by a query. The image bytes are stored as a Uint8Array (typically PNG or JPEG).

TileMatrixSet

Defines the overall spatial extent and SRS of the tile table. One per tile table.

TileMatrix

Defines the grid dimensions and pixel sizes at a specific zoom level. One row per supported zoom level.

TileMatrix and TileMatrixSet

TileMatrixSet is registered in gpkg_tile_matrix_set and stores the bounding box and SRS id that apply to the whole tile table. TileMatrix rows (in gpkg_tile_matrix) define — for each zoom level — how many columns and rows of tiles exist and the pixel dimensions of each tile. Together they let the library convert between geographic coordinates and tile grid positions. TileDao reads both tables on construction and exposes convenience methods:
MethodDescription
getMinZoom() / getMaxZoom()Zoom level range stored in the file
getZoomLevels()Array of all available zoom levels
getTileMatrix(zoom)TileMatrix for a specific zoom level
getTileMatrixSet()The TileMatrixSet for this table
isXYZTiles()Whether the tile grid matches the standard XYZ scheme

Getting a TileDao

import { GeoPackageAPI } from '@ngageoint/geopackage';

const geoPackage = await GeoPackageAPI.open('/path/to/file.gpkg');

const tileDao = geoPackage.getTileDao('my_tiles');
console.log('Zoom range:', tileDao.getMinZoom(), '–', tileDao.getMaxZoom());
console.log('Total tiles:', tileDao.count());

Querying tiles by coordinate

Use queryForTile(column, row, zoomLevel) to retrieve a specific tile:
// Retrieve tile at column 2, row 3, zoom level 5
const tileRow = tileDao.queryForTile(2, 3, 5);

if (tileRow != null) {
  // Raw image bytes — typically PNG or JPEG
  const imageBytes: Uint8Array = tileRow.getTileData();
  console.log('Tile data length:', imageBytes.length);
}

Iterating tiles at a zoom level

const resultSet = tileDao.queryForTiles(10); // zoom level 10
try {
  while (resultSet.moveToNext()) {
    const row = resultSet.getRow();
    console.log(
      `Tile [${row.getTileColumn()}, ${row.getTileRow()}] at z${row.getZoomLevel()}`,
    );
  }
} finally {
  resultSet.close();
}

Higher-level access with GeoPackageTileRetriever

GeoPackageTileRetriever wraps TileDao and handles coordinate conversion, reprojection, and tile scaling automatically. It is the recommended entry point for rendering tiles in a map view.
import {
  GeoPackageAPI,
  GeoPackageTileRetriever,
} from '@ngageoint/geopackage';

const geoPackage = await GeoPackageAPI.open('/path/to/file.gpkg');
const tileDao = geoPackage.getTileDao('my_tiles');

const retriever = new GeoPackageTileRetriever(tileDao, 256, 256);

// Retrieve tile at web map coordinates (x, y, z)
const tile = await retriever.getTile(x, y, z);
if (tile != null) {
  const imageData = tile.getData(); // Uint8Array
}
GeoPackageTileRetriever uses the Tile Scaling NGA Extension when present to fill gaps at zoom levels where no tiles exist by up- or down-scaling tiles from adjacent zoom levels.

Tile coordinates

GeoPackage stores tiles using a TMS-style coordinate system where row 0 is at the top of the bounding box (the same as XYZ/Google Maps conventions). The TileDao.isXYZTiles() method checks whether the stored tile grid matches the standard web map XYZ grid.
Use tileDao.webZoomToGeoPackageZoom(webZoom) to map a web map zoom level to the corresponding GeoPackage zoom level when the two scales differ.

Build docs developers (and LLMs) love