Skip to content

OGC API - Tiles

Martin also serves your tiles through the OGC API - Tiles standard, under /ogc. You get exactly the same tiles as from the regular Martin endpoints, just at different URLs and with OGC metadata instead of TileJSON.

Do you need this?

Probably not. Map libraries like MapLibre work best with the regular endpoints. Use /ogc when a tool only speaks OGC API - Tiles, like GDAL's OGC API driver.

The OGC API is included in the default build, as the ogcapi feature.

How a client finds a tile

An OGC client doesn't need to know how Martin's URLs look. You give it the landing page, /ogc, and it follows links from there, picking each one by its rel, until it has a URL template for the tiles.

A client starts at /ogc and follows links: data to /ogc/collections, tilesets-vector to the tilesets of world_cities, self to the WebMercatorQuad tileset, and item to the tile URL templateGET /ogclanding pagerel: dataGET /ogc/collectionsone collection per sourcerel: ...tilesets-vectorGET /ogc/collections/world_cities/tilesworld_cities has one tileset, on its own gridrel: selfGET /ogc/collections/world_cities/tiles/WebMercatorQuadzoom range, layers and the tile URL templaterel: item, fill in {tileMatrix}/{tileRow}/{tileCol}GET /ogc/collections/world_cities/tiles/WebMercatorQuad/2/1/3a tile/ogc/conformance/ogc/tileMatrixSetsalso linked from the landing page/ogc/tileMatrixSets/WebMercatorQuadthe grid definition

That's four requests before the first tile, where a MapLibre map with TileJSON needs one.

The landing page also links /ogc/api, the OGC API part of Martin's OpenAPI 3.1 definition, for clients that generate requests from it. Clients that weigh HTML above JSON in Accept, as browsers do, get it as a Swagger UI page instead, which loads Swagger UI from the jsDelivr CDN. OGC API's OpenAPI conformance classes ask for OpenAPI 3.0, so Martin does not declare them.

Tile URLs

The thing that trips people up: OGC puts the row before the column. An OGC tile URL ends in {z}/{y}/{x}, not {z}/{x}/{y}.

The Martin tile /world_cities/2/3/1 is the OGC tile /ogc/collections/world_cities/tiles/WebMercatorQuad/2/1/3: tileMatrix is z, tileRow is y and tileCol is x, so x and y swap placesMartin endpointOGC API/sourceIDworld_cities/z2/x3/y1/ogc/collections/collectionIdworld_cities/tiles/WebMercatorQuad/tileMatrix2/tileRow1/tileCol3x and y swap placeszoom 2x = tileColy = tileRow

The tile matrix set in the URL has to be the source's tile grid. For most sources that's WebMercatorQuad, and anything else gets a 404.

Compression, caching and empty tiles behave just like on the regular tile endpoint.

Compared to the Martin endpoints

Martin endpoints OGC API
list of sources /catalog /ogc/collections
source metadata TileJSON tileset, at /ogc/collections/{sourceID}/tiles/{tileMatrixSetId}
tile /{sourceID}/{z}/{x}/{y} /ogc/collections/{sourceID}/tiles/{tileMatrixSetId}/{z}/{y}/{x}
MVT content type application/x-protobuf application/vnd.mapbox-vector-tile, as the standard requires
composite sources /{source1},…,{sourceN} not available
grids in other CRSs served not listed, see below
style /style/{styleID} /ogc/styles/{styleID}, see Styles

Which sources show up

Every tile source shows up as a collection, with its source ID as the collection ID. Vector sources get a vector tileset, raster sources a map tileset.

There are two exceptions:

  • Sources on an unusual grid. The standard needs the units and axis order of each grid's CRS, and Martin only knows those for the CRSs of the built-in grids: EPSG 3857, 4326, 3395, 3035, 2193, 5041 and 5042. A source on a simple grid, or on a custom grid in another CRS, won't be listed.
  • Composite sources and aliases. A collection is always a single source, so /a,b has no OGC counterpart and aliases aren't listed under their own name. If an alias has the same name as a source, the collection serves the alias, just like the tile endpoint does. If that alias combines several sources, the source drops out of the list.

Tile matrix sets

"Tile matrix set" is OGC's name for a tile grid. /ogc/tileMatrixSets lists the grids your sources use, plus WebMercatorQuad, which is always there. Each one links to its full definition in the Two Dimensional Tile Matrix Set 2.0 JSON format: the origin, cell size and number of rows and columns at every zoom.

Grids from the OGC registry also carry their official registry uri. Origins are written in the CRS's own axis order, which for EPSG 3035 and 2193 means northing first.

Styles

/ogc/styles lists your styles through OGC API - Styles, each titled after its name. /ogc/styles/{styleID} is an alias of /style/{styleID}. Martin does not declare the draft's mapbox-style class, which names the Mapbox media type.

OGC API - Styles is still a draft, so this part may change with it.

Maps

With rendering enabled, Martin also renders maps through OGC API - Maps. /ogc/styles/{styleID}/map is a style rendered as one image. /ogc/collections/{sourceID}/map is a raster source as one image. Only raster sources on WebMercatorQuad have such a map, and their collections link it; vector data is drawn through a style. Each collection also gives its storageCrs, the CRS of its grid, with its bounds in that CRS when Martin can convert them. /ogc/map, linked from the landing page, draws all those collections in one image, ordered by ID, or only the ones collections names in that order. A map is in the format the Accept header weighs highest, ignoring q=0: PNG (also for */* or no header), JPEG or TIFF.

Parameter Meaning
width, height size in pixels, up to 2048; with one, the other follows the area; with neither, the longer side is 1024
bbox area as corners in bbox-crs axis order; defaults to a collection's bounds, or the world for a style
bbox-crs CRS of bbox: CRS84 (default), EPSG:4326 or EPSG:3857
center point as x,y to center the map on, instead of bbox
center-crs CRS of center, as for bbox-crs
scale-denominator scale of the map, instead of width and height with bbox
collections for /ogc/map only: comma-separated source IDs, or their /ogc/collections/{sourceID} URLs

Maps are always in web mercator, which the Content-Crs header states. The Content-Bbox header gives the area shown, in metres: when its shape differs from the image's, the map shows more than was asked for. PNGs always have an alpha channel, and TIFFs are GeoTIFFs placed at that area.

The map of all collections and the map of each style also come as map tiles on WebMercatorQuad, 256 pixels square, under /ogc/map/tiles and /ogc/styles/{styleID}/map/tiles. Their tilesets link the tile URL template, and Accept picks the format as for maps. Raster collections need no map tiles of their own: their tilesets under /ogc/collections/{sourceID}/tiles already are map tiles.

Conformance

/ogc/conformance lists which parts of the standards Martin implements:

  • OGC API - Tiles core, tileset, tilesets list, geodata tilesets and Mapbox Vector Tiles
  • OGC API - Common core, landing page and JSON
  • Two Dimensional Tile Matrix Set 2.0 and its JSON encoding
  • OGC API - Styles core and global styles, when Martin is built with styles
  • OGC API - Maps core, dataset map, collection map, collections selection, styled map, map tilesets, PNG, JPEG and TIFF, when rendering is enabled

We run the official OGC test suite against Martin in CI.

Reading Martin with GDAL

GDAL's OGC API driver can read Martin's vector tiles. It shows each zoom level as a separate layer:

ogrinfo OGCAPI:http://localhost:3000/ogc/collections/world_cities -oo API=TILES