Gach 3D-151-180

Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

Properties and types of a tree

PROPERTY COMPONENTTYPE REQUIRED NODATA

height FLOAT32 Yes

species ENUM "Unknown"

leafColor STRING Yes

9.3.4.14. Property Values Structure

Property values that appear as part of the class definition are the offset, scale, minimum,
maximum, default values and no-data values. The structure of these values inside the class
definition depends on the type of the property. For SCALAR (non-array) types, they are single
values. For all other cases, they are arrays:

• For SCALAR array types with fixed length count, they are arrays with length count.

• For VECN types, they are arrays, with length N.

• For MATN types, they are arrays, with length N * N.

• For VECN array types with fixed length count, they are arrays with length count, where
each array element is itself an array of length N

• For MATN array types with fixed length count, they are arrays with length count, where
each array element is itself an array of length N * N.

For noData values and numeric values that are not normalized, the type of the innermost
elements of these arrays corresponds to the componentType. For numeric values that are
normalized, the innermost elements are floating-point values.

9.4. Storage Formats

9.4.1. Overview
Schemas provide templates for entities, but creating an entity requires specific property values
and storage. This section covers two storage formats for entity metadata:

• Binary Table Format — property values are stored in parallel 1D arrays, encoded as binary
data

OPEN GEOSPATIAL CONSORTIUM 22-025R4 136


• JSON Format — property values are stored in key/value dictionaries, encoded as JSON
objects

Both formats are suitable for general purpose metadata storage. Binary formats may be
preferable for larger quantities of metadata.

Additional serialization methods may be defined outside of this specification. For example,
property values could be stored in texture channels or retrieved from a REST API as XML data.

NOTEAny specification that references 3D Metadata shall state explicitly which storage formats
are supported, or define its own serialization. For example, the EXT_structural_metadata glTF
extension implements the binary table format described below, and defines an additional image-
based format for per-texel metadata.

9.4.2. Binary Table Format

9.4.2.1. Overview

The binary table format is similar to a database table where entities are rows and properties are
columns. Each column represents one of the properties of the class. Each row represents a single
entity conforming to the class.

Figure 58 — Illustration of metadata that can be stored in a table

The rows of a table are addressed by an integer index called an entity ID. Entity IDs are always
numbered 0, 1, ..., N - 1 where N is the number of rows in the table.

Property values are stored in parallel arrays called property arrays, one per column. Each
property array stores values for a single property. The i-th value of each property array is the
value of that property for the entity with an entity ID of i.

Binary encoding is efficient for runtime use, and scalable to large quantities of metadata.
Because property arrays contain elements of a single type, bitstreams may be tightly packed or
may use compression methods appropriate for a particular data type.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 137


Property values are binary-encoded according to their data type, in little-endian format. Values
are tightly packed: there is no padding between values.

9.4.2.2. Scalars

A scalar value is encoded based on the componentType. Multiple values are packed tightly in the
same buffer. The following data types are supported:

Table 31 — Types for scalar metadata values

NAME DESCRIPTION

INT8 8-bit two’s complement signed integer

UINT8 8-bit unsigned integer

INT16 16-bit two’s complement signed integer

UINT16 16-bit unsigned integer

INT32 32-bit two’s complement signed integer

UINT32 32-bit unsigned integer

INT64 64-bit two’s complement signed integer

UINT64 64-bit unsigned integer

FLOAT32 32-bit IEEE floating point number

FLOAT64 64-bit IEEE floating point number

9.4.2.3. Vectors

Vector components are tightly packed and encoded based on the componentType.

9.4.2.4. Matrices

Matrix components are tightly packed in column-major order and encoded based on the
componentType.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 138


9.4.2.5. Booleans

A boolean value is encoded as a single bit, either 0 (false) or 1 (true). Multiple boolean values
are packed tightly in the same buffer. These buffers of tightly-packed bits are sometimes
referred to as bitstreams.

For a table with N rows, the buffer that stores these boolean values will consist of ceil(N / 8)
bytes. When N is not divisible by 8, then the unused bits of the last byte of this buffer shall be
set to 0.

NOTEExample accessing a boolean value for entity ID i.


byteIndex = floor(i / 8)
bitIndex = i % 8
bitValue = (buffer[byteIndex] >> bitIndex) & 1
value = bitValue == 1

9.4.2.6. Strings

A string value is a UTF-8 encoded byte sequence. Multiple strings are packed tightly in the same
buffer.

