diff --git a/README.md b/README.md index 74c8b54bc..85b3e2d09 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,8 @@ Topic | Status [Batched 3D Model](TileFormats/Batched3DModel/README.md) (*.b3dm)

Textured terrain and surfaces, 3D building exteriors and interiors, massive models, ... | :white_check_mark: **Solid base**, only minor, if any, changes expected [Instanced 3D Model](TileFormats/Instanced3DModel/README.md) (*.i3dm)

Trees, windmills, bolts, ... | :white_check_mark: **Solid base**, only minor, if any, changes expected [Point Cloud](TileFormats/PointCloud/README.md) (*.pnts)

Massive amount of points | :white_check_mark: **Solid base**, only minor, if any, changes expected -[Vector Data](TileFormats/VectorData/README.md) (*.vctr)

Polygons, polylines, and placemarks | :white_circle: **In progress**, [#124](https://github.com/AnalyticalGraphicsInc/3d-tiles/pull/124/files) +[Geometry](TileFormats/Geometry/README.md) (*.geom)

Boxes, cylinders, ellipsoids, and spheres. | :white_circle: **In progress**, [#228](https://github.com/AnalyticalGraphicsInc/3d-tiles/pull/) +[Vector Data](TileFormats/VectorData/README.md) (*.vctr)

Polygons, polylines, and placemarks | :white_circle: **In progress**, [#228](https://github.com/AnalyticalGraphicsInc/3d-tiles/pull/) [Composite](TileFormats/Composite/README.md) (*.cmpt)

Combine heterogeneous tile formats | :white_check_mark: **Solid base**, only minor, if any, changes expected [Declarative Styling](Styling/README.md)

Style features using per-feature metadata | :white_check_mark: **Solid base**, will add features/functions as needed, [#2](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/2) diff --git a/Styling/README.md b/Styling/README.md index a3a9941aa..45e90af85 100644 --- a/Styling/README.md +++ b/Styling/README.md @@ -25,6 +25,7 @@ Example: Creating a color ramp based on building height. * Tom Fili, [@CesiumFili](https://twitter.com/CesiumFili) * Sean Lilley, [@lilleyse](https://github.com/lilleyse) * Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi) +* Dan Bagnell, [@bagnell](https://github.com/bagnell) Contents: @@ -51,6 +52,7 @@ Contents: * [Notes](#notes) * [Batch Table Hierarchy](#batch-table-hierarchy) * [Point Cloud](#point-cloud) +* [Vector Data](#vector-data) * [File Extension](#file-extension) * [MIME Type](#mime-type) * [Acknowledgments](#acknowledgments) @@ -254,7 +256,7 @@ The following types are supported: * `vec4` * `RegExp` -All of the types except `vec2`, `vec3`, `vec4`, and `RegExp` have the same syntax and runtime behavior as JavaScript. `vec2`, `vec3`, and `vec4` are derived from GLSL vectors and behave similarly to JavaScript `Object` (see the [Vector section](#vector)). Colors derive from [CSS3 Colors](https://www.w3.org/TR/css3-color/) and are implemented as `vec4`. `RegExp` is derived from JavaScript and described in the [RegExp section](#regexp). +All of the types except `vec2`, `vec3`, `vec4`, and `RegExp` have the same syntax and runtime behavior as JavaScript. `vec2`, `vec3`, and `vec4` are derived from GLSL vectors and behave similarly to JavaScript `Object` (see the [Vector section](#vector)). Colors derive from [CSS3 Colors](https://www.w3.org/TR/css3-color/) and are implemented as `vec4`. Fonts derive from [CSS3 Fonts](https://www.w3.org/TR/css-fonts-3/) and are implemented as `String`. RegExp` is derived from JavaScript and described in the [RegExp section](#regexp). Example expressions for different types include the following: * `true`, `false` @@ -268,6 +270,7 @@ Example expressions for different types include the following: * `vec4(1.0, 2.0, 3.0, 4.0)` * `color('#00FFFF')` * `regExp('^Chest'))` +* `"30px sans-serif"` #### Number @@ -496,6 +499,7 @@ The following constants are supported by the styling language: * [`Math.PI`](#pi) * [`Math.E`](#e) +* [`Number.POSITIVE_INFINITY`](#positive-infinity) #### PI @@ -517,6 +521,16 @@ Euler's constant and the base of the natural logarithm, approximately `2.71828`. } ``` +#### Positive Infinity + +A constant that represents positive infinity. + +```json +{ + "disableDepthTestDistance" : "Number.POSITIVE_INFINITY" +} +``` + ### Variables Variables are used to retrieve the property values of individual features in a tileset. Variables are identified using the ES 6 ([ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)) Template Literal syntax, i.e., `${feature.identifier}` or `${feature['identifier']}`, where the identifier is the case-sensitive property name. `feature` is implicit and can be omitted in most cases. @@ -1344,6 +1358,66 @@ For example: **TODO : add note about GLSL implementations requires strict type comparisons among other things: https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/140** +## Vector Data + +A [Vector Tile](../TileFormats/VectorData/README.md) is a collection of vector features such as points, polygons, and polylines. Vector features can be styled similar to other features with `color` and `show`. Points have several other styling options: + +The following style properties apply to polygon and polyline features in vector tiles: + +| Style | Type | Description | Default | +| --- | --- | --- | --- | +| `show` | `Boolean` | Whether or not to show the feature. | `true` | +| `color` | `vec4` | The color of the feature. | `color('#FFFFFF')` | + +The following style properties apply to point features in vector tiles: + +| Style | Type | Description | Default | +| --- | --- | --- | --- | +| `show` | `Boolean` | Whether or not to show the feature. | `true` | +| `color` | `vec4` | The color of the point. `color` is ignored when `image` is defined. | `color('#FFFFFF')` | +| `pointSize` | `Number` | The size of the point in pixels. `pointSize` is ignored when `image` is defined. | `8.0` | +| `pointOutlineColor` | `vec4` | The color of the point outline. `pointOutlineColor` is ignored when `image` is defined. | `color('#000000')` | +| `pointOutlineWidth` | `Number` | The width of the point outline in pixels. `pointOutlineWidth` is ignored when `image` is defined. | `0.0` | +| `labelText` | `String` | The text to display for the point. `'\n'` can be added to separate lines of text. | `undefined` | +| `labelColor` | `vec4` | The color of the label's text. | `color('#FFFFFF')` | +| `labelStyle` | `Number` | The label style: **fill** (`0`), **outline** (`1`), or **both** (`2`). See **Table1**.| `0` | +| `labelOutlineColor` | `vec4` | The color of the text outline. | `color('#FFFFFF')` | +| `labelOutlineWidth` | `Number` | The width of the text outline in pixels. | `1.0` | +| `font` | `String` | The font of the displayed text. | `"30px sans-serif"` | +| `backgroundColor` | `vec4` | The label background color. | `rgba(#FFFF00)` | +| `backgroundPadding` | `vec2` | The background padding, in pixels, of this label. The `x` value controls horizontal padding, and the `y` value controls vertical padding. The number of `x` pixels is added to both sides. The number of `y` pixels is added to the top and bottom. | `vec2(7, 5)` | +| `backgroundEnabled` | `Boolean` | Whether or not to display the label background. | `false` | +| `scaleByDistance` | `vec4` | Sets near and far scaling properties of a feature based on the features's distance from the camera in meters. A feature's scale will interpolate between the `y` and `w` values while the camera distance falls within the lower, `x`, and upper, `z`, bounds. Outside of these ranges, the features's scale remains clamped to the nearest bound. If undefined, `scaleByDistance` will be disabled. | `undefined` | +| `translucencyByDistance` | `vec4` | Sets near and far translucency properties of a feature based on the feature's distance from the camera in meters. Translucency describes how transparent the point will be, where `0.0` means the point is completely transparant and `1.0` means the point is completely opaque. A feature's translucency will interpolate between the `y` and `w` while the camera distance falls within the upper and lower bounds of the specified `x` and `z`. Outside of these ranges the feature's translucency remains clamped to the nearest bound. If undefined, `translucencyByDistance` will be disabled. | `undefined` | +| `distanceDisplayCondition` | `vec2` | Sets the condition specifying at what distance from the camera in meters that this feature will be displayed. The `x` value is the smallest distance in the interval where the feature is visible. The `y` value is the largest distance in the interval where the object is visible. If undefined, `distanceDisplayCondition` will be disabled. | `undefined` | +| `heightOffset` | `Number` | The distance, in meters, to offset the height from the original height of the point. This is ignored if the value is less than or equal to zero. | `0.0` | +| `anchorLineEnabled` | `Boolean` | Whether or not to display a line from the feature to the point's original position. This is ignored unless `heightOffset` is greater than zero. | `false` | +| `anchorLineColor` | `vec4` | The color of the line from the feature to the point's original position. This is ignored unless `heightOffset` is greater than 0.0. | `color('#FFFFFF')` | +| `image` | `String` | A URL to an image or a data URI to be displayed instead of a point. | `undefined` | +| `disableDepthTestDistance` | `Number` | The distance from the camera in meters at which to disable the depth test to, for example, prevent clipping against terrain. When set to zero or `undefined`, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. | `undefined` | +| `horizontalOrigin` | `Number` | The horizontal origin of the point: **center** (`0`), **left** (`1`), or **right** (`-1`). | `0` | +| `verticalOrigin` | `Number` | The vertical origin of the point: **center** (`0`), **Bottom** (`1`), or **top** (`-1`). | `0` | +| `labelHorizontalOrigin` | `Number` | The horizontal origin of the label: **center** (`0`), **left** (`1`), or **right** (`-1`). | `0` | +| `labelVerticalOrigin` | `Number` | The vertical origin of the label: **center** (`0`), **bottom** (`1`), **top** (`-1`), or **baseline** (`2`). | `0` | + +For example: + +```json +{ + "labelText" : "${DISPLAY_TEXT}", + "labelColor" : "color('#FFFF00')", + "labelStyle" : "2", + "image" : "'http://example.com/url/to/image.jpg'", + "origin" : "1", + "labelOrigin" : "-1" +} +``` + +| Fill | Outline | Fill and Outline | +| --- | --- | --- | +| ![](figures/label_fill.jpg) | ![](figures/label_outline.jpg) | ![](figures/label_fill_outline.jpg) | +**Table1**: Label text style options. + ## File Extension TBA diff --git a/Styling/figures/label_fill.jpg b/Styling/figures/label_fill.jpg new file mode 100644 index 000000000..9b7d23a6c Binary files /dev/null and b/Styling/figures/label_fill.jpg differ diff --git a/Styling/figures/label_fill_outline.jpg b/Styling/figures/label_fill_outline.jpg new file mode 100644 index 000000000..2267f15ce Binary files /dev/null and b/Styling/figures/label_fill_outline.jpg differ diff --git a/Styling/figures/label_outline.jpg b/Styling/figures/label_outline.jpg new file mode 100644 index 000000000..6402baddb Binary files /dev/null and b/Styling/figures/label_outline.jpg differ diff --git a/Styling/schema/style.vec2Expression.schema.json b/Styling/schema/style.vec2Expression.schema.json new file mode 100644 index 000000000..c054d1236 --- /dev/null +++ b/Styling/schema/style.vec2Expression.schema.json @@ -0,0 +1,7 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema", + "id" : "style.vec2Expression.schema.json", + "title" : "vec2 expression", + "type" : "string", + "description" : "3D Tiles style expression that evaluates to a vec2." +} diff --git a/Styling/schema/style.vec4Expression.schema.json b/Styling/schema/style.vec4Expression.schema.json new file mode 100644 index 000000000..5ffb74cef --- /dev/null +++ b/Styling/schema/style.vec4Expression.schema.json @@ -0,0 +1,7 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema", + "id" : "style.vec4Expression.schema.json", + "title" : "vec4 expression", + "type" : "string", + "description" : "3D Tiles style expression that evaluates to a vec4." +} diff --git a/Styling/schema/vctr.style.schema.json b/Styling/schema/vctr.style.schema.json new file mode 100644 index 000000000..3cffc61a0 --- /dev/null +++ b/Styling/schema/vctr.style.schema.json @@ -0,0 +1,262 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema", + "id" : "vctr.style.schema.json", + "title" : "Vector Style", + "type" : "object", + "description" : "A 3D Tiles style with additional properties for vector data.", + "allOf" : [{ + "$ref" : "style.schema.json" + }, { + "properties" : { + "show" : { + "oneOf" : [{ + "$ref" : "style.booleanExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Whether or not to show the feature.", + "default" : "true" + }, + "color" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The color of the point. `color` is ignored when `image` is defined.", + "default" : "color('#FFFFFF')" + }, + "pointSize" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The size of the point in pixels. `pointSize` is ignored when `image` is defined.", + "default" : 8.0 + }, + "pointOutlineColor" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The color of the point outline. `pointOutlineColor` is ignored when `image` is defined.", + "default" : "color('#000000')" + }, + "pointOutlineWidth" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The width of the point outline in pixels. `pointOutlineWidth` is ignored when `image` is defined.", + "default" : 0.0 + }, + "labelText" : { + "oneOf" : [{ + "type" : "string" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The text to display for the point. `'\n'` can be added to separate lines of text.", + "default" : "undefined" + }, + "labelColor" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The color of the label's text.", + "default" : "color('#FFFFFF')" + }, + "labelStyle" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The label style: **fill** (`0`), **outline** (`1`), or **both** (`2`).", + "default" : 0 + }, + "labelOutlineColor" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The color of the text outline.", + "default" : "color('#FFFFFF')" + }, + "labelOutlineWidth" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The width of the text outline in pixels.", + "default" : 1.0 + }, + "font" : { + "oneOf" : [{ + "type" : "string" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The font of the displayed text.", + "default" : "'30px sans-serif'" + }, + "backgroundColor" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The label background color.", + "default" : "rgba(42, 42, 42, 0.8)" + }, + "backgroundPadding" : { + "oneOf" : [{ + "$ref" : "style.vec2Expression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The background padding, in pixels, of this label. The `x` value controls horizontal padding, and the `y` value controls vertical padding. The number of `x` pixels is added to both sides. The number of `y` pixels is added to the top and bottom.", + "default" : "vec2(7, 5)" + }, + "backgroundEnabled" : { + "oneOf" : [{ + "$ref" : "style.booleanExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Whether or not to display the label background.", + "default" : "false" + }, + "scaleByDistance" : { + "oneOf" : [{ + "$ref" : "style.vec4Expression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Sets near and far scaling properties of a feature based on the features's distance from the camera in meters. A feature's scale will interpolate between the `y` and `w` values while the camera distance falls within the lower, `x`, and upper, `z`, bounds. Outside of these ranges, the features's scale remains clamped to the nearest bound. If undefined, `scaleByDistance` will be disabled.", + "default" : "undefined" + }, + "translucencyByDistance" : { + "oneOf" : [{ + "$ref" : "style.vec4Expression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Sets near and far translucency properties of a feature based on the feature's distance from the camera in meters. Translucency describes how transparent the point will be, where `0.0` means the point is completely transparant and `1.0` means the point is completely opaque. A feature's translucency will interpolate between the `y` and `w` while the camera distance falls within the upper and lower bounds of the specified `x` and `z`. Outside of these ranges the feature's translucency remains clamped to the nearest bound. If undefined, `translucencyByDistance` will be disabled.", + "default" : "undefined" + }, + "distanceDisplayCondition" : { + "oneOf" : [{ + "$ref" : "style.vec2Expression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Sets the condition specifying at what distance from the camera in meters that this feature will be displayed. The `x` value is the smallest distance in the interval where the feature is visible. The `y` value is the largest distance in the interval where the object is visible. If undefined, `distanceDisplayCondition` will be disabled.", + "default" : "undefined" + }, + "heightOffset" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The distance, in meters, to offset the height from the original height of the point. This is ignored if the value is less than or equal to zero.", + "default" : 0.0 + }, + "anchorLineEnabled" : { + "oneOf" : [{ + "$ref" : "style.booleanExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "Whether or not to display a line from the feature to the point's original position. This is ignored unless `heightOffset` is greater than zero.", + "default" : "false" + }, + "anchorLineColor" : { + "oneOf" : [{ + "$ref" : "style.colorExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The color of the line from the feature to the point's original position. This is ignored unless `heightOffset` is greater than 0.0.", + "default" : "color('#FFFFFF)" + }, + "image" : { + "oneOf" : [{ + "type" : "string" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "A URL to an image or a data URI to be displayed instead of a point.", + "default" : "undefined" + }, + "disableDepthTestDistance" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The distance from the camera in meters at which to disable the depth test to, for example, prevent clipping against terrain. When set to zero or `undefined`, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied.", + "default" : "undefined" + }, + "horizontalOrigin" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The horizontal origin of the point: **center** (`0`), **left** (`1`), or **right** (`-1`).", + "default" : "0" + }, + "verticalOrigin" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The vertical origin of the point: **center** (`0`), **Bottom** (`1`), or **top** (`-1`).", + "default" : "0" + }, + "labelHorizontalOrigin" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The horizontal origin of the label: **center** (`0`), **left** (`1`), or **right** (`-1`).", + "default" : "0" + }, + "labelVerticalOrigin" : { + "oneOf" : [{ + "$ref" : "style.numberExpression.schema.json" + }, { + "$ref" : "style.condition.schema.json" + }], + "description" : "The vertical origin of the label: **center** (`0`), **bottom** (`1`), **top** (`-1`), or **baseline** (`2`).", + "default" : "0" + }, + }, + "dependencies" : { + "labelText" : [ + "labelStyle", + "labelColor", + "labelOutlineColor", + "labelOutlineWidth", + "labelHorizontalOrigin", + "labelVerticalOrigin", + "font", + "backgroundColor", + "backgroundPadding", + "backgroundEnabled" + ] + } + }], + "additionalProperties" : false +} diff --git a/TileFormats/Batched3DModel/README.md b/TileFormats/Batched3DModel/README.md index 237fc1d56..31edc3cc2 100644 --- a/TileFormats/Batched3DModel/README.md +++ b/TileFormats/Batched3DModel/README.md @@ -10,6 +10,8 @@ _Batched 3D Model_ allows offline batching of heterogeneous 3D models, such as different buildings in a city, for efficient streaming to a web client for rendering and interaction. Efficiency comes from transferring multiple models in a single request and rendering them in the least number of WebGL draw calls necessary. Using the core 3D Tiles spec language, each model is a _feature_. +In addition to rendering the batched models, the models can be used as volumes for classifying the geometry of other 3D Tiles tilesets. + Per-model properties, such as IDs, enable individual models to be identified and updated at runtime, e.g., show/hide, highlight color, etc. Properties may be used, for example, to query a web service to access metadata, such as passing a building's ID to get its address. Or a property might be referenced on-the-fly for changing a model's appearance, e.g., changing highlight color based on a property value. Batched 3D Model, or just the _batch_, is a binary blob in little endian accessed in JavaScript as an `ArrayBuffer`. diff --git a/TileFormats/Geometry/README.md b/TileFormats/Geometry/README.md new file mode 100644 index 000000000..76e82e46d --- /dev/null +++ b/TileFormats/Geometry/README.md @@ -0,0 +1,114 @@ +# Geometry + +## Contributors + +* Dan Bagnell, [@bagnell](https://github.com/bagnell) +* Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi) +* Sean Lilley, [@lilleyse](https://github.com/lilleyse) + +## Overview + +The _Geometry_ tile format allows streaming of geometry datasets including boxes, cylinders, ellipsoids, and spheres. + +Each box, cylinder, ellipsoid, and sphere is a _feature_ in the 3D Tiles specification language. + +In addition to rendering the geometry, the geometry can be used for classifying geometry of other 3D Tiles tilesets. + +## Layout + +A tile is composed of two sections: a header immediately followed by a body. + +**Figure1**: Vector tile layout. +![](figures/layout.jpg) + +## Header + +The 28-byte header contains the following fields: + +| Field name | Data type | Description | +| --- | --- | --- | +| `magic` | 4-byte ANSI string | `"geom"`. This can be used to identify the arraybuffer as a Geometry tile. | +| `version` | `uint32` | The version of the Geometry Data format. It is currently `1`. | +| `byteLength` | `uint32` | The length of the entire tile, including the header, in bytes. | +| `featureTableJSONByteLength` | `uint32` | The length of the feature table JSON section in bytes. | +| `featureTableBinaryByteLength` | `uint32` | The length of the feature table binary section in bytes. If `featureTableJSONByteLength` is zero, this will also be zero. | +| `batchTableJSONByteLength` | `uint32` | The length of the batch table JSON section in bytes. Zero indicates that there is no batch table. | +| `batchTableBinaryByteLength` | `uint32` | The length of the batch table binary section in bytes. If `batchTableJSONByteLength` is zero, this will also be zero. | + +If `featureTableJSONByteLength` equals zero, the tile does not need to be rendered. + +The body section immediately follows the header section, and is composed, in order, of two fields: `Feature Table` and `Batch Table`. + +Code for reading the header can be found in +[Geometry3DTileContent.js](https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/Geometry3DTileContent.js) +in the Cesium implementation of 3D Tiles. + +## Feature Table + +Contains values for `geom` semantics used to render features. The general layout of a Feature Table is described in the [Feature Table specification](../FeatureTable). + +The `geom` Feature Table JSON schema is defined in [geom.featureTable.schema.json](../../schema/geom.featureTable.schema.json). + +### Semantics + +Per-feature semantics specific to a feature type are prefixed with the name of the feature type. e.g. `BOXES` for boxes, `CYLINDERS` for cylinders, `ELLIPSOIDS` for ellipsoids, and `SPHERES` for spheres. + +At least one global `LENGTH` semantic must be defined. +* If `BOXES_LENGTH` in not defined, or zero, no boxes will be rendered. +* If `CYLINDERS_LENGTH` in not defined, or zero, no cylinders will be rendered. +* If `ELLIPSOIDS_LENGTH` in not defined, or zero, no ellipsoids will be rendered. +* If `SPHERES_LENGTH` in not defined, or zero, no spheres will be rendered. + +Multiple feature types may be defined in a single Geometry tile using multiple `LENGTH` semantics, and in that case, all specified feature types will be rendered. + +If a semantic has a dependency on another semantic, that semantic must be defined as well. + +#### Geometry Semantics + +| Semantic | Data Type | Description | Required | +| --- | --- | --- | --- | +| `BOXES` | `float32[]` | The boxes in the tile. The length of the array will be `16 * BOXES_LENGTH`. The 16 elements are the 4x4 affine transformation matrix in column-major order. | :white_check_mark: Yes, when the global `BOXES_LENGTH` is greater than zero. | +| `BOX_BATCH_IDS` | `uint16[]` | The `batchId` of the box that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No. | +| `CYLINDERS` | `float32[]` | The cylinders in the tile. The length of the array will be `16 * CYLINDERS_LENGTH`. The 16 elements are the 4x4 affine transformation matrix in column-major order. The scale of the x and y axis will be the radius of the cylinder. Scaling the z axis will change the length of the cylinder. | :white_check_mark: Yes, when the global `CYLINDERS_LENGTH` is greater than zero. | +| `CYLINDER_BATCH_IDS` | `uint16[]` | The `batchId` of the cylinder that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No. | +| `ELLIPSOIDS` | `float32[]` | The ellipsoids in the tile. The length of the array will be `16 * ELLIPSOIDS_LENGTH`. The 16 elements are the 4x4 affine transformation matrix in column-major order. | :white_check_mark: Yes, when the global `ELLIPSOIDS_LENGTH` is greater than zero. | +| `ELLIPSOID_BATCH_IDS` | `uint16[]` | The `batchId` of the ellipsoid that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No. | +| `SPHERES` | `float32[]` | The spheres in the tile. The length of the array will be `4 * SPHERES_LENGTH`. The first element is the scale of the sphere. The following 3 elements are the translation of the sphere. | :white_check_mark: Yes, when the global `SPHERES_LENGTH` is greater than zero. | +| `SPHERE_BATCH_IDS` | `uint16[]` | The `batchId` of the sphere that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No. | + +#### Global Semantics + +The semantics define global properties for all geometry elements. + +| Semantic | Data Type | Description | Required | +| --- | --- | --- | --- | +| `BOXES_LENGTH` | `uint32` | The number of boxes in the tile. | :red_circle: No. | +| `CYLINDERS_LENGTH` | `uint32` | The number of cylinders in the tile. | :red_circle: No. | +| `ELLIPSOIDS_LENGTH` | `uint32` | The number of ellipsoids in the tile. | :red_circle: No. | +| `SPHERES_LENGTH` | `uint32` | The number of spheres in the tile. | :red_circle: No. | +| `RTC_CENTER` | `float32[]` | The center used for RTC rendering. | :red_circle: No. | + +## Batch Table + +The _Batch Table_ contains application-specific metadata, indexable by `batchId`, that can be used for declarative styling and application-specific use cases such as populating a UI or issuing a REST API request. + +See the [Batch Table](../BatchTable/README.md) reference for more information. + +## File Extension + +`.geom` + +The file extension is optional. Valid implementations ignore it and identify a content's format by the `magic` field in its header. + +## MIME Type + +_TODO, [#60](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/60)_ + +`application/octet-stream` + +## Implementation Notes + +In JavaScript, a `TypedArray` cannot be created on data unless it is byte-aligned to the data type. +For example, a `Float32Array` must be stored in memory such that its data begins on a byte multiple of four since each `float` contains four bytes. + +The string generated from the JSON and each array should be padded is necessary to ensure byte alignment. diff --git a/TileFormats/Geometry/figures/figures.pptx b/TileFormats/Geometry/figures/figures.pptx new file mode 100644 index 000000000..54698c9b3 Binary files /dev/null and b/TileFormats/Geometry/figures/figures.pptx differ diff --git a/TileFormats/Geometry/figures/layout.jpg b/TileFormats/Geometry/figures/layout.jpg new file mode 100644 index 000000000..7b02e165b Binary files /dev/null and b/TileFormats/Geometry/figures/layout.jpg differ diff --git a/TileFormats/VectorData/README.md b/TileFormats/VectorData/README.md index f03ceab72..3138ddf34 100644 --- a/TileFormats/VectorData/README.md +++ b/TileFormats/VectorData/README.md @@ -1,19 +1,213 @@ # Vector Data -* [Draft spec](https://github.com/AnalyticalGraphicsInc/3d-tiles/pull/124/files) -* GitHub issue, [#25](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/25) +## Contributors -## Notes +* Dan Bagnell, [@bagnell](https://github.com/bagnell) +* Rob Taglang, [@lasalvavida](https://github.com/lasalvavida) +* Patrick Cozzi, [@pjcozzi](https://twitter.com/pjcozzi) +* Sean Lilley, [@lilleyse](https://github.com/lilleyse) -**Use cases**: Traditional geospatial features: points, polylines, and polygons. Replacing KML. +## Overview -**Format** -* Combination of binary (for positions, normals, etc.) and JSON (for labels, other metadata, etc.). -* Concise representations for Cesium's [set of geometries](https://cesiumjs.org/tutorials/Geometry-and-Appearances/), including extrusions, and billboards and labels. - * Need to carefully select the representation for the best trade-off between conciseness and runtime processing. For example, polygons will likely be pre-triangulated since it only adds indices to the payload, but will be subdivided at runtime since subdivision is fast and increases the vertex payload significantly. - * RTC positions for high precision-rendering. - * Context-aware compression. - * Bounding volume may need to be adjusted at runtime for terrain clamping. -* Metadata for cracking, morphing, and perhaps label declutter. +The _Vector_ tile format allows streaming of vector datasets including points, polylines, and polygons. Points can be represented with a combination of billboard, label, and point graphics primitives. -Could also name this a `Geometry` tile. +Each point, poyline, and polygon is a _feature_ in the 3D Tiles specification language. + +## Layout + +A tile is composed of two sections: a header immediately followed by a body. + +**Figure1**: Vector tile layout. +![](figures/layout.jpg) + +## Header + +The 44-byte header contains the following fields: + +| Field name | Data type | Description | +| --- | --- | --- | +| `magic` | 4-byte ANSI string | `"vctr"`. This can be used to identify the arraybuffer as a Vector tile. | +| `version` | `uint32` | The version of the Vector Data format. It is currently `1`. | +| `byteLength` | `uint32` | The length of the entire tile, including the header, in bytes. | +| `featureTableJSONByteLength` | `uint32` | The length of the feature table JSON section in bytes. | +| `featureTableBinaryByteLength` | `uint32` | The length of the feature table binary section in bytes. If `featureTableJSONByteLength` is zero, this will also be zero. | +| `batchTableJSONByteLength` | `uint32` | The length of the batch table JSON section in bytes. Zero indicates that there is no batch table. | +| `batchTableBinaryByteLength` | `uint32` | The length of the batch table binary section in bytes. If `batchTableJSONByteLength` is zero, this will also be zero. | +| `polygonIndicesByteLength` | `uint32` | The length of the polygon indices buffer in bytes. | +| `polygonPositionsByteLength` | `uint32` | The length of the polygon positions buffer in bytes. | +| `polylinePositionsByteLength` | `uint32` | The length of the polyline positions buffer in bytes. | +| `pointPositionsByteLength` | `uint32` | The length of the point positions buffer in bytes. | + +If `featureTableJSONByteLength` equals zero, the tile does not need to be rendered. + +The body section immediately follows the header section, and is composed, in order, of four fields: `Feature Table`, `Batch Table`, `Indices`, and `Positions`. + +Code for reading the header can be found in +[Vector3DModelTileContent.js](https://github.com/AnalyticalGraphicsInc/cesium/blob/vector-tiles/Source/Scene/Vector3DTileContent.js) +in the Cesium implementation of 3D Tiles. + +## Feature Table + +Contains values for `vctr` semantics used to render features. The general layout of a Feature Table is described in the [Feature Table specification](../FeatureTable). + +The `vctr` Feature Table JSON schema is defined in [vctr.featureTable.schema.json](../../schema/vctr.featureTable.schema.json). + +### Semantics + +Per-feature semantics specific to a feature type are prefixed with the name of the feature type. e.g. `POLYGON` for pre-triangulated polygons, `POLYLINE` for polylines and `POINT` for points. + +At least one global `LENGTH` semantic must be defined. +* If `POLYGONS_LENGTH` is not defined, or zero, no polygons will be rendered. +* If `POLYLINES_LENGTH` is not defined, or zero, no polylines will be rendered. +* If `POINTS_LENGTH` is not defined, or zero, no points will be rendered. + +Multiple feature types may be defined in a single Vector tile using multiple `LENGTH` semantics, and in that case, all specified feature types will be rendered. + +If a semantic has a dependency on another semantic, that semantic must be defined as well. + +#### Vector Semantics + +| Semantic | Data Type | Description | Required | +| --- | --- | --- | --- | +| `POLYGON_COUNTS` | `uint32[]` | The number of vertices that belong to each polygon. This refers to the polygon section of the positions buffer in the body. Each polygon count refers to a contiguous number of vertices in the position buffer that represents the polygon. | :white_check_mark: Yes, when the global `POLYGONS_LENGTH` is greater than zero. | +| `POLYGON_INDEX_COUNTS` | `uint32[]` | The number of indices that belong to each polygon. This refers to the indices buffer of the body. Each index count refers to a contiguous number of indices that represent the triangulated polygon. | :white_check_mark: Yes, when the global `POLYGONS_LENGTH` is greater than zero. | +| `POLYGON_MINIMUM_HEIGHTS` | `float32[]` | The minimum height of each polygon in meters above the WGS84 ellipsoid. | :red_circle: No. If the minimum height for each polygon is not specified, the global `MINIMUM_HEIGHT` will be used. | +| `POLYGON_MAXIMUM_HEIGHTS` | `float32[]` | The maximum height of each polygon in meters above the WGS84 ellipsoid. | :red_circle: No. If the maximum height for each polygon is not specified, the global `MAXIMUM_HEIGHT` will be used. | +| `POLYGON_BATCH_IDS` | `uint16[]` | The `batchId` of the polygon that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No | +| `POLYLINE_COUNTS` | `uint32[]` | The number of vertices that belong to each polyline. This refers to the polyline section of the positions buffer in the body. Each polyline count refers to a contiguous number of vertices in the position buffer that represents the polyline. From the first point on the polyline, each successive point creates a segment connected to the previous. | :white_check_mark: Yes, when the global `POLYLINES_LENGTH` is greater than zero. | +| `POLYLINE_WIDTHS` | `uint16[]` | The width of each polyline in pixels. | :red_circle: No. The default width for every polyline is `2.0`. | +| `POLYLINE_BATCH_IDS` | `uint16[]` | The `batchId` of the polyline that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No | +| `POINT_BATCH_IDS` | `uint16[]` | The `batchId` of the point that can be used to retrieve metadata from the `Batch Table`. | :red_circle: No | + +#### Global Semantics + +The semantics define global properties for all vector elements. + +| Semantic | Data Type | Description | Required | +| --- | --- | --- | --- | +| `POLYGONS_LENGTH` | `uint32` | The number of pre-triangulated polygons in the tile. | :red_circle: No | +| `POLYLINES_LENGTH` | `uint32` | The number of polylines in the tile. | :red_circle: No | +| `POINTS_LENGTH` | `uint32` | The number of points in the tile. | :red_circle: No | +| `REGION` | `float32[]` | An array of six numbers that define the bounding geographic region in WGS84 / EPSG:4326 coordinates with the order `[west, south, east, north, minimum height, maximum height]`. Longitudes and latitudes are in radians, and heights are in meters above (or below) the [WGS84 ellipsoid](http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf). | :white_check_mark: Yes | +| `RTC_CENTER` | `float32[]` | The center used for RTC rendering. | :red_circle: No. If no center is supplied, the center of the global `REGION` will be used. | + +## Batch Table + +The _Batch Table_ contains application-specific metadata, indexable by `batchId`, that can be used for declarative styling and application-specific use cases such as populating a UI or issuing a REST API request. + +See the [Batch Table](../BatchTable/README.md) reference for more information. + +### Polygon Indices + +The indices are a buffer of `uint32` values. The byte length is given by `polygonIndicesByteLength` in the header. Each count in `POLYGON_INDEX_COUNT` represents a contiguous section of the array that represents a triangulated polygon. +For example, let the first two polygons have 6 and 12 for their index counts. The first polygon has 3 indices starting at byte offset `0` and ending at byte offset `3 * sizeof(uint32) - 1`. +The second polygon has 6 indices starting at byte offset `3 * sizeof(uint32)` and ending at `3 * sizeof(uint32) + 6 * sizeof(uint32) - 1`. + +**Figure 2**: Example index buffer. + +![](figures/indices.jpg) + +The number of indices must be a multiple of three. Each consecutive list of three indices is a triangle that must be ordered counter-clockwise. Each index is from the start of the buffer, **NOT** from the offset of the first position of the polygon. + +### Positions + +The positions buffer is a `uint16` buffer that contains up to three sub-buffers for the polygons, polylines, and points. + +The positions are represented by u, v, and height values that are quantized and delta encoded. + +| Field | Meaning | +| --- | --- | +| u | The horizontal coordinate of the vertex in the tile. When the u value is 0, the vertex is on the western edge of the tile. Then the value is 32767, the vertex is on the eastern edge of the tile. For other values, the vertex's longitude is a linear interpolation between the longitudes of the western and eastern edges of the tile. | +| v | The vertical coordinate of the vertex in the tile. When the v value is 0, the vertex is on the southern edge of the tile. When the value is 32767, the vertex is on the northern edge of the tile. For other values, the vertex's latitude is a linear interpolation between the latitudes of the southern and northern edges of the tile. | +| height | The height of the vertex of the tile. When the height value is 0, the vertex's height is equal to `MINIMUM_HEIGHT` from the feature table. When the value is 32767, the vertex's height is equal to `MAXIMUM_HEIGHT` from the feature table. For other values, the vertex's height is a linear interpolation of the minimum and maximum heights. | + +The values are then delta and ZigZag encoded. The delta encoding ensures the values are small integers. The ZigZag encoding ensures the values are positive integers. Example encoding code is listed below: +```javascript +function zigZag(value) { + return ((value << 1) ^ (value >> 15)) & 0xFFFF; +} + +var lastU = 0; +var lastV = 0; +var lastHeight = 0; + +for (var i = 0; i < length; ++i) { + var u = uBuffer[i]; + var v = vBuffer[i]; + var height = heightBuffer[i]; + + uBuffer[i] = zigZag(u - lastU); + vBuffer[i] = zigZag(v - lastV); + heightBuffer = zigZag(height - lastHeight); + + lastU = u; + lastV = v; + lastHeight = height; +} +``` + +Example decoding code is listed below: +```javascript +function zigZagDecode(value) { + return (value >> 1) ^ (-(value & 1)); +} + +var u = 0; +var v = 0; +var height = 0; + +for (var i = 0; i < length; ++i) { + u += zigZagDecode(uBuffer[i]); + v += zigZagDecode(vBuffer[i]); + height += zigZagDecode(heightBuffer[i]); + + uBuffer[i] = u; + vBuffer[i] = v; + heightBuffer[i] = height; +} +``` + +#### Polygon positions + +**Figure 3**: Polygon layout. + +![](figures/polygon.jpg) + +The number of positions for each polygon is determined by the value of its `POLYGON_COUNT`. For example, let the first polygon count be 5. The first polygon's u values start at offset `0` and end at `5 * sizeof(uint16)`. Its v values start at `polygonPositionsByteLength / 2` and end at `polygonPositionsByteLength / 2 + 5 * sizeof(uint16)`. + +The positions of the polygons must be the outer ring positions listed in counter-clockwise order. + +#### Polyline positions + +**Figure 4**: Polyline layout. + +![](figures/polyline.jpg) + +The number of positions for each polyline is determined by the value of its `POLYLINE_COUNT`. From the first point on the polyline, each successive point creates a segment connected to the previous. + +#### Point positions + +**Figure 5**: Point layout. + +![](figures/point.jpg) + +Each `u, v, height` triple is a single point. + +## File Extension + +`.vctr` + +The file extension is optional. Valid implementations ignore it and identify a content's format by the `magic` field in its header. + +## MIME Type + +_TODO, [#60](https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/60)_ + +`application/octet-stream` + +## Implementation Notes + +In JavaScript, a `TypedArray` cannot be created on data unless it is byte-aligned to the data type. +For example, a `Float32Array` must be stored in memory such that its data begins on a byte multiple of four since each `float` contains four bytes. + +The string generated from the JSON and each array should be padded is necessary to ensure byte alignment. diff --git a/TileFormats/VectorData/figures/figues.pptx b/TileFormats/VectorData/figures/figues.pptx new file mode 100644 index 000000000..e41b7eebb Binary files /dev/null and b/TileFormats/VectorData/figures/figues.pptx differ diff --git a/TileFormats/VectorData/figures/indices.jpg b/TileFormats/VectorData/figures/indices.jpg new file mode 100644 index 000000000..8bb8a4c77 Binary files /dev/null and b/TileFormats/VectorData/figures/indices.jpg differ diff --git a/TileFormats/VectorData/figures/layout.jpg b/TileFormats/VectorData/figures/layout.jpg new file mode 100644 index 000000000..b550849ec Binary files /dev/null and b/TileFormats/VectorData/figures/layout.jpg differ diff --git a/TileFormats/VectorData/figures/point.jpg b/TileFormats/VectorData/figures/point.jpg new file mode 100644 index 000000000..6d9932c6b Binary files /dev/null and b/TileFormats/VectorData/figures/point.jpg differ diff --git a/TileFormats/VectorData/figures/polygon.jpg b/TileFormats/VectorData/figures/polygon.jpg new file mode 100644 index 000000000..5363c7a6b Binary files /dev/null and b/TileFormats/VectorData/figures/polygon.jpg differ diff --git a/TileFormats/VectorData/figures/polyline.jpg b/TileFormats/VectorData/figures/polyline.jpg new file mode 100644 index 000000000..4c82bf3b7 Binary files /dev/null and b/TileFormats/VectorData/figures/polyline.jpg differ diff --git a/schema/geom.featureTable.schema.json b/schema/geom.featureTable.schema.json new file mode 100644 index 000000000..f72532c77 --- /dev/null +++ b/schema/geom.featureTable.schema.json @@ -0,0 +1,73 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema", + "id" : "geom.featureTable.schema.json", + "title" : "Geometry Feature Table", + "type" : "object", + "description" : "A set of Geometry semantics that contain additional information about features in a tile.", + "allOf" : [{ + "$ref" : "featureTable.schema.json" + }, { + "properties" : { + "RTC_CENTER" : { + "type" : "array", + "description" : "A floating-point 3 element array that defines the center for RTC rendering.", + "items" : { + "type": "number" + }, + "minItems" : 3, + "maxItems" : 3 + }, + "BOXES_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "CYLINDERS_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "ELLIPSOIDS_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "SPHERES_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "BOXES" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "BOX_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "CYLINDERS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "CYLINDER_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "ELLIPSOIDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "ELLIPSOID_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "SPHERES" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "SPHERE_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + } + }, + "dependencies" : { + "BOXES_LENGTH" : [ + "BOXES" + ], + "CYLINDERS_LENGTH" : [ + "CYLINDERS" + ], + "ELLIPSOIDS_LENGTH" : [ + "ELLIPSOIDS" + ], + "SPHERES_LENGTH" : [ + "SPHERES" + ] + }, + "additionalProperties" : false + }] +} diff --git a/schema/vctr.featureTable.schema.json b/schema/vctr.featureTable.schema.json new file mode 100644 index 000000000..2d1ca75c3 --- /dev/null +++ b/schema/vctr.featureTable.schema.json @@ -0,0 +1,75 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema", + "id" : "vctr.featureTable.schema.json", + "title" : "Vector Feature Table", + "type" : "object", + "description" : "A set of Vector semantics that contain additional information about features in a tile.", + "allOf" : [{ + "$ref" : "featureTable.schema.json" + }, { + "properties" : { + "REGION" : { + "type" : "array", + "description" : "An array of six numbers that define a bounding geographic region in WGS84 / EPSG:4326 coordinates with the order [west, south, east, north, minimum height, maximum height]. Longitudes and latitudes are in radians, and heights are in meters above (or below) the WGS84 ellipsoid.", + "items" : { + "type" : "number" + }, + "minItems" : 6, + "maxItems" : 6 + }, + "RTC_CENTER" : { + "type" : "array", + "description" : "A floating-point 3 element array that defines the center for RTC rendering.", + "items" : { + "type": "number" + }, + "minItems" : 3, + "maxItems" : 3 + }, + "POLYGONS_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "POLYLINES_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "POINTS_LENGTH" : { + "$ref" : "featureTable.schema.json#/definitions/globalPropertyScalar" + }, + "POLYGON_COUNTS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYGON_INDEX_COUNTS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYGON_MINIMUM_HEIGHTS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYGON_MAXIMUM_HEIGHTS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYGON_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYLINE_COUNTS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POLYLINE_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + }, + "POINT_BATCH_IDS" : { + "$ref" : "featureTable.schema.json#/definitions/binaryBodyReference" + } + }, + "dependencies" : { + "POLYGONS_LENGTH" : [ + "POLYGON_COUNT", + "POLYGON_INDEX_COUNT" + ], + "POLYLINES_LENGTH" : [ + "POLYLINE_COUNT" + ] + }, + "required" : ["REGION"], + "additionalProperties" : false + }] +}