Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@

Have a question? Discuss the quantized-mesh specification on the [Cesium community forum](https://community.cesium.com/).

A terrain tileset in quantized-mesh-1.0 format is a simple multi-resolution quadtree pyramid of meshes. All tiles have the extension .terrain. So, if the Tiles URL for a tileset is:
A terrain tileset in quantized-mesh-1.0 format is a simple multi-resolution quadtree pyramid of meshes.

The structure of this pyramid is defined in a `layer.json` file. The format of this file is described in the [`SPECIFICATION.md`](./SPECIFICATION.md]). This file contains information about the URL at which the actual terrain tiles can be requested. For example, when the URL for a tileset is

```
http://example.com/tiles
```

Then the two root files of the pyramid are found at these URLs:
then then the two root files of the pyramid may be found at these URLs:

* (-180 deg, -90 deg) - (0 deg, 90 deg) - http://example.com/tiles/0/0/0.terrain
* (0 deg, -90 deg) - (180 deg, 90 deg) - http://example.com/tiles/0/1/0.terrain
* (-180 deg, -90 deg) - (0 deg, 90 deg) - `http://example.com/tiles/0/0/0.terrain`
* (0 deg, -90 deg) - (180 deg, 90 deg) - `http://example.com/tiles/0/1/0.terrain`

The eight tiles at the next level are found at these URLs:
The eight tiles at the next level are then found at these URLs:

* (-180 deg, -90 deg) - (-90 deg, 0 deg) - http://example.com/tiles/1/0/0.terrain
* (-90 deg, -90 deg) - (0 deg, 0 deg) - http://example.com/tiles/1/1/0.terrain
* (0 deg, -90 deg) - (90 deg, 0 deg) - http://example.com/tiles/1/2/0.terrain
* (90 deg, -90 deg) - (180 deg, 0 deg) - http://example.com/tiles/1/3/0.terrain
* (-180 deg, 0 deg) - (-90 deg, 90 deg) - http://example.com/tiles/1/0/1.terrain
* (-90 deg, 0 deg) - (0 deg, 90 deg) - http://example.com/tiles/1/1/1.terrain
* (0 deg, 0 deg) - (90 deg, 90 deg) - http://example.com/tiles/1/2/1.terrain
* (90 deg, 0 deg) - (180 deg, 90 deg) - http://example.com/tiles/1/3/1.terrain
* (-180 deg, -90 deg) - (-90 deg, 0 deg) - `http://example.com/tiles/1/0/0.terrain`
* (-90 deg, -90 deg) - (0 deg, 0 deg) - `http://example.com/tiles/1/1/0.terrain`
* (0 deg, -90 deg) - (90 deg, 0 deg) - `http://example.com/tiles/1/2/0.terrain`
* (90 deg, -90 deg) - (180 deg, 0 deg) - `http://example.com/tiles/1/3/0.terrain`
* (-180 deg, 0 deg) - (-90 deg, 90 deg) - `http://example.com/tiles/1/0/1.terrain`
* (-90 deg, 0 deg) - (0 deg, 90 deg) - `http://example.com/tiles/1/1/1.terrain`
* (0 deg, 0 deg) - (90 deg, 90 deg) - `http://example.com/tiles/1/2/1.terrain`
* (90 deg, 0 deg) - (180 deg, 90 deg) - `http://example.com/tiles/1/3/1.terrain`