Because string lengths may vary, a string offset buffer is used to identify strings in the buffer.
If there are N strings in the property array, the string offset buffer has N + 1 elements. The first
N of these point to the first byte of each string, while the last points to the byte immediately
after the last string. The number of bytes in the i-th string is given by stringOffset[i +
1] - stringOffset[i]. UTF-8 encodes each character as 1-4 bytes, so string offsets do not
necessarily represent the number of characters in the string.

The data type used for offsets is defined by a string offset type, which may be UINT8, UINT16,
UINT32, or UINT64.

NOTEThree UTF-8 strings, binary-encoded in a buffer.

Figure 60 — Data layout for the buffers storing string metadata

OPEN GEOSPATIAL CONSORTIUM 22-025R4 139


9.4.2.7. Enums

Enums are encoded as integer values according to the enum value type (see Enums). Any integer
data type supported for Scalars may be used for enum values.

9.4.2.8. Fixed-Length Arrays

A fixed-length array value is encoded as a tightly packed array of count elements, where each
element is encoded according to the type.

9.4.2.9. Variable-Length Arrays

Variable-length arrays use an additional array offset buffer. The i-th value in the array offset
buffer is an element index — not a byte offset — identifying the beginning of the i-th array.
String values within an array may have inconsistent lengths, requiring both array offset and
string offset buffers (see: Strings).

The data type used for offsets is defined by an array offset type, which may be UINT8, UINT16,
UINT32, or UINT64.

If there are N arrays in the property array, the array offset buffer has N + 1 elements. The first N
of these point to the first element of an array within the property array, or within a string offset
buffer for string component types. The last value points to a (non-existent) element immediately
following the last array element.

For each case below, the offset of an array element i within its binary storage is expressed in
terms of entity ID id and element index i.

Table 32 — Offset types for strings and arrays

TYPE OFFSET TYPE OFFSET

STRING byte offset stringOffset[arrayOffset[id] + i]

All other types array index arrayOffset[id] + i

Each expression in the table above defines an index into the underlying property array. For a
property array of SCALAR elements with FLOAT32 component type, index 3 corresponds to byte
offset 3 * sizeof(FLOAT32). For a property array of VEC4 elements with FLOAT32 component
type, index 3 corresponds to byte offset 3 * 4 * sizeof(FLOAT32) = 48. For an array of
BOOLEAN elements, offset 3 would correspond to bit offset 3.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 140


NOTE 1Five variable-length arrays of UINT8 components, binary-encoded in a buffer. The
associated property definition would be type = "SCALAR", componentType = "UINT8", and array =
true.

Figure 61 — Data layout for the buffers storing string variable-length arrays

NOTE 2Two variable-length arrays of strings, binary-encoded in a buffer. The associated


property definition would be type = "STRING" and array = true (variable-length). Observe that
the last element of the array offset buffer points to the last element of the string offset buffer.
This is because the last valid string offset is the next-to-last element of the string offset buffer.

Figure 62 — Data layout for the buffers storing string variable-length arrays of strings

9.4.3. JSON Format

9.4.3.1. Overview

JSON encoding is useful for storing a small number of entities in human readable form.

Each entity is represented as a JSON object with its class identified by a string ID. Property
values are defined in a key/value properties dictionary, having property IDs as its keys.
Property values are encoded as corresponding JSON types: numeric types are represented as

OPEN GEOSPATIAL CONSORTIUM 22-025R4 141


number, booleans as boolean, strings as string, enums as string, vectors and matrices as
array of number, and arrays as array of the containing type.

NOTEThe following example demonstrates usage for both fixed- and variable-length arrays:

An enum, “basicEnum”, composed of three (name: value) pairs:

Names and values of an example enum

NAME VALUE

"Enum A" 0

"Enum B" 1

"Enum C" 2

A class, “basicClass”, composed of ten properties. stringArrayProperty count is undefined and therefore
variable-length.

Properties of an example class

ID TYPE COMPONENTTYPE
ARRAY COUNT ENUMTYPE REQUIRED

floatProperty SCALAR FLOAT64 false Yes

integerProperty SCALAR INT32 false Yes

vectorProperty VEC2 FLOAT32 false Yes

floatArrayProperty SCALAR FLOAT32 true 3 Yes

vectorArrayProperty VEC2 FLOAT32 true 2 Yes

booleanProperty BOOLEAN false Yes

stringProperty STRING false Yes

enumProperty ENUM false basicEnum Yes

stringArrayProperty STRING true Yes

optionalProperty STRING false

OPEN GEOSPATIAL CONSORTIUM 22-025R4 142


A single entity encoded in JSON. Note that the optional property is omitted in this example.

