PMTiles
Note
You can find the full source code of this example in PMTilesActivity.kt of the MapLibreAndroidTestApp.
Starting MapLibre Android 11.7.0, PMTiles archives are supported as tile sources. Prefix any tile source URL with pmtiles:// to read from a PMTiles archive:
pmtiles://https://— stream tiles from a remote filepmtiles://file://— read a file from device storage (usegetExternalFilesDirorfilesDirfor the path)
The pmtiles:// prefix works with any tile source type (e.g. vector, raster, raster-dem, etc.), from a style JSON or dynamically.
Unlike MapLibre GL JS, which resolves relative URLs against the style's base URL, MapLibre Native requires the URL inside pmtiles:// to be fully specified (e.g. pmtiles://https://example.com/tiles.pmtiles, not pmtiles://tiles.pmtiles).
Note: PMTiles sources do not support offline pack downloads or caching.
Loading a style that uses PMTiles sources
Load a style JSON that references pmtiles:// sources. The example below loads a satellite imagery basemap of the Central Alps and sets the initial camera position:
map.setStyle("https://demotiles.maplibre.org/pmtiles/raster/style-imagery.json") { style ->
map.cameraPosition = CameraPosition.Builder()
.target(LatLng(47.5, 12.0))
.zoom(9.0)
.build()
Adding a PMTiles source directly
Add vector sources from PMTiles archives to an already-loaded style. The example overlays two places datasets — Overture Maps (yellow) and Foursquare OS Places (blue) — both using CircleLayer. The setSourceLayer call names the layer within the archive to render:
val overtureSource = VectorSource(
"overture-places",
"pmtiles://https://overturemaps-tiles-us-west-2-beta.s3.amazonaws.com/2026-01-21/places.pmtiles"
)
style.addSource(overtureSource)
val overtureLayer = CircleLayer("overture-layer", "overture-places")
overtureLayer.setSourceLayer("place")
overtureLayer.setProperties(
PropertyFactory.circleColor(Color.parseColor("#f5c800")),
PropertyFactory.circleRadius(4f),
PropertyFactory.circleOpacity(0.6f)
)
style.addLayer(overtureLayer)
The same pattern works for raster archives using RasterSource and RasterLayer.
Note:
raster-demsources added programmatically cannot specifyencodingvia the current Android API. Defineraster-demsources with terrarium encoding in the style JSON instead, where theencodingfield is fully supported.
Loading a local PMTiles file
For files on device storage, use file:// with an absolute path. The example below uses getExternalFilesDir(null) to locate a file downloaded to the app's external files directory:
val path = getExternalFilesDir(null)?.absolutePath + "/watercolor.pmtiles"
val source = RasterSource(
"watercolor",
"pmtiles://file://$path",
256
)
style.addSource(source)
style.addLayer(RasterLayer("watercolor", "watercolor"))
Note:
pmtiles://asset://(files insrc/main/assets/) is not currently supported.AssetManagerFileSourcedoes not implement byte-range reads, which PMTiles requires to read its header and metadata. Usefile://from device storage instead. See the open issue for status.