When requesting tiles, be sure to include the following HTTP header in the request:
```
Expand Down
56 changes: 56 additions & 0 deletions SPECIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

# JSON Format Specification

This section describes the format of the `layer.json` manifest file. The format is derived from [tilejson](https://github.com/mapbox/tilejson-spec), but is not a strict subset of this format. The JSON schema for this file can be found in [`layer.schema.json`](./schema/layer.schema.json). The following table summarizes the properties that can be contained in this JSON file, their data types, default values, and interpretation:


| *Property* | *Type* | *Description* | *Required* |
|---|---|---|---|
| name | `string` | The name of this terrain tileset. | No. Default: `"Terrain"` |
| description | `string` | The description of this terrain tileset. | No. Default: `""` |
| attribution | `string` | The attribution (credit) string for the terrain. | No. Default: `""` |
| version | `string` | The version of this tileset. | No. Default: `"1.0.0"` |
| format | `string` | The format of the terrain tiles. Should be `"quantized-mesh-1.0"`. | No. Default: `"quantized-mesh-1.0"` |
| scheme | `string` | The tiling scheme. The only valid value is `"tms"`. | No. Default: `"tms"` |
| extensions | `string[]` | The extensions available for this tileset. | No. Default: `undefined` |
| projection | `string` | The map projection of this tileset. Valid values are `"EPSG:4326"` and `"EPSG:3857"`. | No. Default: `"EPSG:4326"` |
| parentUrl | `string` | The URL of the parent layer.json that this one is layered on top of. | No. Default: `undefined` |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expand on what "parentUrl" means here. I assume this may just be being used to fill out tile gaps in the current layer.json?

Also is this used frequently? It's not supported in 3d tiles renderer at the moment.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parentUrl description was taken from the schema. You asked about that in an issue comment as well, but no response so far. I had a look at the layer.json from Cesium World Terrain. It wasn't used there. I'll try to reverse engineer where and how this is used in CesiumJS/native. Sure, that's not ideal and time-consuming, but ... it's better when one person is doing it once and writing it up in an "agreed upon" form, than dozens of people spending time with that (and in the worst case, coming to different conclusions...)

| minzoom | `integer` | The minimum level for which there are any available tiles. | No. Default: `0` |
| maxzoom | `integer` | The maximum level for which there are any available tiles. | Yes |
| bounds | `number[4]` | The bounding box of the terrain, expressed as `[west, south, east, north]`, in degrees. This is not required for calculating tile positions or downloads. Implementations may choose to ignore this property. | No. Default: `[-180,-90,180,90]` |
| tiles | `string[]` | The URL templates from which to obtain tiles. | Yes |
| available | `availabilityRectangle[][]` | The tile availability information. The outer array is indexed by tile level. The inner array is a list of rectangles of availability at that level. Tiles themselves may also contain further availability information for their subtree. If `metadataAvailability` is present, then this property should be ignored. | No. Default: `undefined` |
| metadataAvailability | `integer` | The levels at which metadata is found in tiles. A value of `n` indicates that metadata can be found at every `n`th level, starting at 0. For example, if this value is 10, then metadata is found at levels 0, 10, 20, etc. If this property is present, then the `available` property should be ignored.| No. Default: `undefined` |

## About `available` and `metadataAvailability`

The `available` property is a predecessor of what is now stored in the `metadataAvailability`. When the `metadataAvailability` is present, then the `available` property should be ignored. Specifically: When the `metadataAvailability` is present, then the structure of the `available` property may not properly reflect the actual availability.

## About `tiles`

The `tiles` property is an array of template URLs. This array should have a length of exactly 1. Clients may choose to ignore all but the first array element. The template URLs can contain variables `{x}`, `{y}`, `{z}`, and `{version}`. The `{z}` variable indicates the level of the tile. The `{x}` and `{y}` variables indicate the x- and y coordinate of the tile. The `version` indicator is a hint for clients or users to indicate whether the underlying data changed over time. When clients or users are caching the data in any form, then a change in the version number should cause that cache to be invalidated.

An example of the entry of the `tiles` array is
`"{z}/{x}/{y}.terrain?v={version}"`
At runtime, this will be converted into an actual URL by substituting the template variables accordingly - for example:
`5/46/21.terrain?v=1.2.0`

## About `extensions`

The `extensions` is an array of strings that indicate different flavors of the data that may be requested. The elements of this array can be added as query parameters in the request, with the key being `extensions`, and the value being the names of the desired extensions, separated by a `-` dash. For example, when the layer JSON indicates extensions
```json
"extensions": [
"watermask",
"metadata",
"octvertexnormals"
]
```
then the query parameter can be
`extensions=octvertexnormals-watermask-metadata`
The request URL (including the substituted template variables) and these parameters would therefore be
`12/6074/2684.terrain?extensions=octvertexnormals-watermask-metadata&v=1.2.0`

## About `minzoom`

While the value of `minzoom` can technically be greater than 0, some details of the behavior are not clearly specified for this case. Many clients will ignore the `minzoom` value, and assume the availability information to be present for layer 0.

25 changes: 25 additions & 0 deletions schema/availabilityRectangle.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "availabilityRectangle.schema.json",
"title": "AvailabilityRectangle",
"description": "A rectangle of tile availability.",
"properties": {
"startX": {
"description": "The index of the start tile in the X direction.",
"type": "integer"
},
"startY": {
"description": "The index of the start tile in the Y direction.",
"type": "integer"
},
"endX": {
"description": "The index of the end tile in the X direction.",
"type": "integer"
},
"endY": {
"description": "The index of the end tile in the Y direction.",
"type": "integer"
}
},
"required": ["startX", "startY", "endX", "endY"]
}
95 changes: 95 additions & 0 deletions schema/layer.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "layer.schema.json",
"title": "Layer",
"description": "A quantized-mesh terrain layer.json.",
"properties": {
"attribution": {
"description": "The attribution (credit) string for the terrain.",
"type": "string",
"default": ""
},
"available": {
"description": "The tile availability information. The outer array is indexed by tile level. The inner array is a list of rectangles of availability at that level. Tiles themselves may also contain further availability information for their subtree.",
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "availabilityRectangle.schema.json"
}
}
},
"bounds": {
"description": "The bounding box of the terrain, expressed as west, south, east, north in degrees.",
"type": "array",
"default": [-180,-90,180,90],
"minItems": 4,
"maxItems": 4,
"items": {
"type": "number"
}
},
"description": {
"description": "The description of this terrain tileset.",
"type": "string",
"default": ""
},
"extensions": {
"description": "The extensions available for this tileset.",
"type": "array",
"items": {
"type": "string"
}
},
"format": {
"description": "The format of the terrain tiles. Should be `\"quantized-mesh-1.0\"`.",
"type": "string",
"default": "quantized-mesh-1.0"
},
"maxzoom": {
"description": "The maximum level for which there are any available tiles.",
"type": "integer"
},
"minzoom": {
"description": "The minimum level for which there are any available tiles.",
"type": "integer",
"default": 0
},
"metadataAvailability": {
"description": "The levels at which metadata is found in tiles. For example, if this value is 10, then metadata is found at levels 0, 10, 20, etc.",
"type": "integer"
},
"name": {
"description": "The name of this terrain tileset.",
"type": "string",
"default": "Terrain"
},
"parentUrl": {
"description": "The URL of the parent layer.json that this one is layered on top of.",
"type": "string"
},
"projection": {
"description": "The map projection of this tileset. Valid values are `\"EPSG:4326\"` and `\"EPSG:3857\"`.",
"type": "string",
"default": "EPSG:4326"
},
"scheme": {
"description": "The tiling scheme. The only valid value is `\"tms\"`.",
"type": "string",
"default": "tms"
},
"tiles": {
"description": "The URL templates from which to obtain tiles.",
"type": "array",
"items": {
"type": "string"
}
},
"version": {
"description": "The version of this tileset.",
"type": "string",
"default": "1.0.0"
}
},
"required": ["tiles", "maxzoom"]
}