{
"entity": {
"class": "basicClass",
"properties": {
"floatProperty": 1.5,
"integerProperty": -90,
"vectorProperty": [0.0, 1.0],
"floatArrayProperty": [1.0, 0.5, -0.5],
"vectorArrayProperty": [[0.0, 1.0], [1.0, 2.0]],
"booleanProperty": true,
"stringProperty": "x123",
"enumProperty": "Enum B",
"stringArrayProperty": ["abc", "12345", "おはようございます"]
}
}
}

9.4.3.2. Scalars

All component types (INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32, and
FLOAT64) are encoded as JSON numbers. Floating point values shall be representable as IEEE
floating point numbers.

NOTEFor numeric types the size in bits is made explicit. Even though JSON only has a single
number type for all integers and floating point numbers, the application that consumes the JSON
may make a distinction. For example, C and C++ have several different integer types such as
uint8_t, uint32_t. The application is responsible for interpreting the metadata using the type
specified in the property definition.

9.4.3.3. Vectors

Vectors are encoded as a JSON array of numbers.

9.4.3.4. Matrices

Matrices are encoded as a JSON array of numbers in column-major order.

9.4.3.5. Booleans

Booleans are encoded as a JSON boolean, either true or false.

9.4.3.6. Strings

Strings are encoded as JSON strings.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 143


9.4.3.7. Enums

Enums are encoded as JSON strings using the name of the enum value rather than the integer
value. Therefore the enum value type, if specified, is ignored for the JSON encoding.

9.4.3.8. Arrays

Arrays are encoded as JSON arrays, where each element is encoded according to the type.
When a count is specified, the length of the JSON array shall match the count. Otherwise, for
variable-length arrays, the JSON array may be any length, including zero-length.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 144


10

STYLING

OPEN GEOSPATIAL CONSORTIUM 22-025R4 145


10 STYLING

10.1. Overview

3D Tiles styles provide concise declarative styling of tileset features. A style defines expressions
to evaluate the display of a feature, for example color (RGB and translucency) and show
properties, often based on the feature’s properties stored in the tile’s Batch Table.

A style may be applied to a tile that doesn’t contain features, in which case the tile is treated as
an implicit single feature without properties.

While a style may be created for and reference properties of a tileset, a style is independent of a
tileset, such that any style can be applied to any tileset.

Styles are defined with JSON and expressions written in a small subset of JavaScript augmented
for styling. Additionally, the styling language provides a set of built-in functions to support
common math operations.

The following example assigns a color based on building height.


{
"show" : "${Area} > 0",
"color" : {
"conditions" : [
["${Height} < 60", "color('#13293D')"],
["${Height} < 120", "color('#1B98E0')"],
["true", "color('#E8F1F2', 0.5)"]
]
}
}

OPEN GEOSPATIAL CONSORTIUM 22-025R4 146


Figure 63 — Rendering of buildings with different colors, based on the height of the buildings

10.2. Concepts

10.2.1. Styling features


Visual properties available for styling features are the show property, the assigned expression of
which will evaluate to a boolean that determines if the feature is visible, and the color property,
the assigned expression of which will evaluate to a Color object (RGB and translucency) which
determines the displayed color of a feature.

The following style assigns the default show and color properties to each feature:
{
"show" : "true",
"color" : "color('#ffffff')"
}
Instead of showing all features, show can be an expression dependent on a feature’s properties,
for example, the following expression will show only features in the 19341 zip code:
{
"show" : "${ZipCode} === '19341'"
}

OPEN GEOSPATIAL CONSORTIUM 22-025R4 147


show can also be used for more complex queries; for example, here a compound condition and
regular expression are used to show only features whose county starts with 'Chest' and whose
year built is greater than or equal to 1970:
{
"show" : "(regExp('^Chest').test(${County})) && (${YearBuilt} >= 1970)"
}
Colors can also be defined by expressions dependent on a feature’s properties. For example,
the following expression colors features with a temperature above 90 as red and the others as
white:
{
"color" : "(${Temperature} > 90) ? color('red') : color('white')"
}
The color’s alpha component defines the feature’s opacity. For example, the following sets the
feature’s RGB color components from the feature’s properties and makes features with volume
greater than 100 transparent:
{
"color" : "rgba(${red}, ${green}, ${blue}, (${volume} > 100 ? 0.5 : 1.0))"
}

10.2.2. Conditions
In addition to a string containing an expression, color and show can be an array defining a series
of conditions (similar to if...else statements). Conditions can, for example, be used to make
color maps and color ramps with any type of inclusive/exclusive intervals.

For example, the following expression maps an ID property to colors. Conditions are evaluated
in order, so if ${id} is not '1' or '2', the "true" condition returns white. If no conditions are
met, the color of the feature will be undefined:
{
"color" : {
"conditions" : [
["${id} === '1'", "color('#FF0000')"],
["${id} === '2'", "color('#00FF00')"],
["true", "color('#FFFFFF')"]
]
}
}
The next example shows how to use conditions to create a color ramp using intervals with an
inclusive lower bound and exclusive upper bound:
"color" : {
"conditions" : [
["(${Height} >= 1.0) && (${Height} < 10.0)", "color('#FF00FF')"],
["(${Height} >= 10.0) && (${Height} < 30.0)", "color('#FF0000')"],
["(${Height} >= 30.0) && (${Height} < 50.0)", "color('#FFFF00')"],
["(${Height} >= 50.0) && (${Height} < 70.0)", "color('#00FF00')"],
["(${Height} >= 70.0) && (${Height} < 100.0)", "color('#00FFFF')"],
["(${Height} >= 100.0)", "color('#0000FF')"]
]
}

OPEN GEOSPATIAL CONSORTIUM 22-025R4 148


Since conditions are evaluated in order, the above can be written more concisely as the
following:
"color" : {
"conditions" : [
["(${Height} >= 100.0)", "color('#0000FF')"],
["(${Height} >= 70.0)", "color('#00FFFF')"],
["(${Height} >= 50.0)", "color('#00FF00')"],
["(${Height} >= 30.0)", "color('#FFFF00')"],
["(${Height} >= 10.0)", "color('#FF0000')"],
["(${Height} >= 1.0)", "color('#FF00FF')"]
]
}

10.2.3. Defining variables


Commonly used expressions may be stored in a defines object with a variable name as a key.
If a variable references the name of a defined expression, it is replaced with the result of the
referenced evaluated expression:
{
"defines" : {
"NewHeight" : "clamp((${Height} - 0.5) / 2.0, 1.0, 255.0)",
"HeightColor" : "rgb(${Height}, ${Height}, ${Height})"
},
"color" : {
"conditions" : [
["(${NewHeight} >= 100.0)", "color('#0000FF') * ${HeightColor}"],
["(${NewHeight} >= 50.0)", "color('#00FF00') * ${HeightColor}"],
["(${NewHeight} >= 1.0)", "color('#FF0000') * ${HeightColor}"]
]
},
"show" : "${NewHeight} < 200.0"
}
A define expression may not reference other defines; however, it may reference feature
properties with the same name. In the style below a feature of height 150 gets the color red:
{
"defines" : {
"Height" : "${Height}/2.0}",
},
"color" : {
"conditions" : [
["(${Height} >= 100.0)", "color('#0000FF')"],
["(${Height} >= 1.0)", "color('#FF0000')"]
]
}
}

10.2.4. Meta property


Non-visual properties of a feature can be defined using the meta property. For example, the
following sets a description meta property to a string containing the feature name:
{
"meta" : {

OPEN GEOSPATIAL CONSORTIUM 22-025R4 149


"description" : "'Hello, ${featureName}.'"
}
}
A meta property expression can evaluate to any type. For example:
{
"meta" : {
"featureColor" : "rgb(${red}, ${green}, ${blue})",
"featureVolume" : "${height} * ${width} * ${depth}"
}
}

10.3. Expressions

The language for expressions is a small subset of JavaScript (EMCAScript 5), plus native vector
and regular expression types and access to tileset feature properties in the form of readonly
variables.

NOTECesiumJS uses the jsep JavaScript expression parser library to parse style expressions into
an abstract syntax tree (AST).

10.3.1. Semantics
Dot notation is used to access properties by name, e.g., building.name.

Bracket notation ([]) is also used to access properties, e.g., building['name'], or arrays, e.g.,
temperatures[1].

Functions are called with parenthesis (()) and comma-separated arguments, e.g., (isNaN(0.0),
color('cyan', 0.5)).

10.3.2. Operators
The following operators are supported with the same semantics and precedence as JavaScript.

• Unary: +, -, !

• Not supported: ~

• Binary: ||, &&, ===, !==, <, >, <=, >=, +, -, *, /, %, =~, !~

• Not supported: |, ^, &, <<, >>, and >>>

• Ternary: ? :

OPEN GEOSPATIAL CONSORTIUM 22-025R4 150


( and ) are also supported for grouping expressions for clarity and precedence.

Logical || and && implement short-circuiting; true || expression does not evaluate the right
expression, and false && expression does not evaluate the right expression.

Similarly, true ? leftExpression : rightExpression only executes the left expression, and
false ? leftExpression : rightExpression only executes the right expression.

10.3.3. Types
The following types are supported:

• Boolean

• Null

• Undefined

• Number

• String

• Array

• vec2

• vec3

• 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). Colors derive from CSS3 Colors and are
implemented as vec4. RegExp is derived from JavaScript and described in the RegExp section.

Example expressions for different types include the following:

• true, false

• null

• undefined

• 1.0, NaN, Infinity

• 'Cesium', "Cesium"

• [0, 1, 2]

• vec2(1.0, 2.0)

OPEN GEOSPATIAL CONSORTIUM 22-025R4 151


• vec3(1.0, 2.0, 3.0)

• vec4(1.0, 2.0, 3.0, 4.0)

• color('#00FFFF')

• regExp('^Chest'))

10.3.3.1. Number

As in JavaScript, numbers can be NaN or Infinity. The following test functions are supported:

• isNaN(testValue : Number) : Boolean

• isFinite(testValue : Number) : Boolean

10.3.3.2. String

Strings are encoded in UTF-8.

10.3.3.3. Vector

The styling language includes 2, 3, and 4 component floating-point vector types: vec2, vec3, and
vec4. Vector constructors share the same rules as GLSL:

10.3.3.3.1. vec2

• vec2(xy : Number) — initialize each component with the number

• vec2(x : Number, y : Number) — initialize with two numbers

• vec2(xy : vec2) — initialize with another vec2

• vec2(xyz : vec3) — drops the third component of a vec3

• vec2(xyzw : vec4) — drops the third and fourth component of a vec4

10.3.3.3.2. vec3

• vec3(xyz : Number) — initialize each component with the number

• vec3(x : Number, y : Number, z : Number) — initialize with three numbers

• vec3(xyz : vec3) — initialize with another vec3

OPEN GEOSPATIAL CONSORTIUM 22-025R4 152


• vec3(xyzw : vec4) — drops the fourth component of a vec4

• vec3(xy : vec2, z : Number) — initialize with a vec2 and number

• vec3(x : Number, yz : vec2) — initialize with a vec2 and number

10.3.3.3.3. vec4

• vec4(xyzw : Number) — initialize each component with the number

• vec4(x : Number, y : Number, z : Number, w : Number) — initialize with four


numbers

• vec4(xyzw : vec4) — initialize with another vec4

• vec4(xy : vec2, z : Number, w : Number) — initialize with a vec2 and two numbers

• vec4(x : Number, yz : vec2, w : Number) — initialize with a vec2 and two numbers

• vec4(x : Number, y : Number, zw : vec2) — initialize with a vec2 and two numbers

• vec4(xyz : vec3, w : Number) — initialize with a vec3 and number

• vec4(x : Number, yzw : vec3) — initialize with a vec3 and number

10.3.3.3.4. Vector usage

vec2 components may be accessed with

• .x, .y

• .r, .g

• [0], [1]

vec3 components may be accessed with

• .x, .y, .z

• .r, .g, .b

• [0], [1], [2]

vec4 components may be accessed with

• .x, .y, .z, .w

• .r, .g, .b, .a

OPEN GEOSPATIAL CONSORTIUM 22-025R4 153


• [0], [1], [2], [3]

Unlike GLSL, the styling language does not support swizzling. For example, vec3(1.0).xy is not
supported.

Vectors support the following unary operators: -, +.

Vectors support the following binary operators by performing component-wise operations: ==


=, !==, +, -, *, /, and %. For example vec4(1.0) === vec4(1.0) is true since the x, y, z, and w
components are equal. Operators are essentially overloaded for vec2, vec3, and vec4.

vec2, vec3, and vec4 have a toString function for explicit (and implicit) conversion to strings in
the format '(x, y)', '(x, y, z)', and '(x, y, z, w)'.

• toString() : String

vec2, vec3, and vec4 do not expose any other functions or a prototype object.

10.3.3.4. Color

Colors are implemented as vec4 and are created with one of the following functions:

• color()

• color(keyword : String, [alpha : Number])

• color(6-digit-hex : String, [alpha : Number])

• color(3-digit-hex : String, [alpha : Number])

• rgb(red : Number, green : Number, blue : Number)

• rgba(red : Number, green : Number, blue : Number, alpha : Number)

• hsl(hue : Number, saturation : Number, lightness : Number)

• hsla(hue : Number, saturation : Number, lightness : Number, alpha :


Number)

Calling color() with no arguments is the same as calling color('#FFFFFF').

Colors defined by a case-insensitive keyword (e.g., 'cyan') or hex rgb are passed as strings to
the color function. For example:

• color('cyan')

• color('#00FFFF')

• color('#0FF')

OPEN GEOSPATIAL CONSORTIUM 22-025R4 154


These color functions have an optional second argument that is an alpha component to define
opacity, where 0.0 is fully transparent and 1.0 is fully opaque. For example:

• color('cyan', 0.5)

Colors defined with decimal RGB or HSL are created with rgb and hsl functions, respectively,
just as in CSS (but with percentage ranges from 0.0 to 1.0 for 0% to 100%, respectively). For
example:

• rgb(100, 255, 190)

• hsl(1.0, 0.6, 0.7)

The range for rgb components is 0 to 255, inclusive. For hsl, the range for hue, saturation, and
lightness is 0.0 to 1.0, inclusive.

Colors defined with rgba or hsla have a fourth argument that is an alpha component to define
opacity, where 0.0 is fully transparent and 1.0 is fully opaque. For example:

• rgba(100, 255, 190, 0.25)

• hsla(1.0, 0.6, 0.7, 0.75)

Colors are equivalent to the vec4 type and share the same functions, operators, and component
accessors. Color components are stored in the range 0.0 to 1.0.

For example:

• color('red').x, color('red').r, and color('red')[0] all evaluate to 1.0.

• color('red').toString() evaluates to (1.0, 0.0, 0.0, 1.0)

• color('red') * vec4(0.5) is equivalent to vec4(0.5, 0.0, 0.0, 0.5)

10.3.3.5. RegExp

Regular expressions are created with the following functions, which behave like the JavaScript
RegExp constructor:

• regExp()

• regExp(pattern : String, [flags : String])

Calling regExp() with no arguments is the same as calling regExp('(?:)').

If specified, flags can have any combination of the following values:

• g — global match

OPEN GEOSPATIAL CONSORTIUM 22-025R4 155


• i — ignore case

• m — multiline

• u — unicode

• y- sticky

Regular expressions support these functions:

• test(string : String) : Boolean — Tests the specified string for a match.

• exec(string : String) : String — Executes a search for a match in the specified


string. If the search succeeds, it returns the first instance of a captured String. If the
search fails, it returns null.

For example:
{
"Name" : "Building 1"
}
regExp('a').test('abc') === true
regExp('a(.)', 'i').exec('Abc') === 'b'
regExp('Building\s(\d)').exec(${Name}) === '1'
Regular expressions have a toString function for explicit (and implicit) conversion to strings in
the format 'pattern':

• toString() : String

Regular expressions do not expose any other functions or a prototype object.

The operators =~ and !~ are overloaded for regular expressions. The =~ operator matches the
behavior of the test function, and tests the specified string for a match. It returns true if one is
found, and false if not found. The !~ operator is the inverse of the =~ operator. It returns true
if no matches are found, and false if a match is found. Both operators are commutative.

For example, the following expressions all evaluate to true:


regExp('a') =~ 'abc'
'abc' =~ regExp('a')

regExp('a') !~ 'bcd'
'bcd' !~ regExp('a')

10.3.4. Operator rules


• Unary operators + and - operate only on number and vector expressions.

• Unary operator ! operates only on boolean expressions.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 156


• Binary operators <, <=, >, and >= operate only on number expressions.

• Binary operators || and && operate only on boolean expressions.

• Binary operator + operates on the following expressions:

• Number expressions

• Vector expressions of the same type

• If at least one expressions is a string, the other expression is converted to a string


following String Conversions, and the operation returns a concatenated string, e.g.
"name" + 10 evaluates to "name10"

• Binary operator - operates on the following expressions:

• Number expressions

• Vector expressions of the same type

• Binary operator * operates on the following expressions:

• Number expressions

• Vector expressions of the same type

• Mix of number expression and vector expression, e.g. 3 * vec3(1.0) and vec2(1.0)
* 3

• Binary operator / operates on the following expressions:

• Number expressions

• Vector expressions of the same type

• Vector expression followed by number expression, e.g.vec3(1.0) / 3

• Binary operator % operates on the following expressions:

• Number expressions

• Vector expressions of the same type

• Binary equality operators === and !== operate on any expressions. The operation returns
false if the expression types do not match.

• Binary regExp operators =~ and !~ require one argument to be a string expression and the
other to be a RegExp expression.

• Ternary operator ? : conditional argument shall be a boolean expression.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 157


10.3.5. Type conversions
Explicit conversions between primitive types are handled with Boolean, Number, and String
functions.

• Boolean(value : Any) : Boolean

• Number(value : Any) : Number

• String(value : Any) : String

For example:
Boolean(1) === true
Number('1') === 1
String(1) === '1'
Boolean and Number follow JavaScript conventions. String follows String Conversions.

These are essentially casts, not constructor functions.

The styling language does not allow for implicit type conversions, unless stated above.
Expressions like vec3(1.0) === vec4(1.0) and "5" < 6 are not valid.

10.3.6. String conversions


vec2, vec3, vec4, and RegExp expressions are converted to strings using their toString
methods. All other types follow JavaScript conventions.

• true — "true"

• false — "false"

• null — "null"

• undefined — "undefined"

• 5.0 — "5"

• NaN — "NaN"

• Infinity — "Infinity"

• "name" — "name"

• [0, 1, 2] — "[0, 1, 2]"

• vec2(1, 2) — "(1, 2)"

• vec3(1, 2, 3) — "(1, 2, 3)"

OPEN GEOSPATIAL CONSORTIUM 22-025R4 158


• vec4(1, 2, 3, 4) — "(1, 2, 3, 4)"

• RegExp('a') — "/a/"

10.3.7. Constants
The following constants are supported by the styling language:

• Math.PI

• Math.E

10.3.7.1. PI

The mathematical constant PI, which represents a circle’s circumference divided by its diameter,
approximately 3.14159.
{
"show" : "cos(${Angle} + Math.PI) < 0"
}

10.3.7.2. E

Euler’s constant and the base of the natural logarithm, approximately 2.71828.
{
"color" : "color() * pow(Math.E / 2.0, ${Temperature})"
}

10.3.8. Variables
Variables are used to retrieve the property values of individual features in a tileset. Variables
are identified using the ES 6 (ECMAScript 2015) template literal syntax, i.e., ${feature.
identifier} or ${feature['identifier']}, where the identifier is the case-sensitive property
name. Variable names are encoded in UTF-8. feature is implicit and can be omitted in most
cases. If the identifier contains non-alphanumeric characters, such as :, -, #, or spaces, the
${feature['identifier']} form should be used.

Variables can be used anywhere a valid expression is accepted, except inside other variable
identifiers. For example, the following is not allowed:
${foo[${bar}]}
----
If a feature does not have a property with the specified name, the variable evaluates to
undefined. Note that the property may also be null if null was explicitly stored for a property.

OPEN GEOSPATIAL CONSORTIUM 22-025R4 159


Variables may be any of the supported native JavaScript types:

• Boolean

• Null

• Undefined

• Number

• String

• Array

For example:
{
"enabled" : true,
"description" : null,
"order" : 1,
"name" : "Feature name"
}
${enabled} === true
${description} === null
${order} === 1
${name} === 'Feature name'
Additionally, variables originating from vector properties stored in the Batch Table binary are
treated as vector types:

Table 33 — Vector type variables

componentType VARIABLE TYPE

"VEC2" vec2

"VEC3" vec3

"VEC4" vec4

Variables can be used to construct colors or vectors. For example:


rgba(${red}, ${green}, ${blue}, ${alpha})
vec4(${temperature})
Dot or bracket notation is used to access feature subproperties. For example:
{
"address" : {
"street" : "Example street",
"city" : "Example city"
}
}
${address.street} === `Example street`

OPEN GEOSPATIAL CONSORTIUM 22-025R4 160


${address['street']} === `Example street`

${address.city} === `Example city`


${address['city']} === `Example city`
Bracket notation supports only string literals.

Top-level properties can be accessed with bracket notation by explicitly using the feature
keyword. For example:
{
"address.street" : "Maple Street",
"address" : {
"street" : "Oak Street"
}
}
${address.street} === `Oak Street`
${feature.address.street} === `Oak Street`
${feature['address'].street} === `Oak Street`
${feature['address.street']} === `Maple Street`
To access a feature named feature, use the variable ${feature}. This is equivalent to accessing
${feature.feature}

{
"feature" : "building"
}
${feature} === `building`
${feature.feature} === `building`
Variables can also be substituted inside strings defined with backticks, for example:
{
"order" : 1,
"name" : "Feature name"
}
`Name is ${name}, order is ${order}`
Bracket notation is used to access feature subproperties or arrays. For example:
{
"temperatures" : {
"scale" : "fahrenheit",
"values" : [70, 80, 90]
}
}
${temperatures['scale']} === 'fahrenheit'
${temperatures.values[0]} === 70
${temperatures['values'][0]} === 70 // Same as (temperatures[values])[0] and
temperatures.values[0]

10.3.9. Built-in functions


The following built-in functions are supported by the styling language:

• abs

OPEN GEOSPATIAL CONSORTIUM 22-025R4 161


• sqrt

• cos

• sin

• tan

• acos

• asin

• atan

• atan2

• radians

• degrees

• sign

• floor

• ceil

• round

• exp

• log

• exp2

• log2

• fract

• pow

• min

• max

• clamp

• mix

• length

• distance

• normalize

• dot

OPEN GEOSPATIAL CONSORTIUM 22-025R4 162


• cross

Many of the built-in functions take either scalars or vectors as arguments. For vector arguments
the function is applied component-wise and the resulting vector is returned.

10.3.9.1. abs
abs(x : Number) : Number
abs(x : vec2) : vec2
abs(x : vec3) : vec3
abs(x : vec4) : vec4
Returns the absolute value of x.
{
"show" : "abs(${temperature}) > 20.0"
}

10.3.9.2. sqrt
sqrt(x : Number) : Number
sqrt(x : vec2) : vec2
sqrt(x : vec3) : vec3
sqrt(x : vec4) : vec4
Returns the square root of x when x >= 0. Returns NaN when x < 0.
{
"color" : {
"conditions" : [
["${temperature} >= 0.5", "color('#00FFFF')"],
["${temperature} >= 0.0", "color('#FF00FF')"]
]
}
}

10.3.9.3. cos
cos(angle : Number) : Number
cos(angle : vec2) : vec2
cos(angle : vec3) : vec3
cos(angle : vec4) : vec4
Returns the cosine of angle in radians.
{
"show" : "cos(${Angle}) > 0.0"
}

10.3.9.4. sin
sin(angle : Number) : Number
sin(angle : vec2) : vec2

OPEN GEOSPATIAL CONSORTIUM 22-025R4 163


sin(angle : vec3) : vec3
sin(angle : vec4) : vec4
Returns the sine of angle in radians.
{
"show" : "sin(${Angle}) > 0.0"
}

10.3.9.5. tan
tan(angle : Number) : Number
tan(angle : vec2) : vec2
tan(angle : vec3) : vec3
tan(angle : vec4) : vec4
Returns the tangent of angle in radians.
{
"show" : "tan(${Angle}) > 0.0"
}

10.3.9.6. acos
acos(angle : Number) : Number
acos(angle : vec2) : vec2
acos(angle : vec3) : vec3
acos(angle : vec4) : vec4
Returns the arccosine of angle in radians.
{
"show" : "acos(${Angle}) > 0.0"
}

10.3.9.7. asin
asin(angle : Number) : Number
asin(angle : vec2) : vec2
asin(angle : vec3) : vec3
asin(angle : vec4) : vec4
Returns the arcsine of angle in radians.
{
"show" : "asin(${Angle}) > 0.0"
}

10.3.9.8. atan
atan(angle : Number) : Number
atan(angle : vec2) : vec2
atan(angle : vec3) : vec3
atan(angle : vec4) : vec4

OPEN GEOSPATIAL CONSORTIUM 22-025R4 164


Returns the arctangent of angle in radians.
{
"show" : "atan(${Angle}) > 0.0"
}

10.3.9.9. atan2
atan2(y : Number, x : Number) : Number
atan2(y : vec2, x : vec2) : vec2
atan2(y : vec3, x : vec3) : vec3
atan2(y : vec4, x : vec4) : vec4
Returns the arctangent of the quotient of y and x.
{
"show" : "atan2(${GridY}, ${GridX}) > 0.0"
}

10.3.9.10. radians
radians(angle : Number) : Number
radians(angle : vec2) : vec2
radians(angle : vec3) : vec3
radians(angle : vec4) : vec4
Converts angle from degrees to radians.
{
"show" : "radians(${Angle}) > 0.5"
}

10.3.9.11. degrees
degrees(angle : Number) : Number
degrees(angle : vec2) : vec2
degrees(angle : vec3) : vec3
degrees(angle : vec4) : vec4
Converts angle from radians to degrees.
{
"show" : "degrees(${Angle}) > 45.0"
}

10.3.9.12. sign
sign(x : Number) : Number
sign(x : vec2) : vec2
sign(x : vec3) : vec3
sign(x : vec4) : vec4
Returns 1.0 when x is positive, 0.0 when x is zero, and -1.0 when x is negative.
{

OPEN GEOSPATIAL CONSORTIUM 22-025R4 165

You might also like