From db95ba147ad23949efe05fce0ca57d744055faaa Mon Sep 17 00:00:00 2001 From: Bart Louwers Date: Tue, 27 Aug 2024 00:09:29 +0200 Subject: [PATCH] Use latest MapLibre Style Spec (#2756) --- .github/workflows/android-ci.yml | 23 +- BUILD.bazel | 1 - package-lock.json | 263 ++- package.json | 5 +- .../style/layers/location_indicator_layer.cpp | 15 + .../style/layers/location_indicator_layer.hpp | 2 + .../location/LocationIndicatorLayer.java | 28 + .../android/style/layers/HillshadeLayer.java | 2 +- .../android/style/layers/Property.java | 10 +- .../android/style/layers/PropertyFactory.java | 28 +- .../android/style/layers/SymbolLayer.java | 2 +- .../location/LocationIndicatorLayerTest.java | 12 + platform/android/package-lock.json | 265 --- platform/android/package.json | 25 - .../scripts/android-style-spec-overrides.mjs | 184 ++ .../android/scripts/generate-style-code.mjs | 471 ++++ .../darwin/scripts/generate-style-code.mjs | 68 +- pnpm-lock.yaml | 196 +- scripts/style-code.mjs | 10 - scripts/style-spec-reference/latest.mjs | 3 - scripts/style-spec-reference/v8.json | 2037 ++++++++++++----- scripts/style-spec.mjs | 362 +-- test/BUILD.bazel | 2 +- 23 files changed, 2807 insertions(+), 1207 deletions(-) delete mode 100644 platform/android/package-lock.json delete mode 100644 platform/android/package.json create mode 100644 platform/android/scripts/android-style-spec-overrides.mjs create mode 100644 platform/android/scripts/generate-style-code.mjs delete mode 100644 scripts/style-spec-reference/latest.mjs diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml index 4bf34ac2e..609e258d6 100644 --- a/.github/workflows/android-ci.yml +++ b/.github/workflows/android-ci.yml @@ -84,9 +84,30 @@ jobs: ${{ runner.os }}-build- ${{ runner.os }}- + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + - name: npm install run: npm install --ignore-scripts - working-directory: platform/android + working-directory: . + + - name: run platform/android/scripts/generate-style-code.mjs + run: node platform/android/scripts/generate-style-code.mjs + working-directory: . + + - uses: pre-commit/action@v3.0.1 + continue-on-error: true # this can mean files are modified, which is not an error + with: + extra_args: clang-format --all-files + + - uses: pre-commit/action@v3.0.1 + with: + extra_args: clang-format --all-files + + - uses: infotroph/tree-is-clean@v1 + with: + check_untracked: true - uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/BUILD.bazel b/BUILD.bazel index 33e2d795f..9e7d53e03 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -229,7 +229,6 @@ js_library( name = "style-spec", srcs = ["scripts/style-spec.mjs"], data = glob([ - "scripts/style-spec-reference/*.mjs", "scripts/style-spec-reference/*.json", ]), visibility = ["//visibility:public"], diff --git a/package-lock.json b/package-lock.json index e6bec2bdf..759764890 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "5.4.0", "license": "BSD-2-Clause", "dependencies": { + "@maplibre/maplibre-gl-style-spec": "^20.3.1", "minimatch": "^9.0.4", "npm-run-all": "^4.1.5", "simple-git": "^3.25.0" @@ -1088,6 +1089,14 @@ "flow-remove-types": "flow-remove-types" } }, + "node_modules/@mapbox/jsonlint-lines-primitives": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/@mapbox/mvt-fixtures": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@mapbox/mvt-fixtures/-/mvt-fixtures-3.10.0.tgz", @@ -1119,6 +1128,12 @@ "xyz": "bin/xyz.js" } }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause" + }, "node_modules/@mapbox/vector-tile": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", @@ -1128,6 +1143,27 @@ "@mapbox/point-geometry": "~0.1.0" } }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "20.3.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.3.1.tgz", + "integrity": "sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==", + "license": "ISC", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "sort-object": "^3.0.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, "node_modules/@octokit/auth-token": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.0.tgz", @@ -2212,6 +2248,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -2291,6 +2336,15 @@ "node": ">=0.8" } }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", @@ -2543,6 +2597,25 @@ "node": ">= 0.8" } }, + "node_modules/bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==", + "license": "MIT", + "dependencies": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "node_modules/bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==", + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3202,6 +3275,18 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3421,6 +3506,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3816,6 +3910,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -3853,6 +3956,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -3986,6 +4101,15 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -4058,8 +4182,7 @@ "node_modules/json-stringify-pretty-compact": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", - "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", - "dev": true + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==" }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -4323,7 +4446,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4807,6 +4929,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "license": "ISC" + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -4951,6 +5079,12 @@ "protocol-buffers-schema": "^3.3.1" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-array-concat": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", @@ -5111,6 +5245,21 @@ "node": ">= 0.4" } }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -5219,6 +5368,41 @@ "plist": "^3.0.5" } }, + "node_modules/sort-asc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.2.0.tgz", + "integrity": "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-desc": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.2.0.tgz", + "integrity": "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-object": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-3.0.3.tgz", + "integrity": "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==", + "license": "MIT", + "dependencies": { + "bytewise": "^1.1.0", + "get-value": "^2.0.2", + "is-extendable": "^0.1.1", + "sort-asc": "^0.2.0", + "sort-desc": "^0.2.0", + "union-value": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -5247,6 +5431,43 @@ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==" }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -5537,6 +5758,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -5678,6 +5905,21 @@ "node": ">=14.17" } }, + "node_modules/typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==", + "license": "MIT", + "dependencies": { + "typewise-core": "^1.2.0" + } + }, + "node_modules/typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==", + "license": "MIT" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -5699,6 +5941,21 @@ "dev": true, "license": "MIT" }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/universal-user-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", diff --git a/package.json b/package.json index 69378454c..b26440424 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "main": "index.js", "license": "BSD-2-Clause", "dependencies": { + "@maplibre/maplibre-gl-style-spec": "^20.3.1", "minimatch": "^9.0.4", "npm-run-all": "^4.1.5", "simple-git": "^3.25.0" @@ -44,6 +45,8 @@ "typescript": "^5.4.5", "xcode": "^3.0.1" }, - "scripts": {}, + "scripts": { + "copy-style-spec": "cp node_modules/@maplibre/maplibre-gl-style-spec/dist/latest.json scripts/style-spec-reference/v8.json" + }, "type": "module" } diff --git a/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.cpp b/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.cpp index a7abba30d..b7ca8813f 100644 --- a/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.cpp @@ -70,6 +70,19 @@ jni::Local> LocationIndicatorLayer::getBearing(jni::JNIEnv& env) { return std::move(*convert>>(env, toLocationIndicatorLayer(layer).getBearing())); } +jni::Local> LocationIndicatorLayer::getBearingTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = toLocationIndicatorLayer(layer).getBearingTransition(); + return std::move(*convert>>(env, options)); +} + +void LocationIndicatorLayer::setBearingTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + toLocationIndicatorLayer(layer).setBearingTransition(options); +} + jni::Local> LocationIndicatorLayer::getLocation(jni::JNIEnv& env) { using namespace mbgl::android::conversion; return std::move(*convert>>(env, toLocationIndicatorLayer(layer).getLocation())); @@ -244,6 +257,8 @@ void LocationIndicatorJavaLayerPeerFactory::registerNative(jni::JNIEnv& env) { METHOD(&LocationIndicatorLayer::getShadowImage, "nativeGetShadowImage"), METHOD(&LocationIndicatorLayer::getPerspectiveCompensation, "nativeGetPerspectiveCompensation"), METHOD(&LocationIndicatorLayer::getImageTiltDisplacement, "nativeGetImageTiltDisplacement"), + METHOD(&LocationIndicatorLayer::getBearingTransition, "nativeGetBearingTransition"), + METHOD(&LocationIndicatorLayer::setBearingTransition, "nativeSetBearingTransition"), METHOD(&LocationIndicatorLayer::getBearing, "nativeGetBearing"), METHOD(&LocationIndicatorLayer::getLocationTransition, "nativeGetLocationTransition"), METHOD(&LocationIndicatorLayer::setLocationTransition, "nativeSetLocationTransition"), diff --git a/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.hpp b/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.hpp index 387a58d0a..4f3ae2dc7 100644 --- a/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/style/layers/location_indicator_layer.hpp @@ -37,6 +37,8 @@ public: jni::Local> getImageTiltDisplacement(jni::JNIEnv&); jni::Local> getBearing(jni::JNIEnv&); + void setBearingTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Local> getBearingTransition(jni::JNIEnv&); jni::Local> getLocation(jni::JNIEnv&); void setLocationTransition(jni::JNIEnv&, jlong duration, jlong delay); diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationIndicatorLayer.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationIndicatorLayer.java index 4a85ee8f6..614e1598e 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationIndicatorLayer.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationIndicatorLayer.java @@ -134,6 +134,27 @@ class LocationIndicatorLayer extends Layer { return (PropertyValue) new PropertyValue("bearing", nativeGetBearing()); } + /** + * Get the Bearing property transition options + * + * @return transition options for Double + */ + @NonNull + public TransitionOptions getBearingTransition() { + checkThread(); + return nativeGetBearingTransition(); + } + + /** + * Set the Bearing property transition options + * + * @param options transition options for Double + */ + public void setBearingTransition(@NonNull TransitionOptions options) { + checkThread(); + nativeSetBearingTransition(options.getDuration(), options.getDelay()); + } + /** * Get the Location property * @@ -423,6 +444,13 @@ class LocationIndicatorLayer extends Layer { @Keep private native Object nativeGetBearing(); + @NonNull + @Keep + private native TransitionOptions nativeGetBearingTransition(); + + @Keep + private native void nativeSetBearingTransition(long duration, long delay); + @NonNull @Keep private native Object nativeGetLocation(); diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java index 4f396afb4..16f1645f4 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/HillshadeLayer.java @@ -16,7 +16,7 @@ import org.maplibre.android.style.expressions.Expression; import org.maplibre.android.style.layers.TransitionOptions; /** - * Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB and Mapzen Terrarium tiles. + * Client-side hillshading visualization based on DEM data. The implementation supports Mapbox Terrain RGB, Mapzen Terrarium tiles and custom encodings. * * @see The online documentation */ diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/Property.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/Property.java index 490ea6bfd..f2a6d16be 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/Property.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/Property.java @@ -108,23 +108,23 @@ public final class Property { @Retention(RetentionPolicy.SOURCE) public @interface SYMBOL_PLACEMENT {} - // SYMBOL_Z_ORDER: Controls the order in which overlapping symbols in the same layer are rendered + // SYMBOL_Z_ORDER: Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use `symbol-sort-key`. /** - * If symbol sort key is set, sort based on that. Otherwise sort symbols by their y-position relative to the viewport. + * Sorts symbols by symbol sort key if set. Otherwise, sorts symbols by their y-position relative to the viewport if {@link ICON_ALLOW_OVERLAP} or {@link TEXT_ALLOW_OVERLAP} is set to {@link TRUE} or {@link ICON_IGNORE_PLACEMENT} or {@link TEXT_IGNORE_PLACEMENT} is {@link FALSE}. */ public static final String SYMBOL_Z_ORDER_AUTO = "auto"; /** - * Symbols will be sorted by their y-position relative to the viewport. + * Sorts symbols by their y-position relative to the viewport if {@link ICON_ALLOW_OVERLAP} or {@link TEXT_ALLOW_OVERLAP} is set to {@link TRUE} or {@link ICON_IGNORE_PLACEMENT} or {@link TEXT_IGNORE_PLACEMENT} is {@link FALSE}. */ public static final String SYMBOL_Z_ORDER_VIEWPORT_Y = "viewport-y"; /** - * Symbols will be rendered in the same order as the source data with no sorting applied. + * Sorts symbols by symbol sort key if set. Otherwise, no sorting is applied; symbols are rendered in the same order as the source data. */ public static final String SYMBOL_Z_ORDER_SOURCE = "source"; /** - * Controls the order in which overlapping symbols in the same layer are rendered + * Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use `symbol-sort-key`. */ @StringDef({ SYMBOL_Z_ORDER_AUTO, diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java index 499b9a1a6..6e86a0c5f 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java @@ -446,7 +446,7 @@ public class PropertyFactory { } /** - * The color of the icon. This can only be used with sdf icons. + * The color of the icon. This can only be used with SDF icons. * * @param value a int color value * @return property wrapper around String color @@ -456,7 +456,7 @@ public class PropertyFactory { } /** - * The color of the icon. This can only be used with sdf icons. + * The color of the icon. This can only be used with SDF icons. * * @param value a String value * @return property wrapper around String @@ -466,7 +466,7 @@ public class PropertyFactory { } /** - * The color of the icon. This can only be used with sdf icons. + * The color of the icon. This can only be used with SDF icons. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -506,7 +506,8 @@ public class PropertyFactory { } /** - * Distance of halo to the icon outline. + * Distance of halo to the icon outline. +The unit is in density-independent pixels only for SDF sprites that were created with a blur radius of 8, multiplied by the display density. I.e., the radius needs to be 16 for `@2x` sprites, etc. * * @param value a Float value * @return property wrapper around Float @@ -516,7 +517,8 @@ public class PropertyFactory { } /** - * Distance of halo to the icon outline. + * Distance of halo to the icon outline. +The unit is in density-independent pixels only for SDF sprites that were created with a blur radius of 8, multiplied by the display density. I.e., the radius needs to be 16 for `@2x` sprites, etc. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -1406,7 +1408,7 @@ public class PropertyFactory { } /** - * Fade duration when a new tile is added. + * Fade duration when a new tile is added, or when a video is started or its coordinates are updated. * * @param value a Float value * @return property wrapper around Float @@ -1416,7 +1418,7 @@ public class PropertyFactory { } /** - * Fade duration when a new tile is added. + * Fade duration when a new tile is added, or when a video is started or its coordinates are updated. * * @param expression an expression statement * @return property wrapper around an expression statement @@ -1806,7 +1808,7 @@ public class PropertyFactory { } /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like MapLibre GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. * * @param value a Boolean value * @return property wrapper around Boolean @@ -1816,7 +1818,7 @@ public class PropertyFactory { } /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like MapLibre GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries. * * @param value a Boolean value * @return property wrapper around Boolean @@ -1846,7 +1848,7 @@ public class PropertyFactory { } /** - * Controls the order in which overlapping symbols in the same layer are rendered + * Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use {@link PropertyFactory#symbolSortKey}. * * @param value a String value * @return property wrapper around String @@ -1856,7 +1858,7 @@ public class PropertyFactory { } /** - * Controls the order in which overlapping symbols in the same layer are rendered + * Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use {@link PropertyFactory#symbolSortKey}. * * @param value a String value * @return property wrapper around String @@ -2046,7 +2048,7 @@ public class PropertyFactory { } /** - * Size of the additional area around the icon bounding box used for detecting symbol collisions. + * Size of additional area round the icon bounding box used for detecting symbol collisions. * * @param value a Float value * @return property wrapper around Float @@ -2056,7 +2058,7 @@ public class PropertyFactory { } /** - * Size of the additional area around the icon bounding box used for detecting symbol collisions. + * Size of additional area round the icon bounding box used for detecting symbol collisions. * * @param value a Float value * @return property wrapper around Float diff --git a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/SymbolLayer.java b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/SymbolLayer.java index cb9a3b9a6..bdae6da13 100644 --- a/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/SymbolLayer.java +++ b/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/SymbolLayer.java @@ -683,7 +683,7 @@ public class SymbolLayer extends Layer { } /** - * The color of the icon. This can only be used with sdf icons. + * The color of the icon. This can only be used with SDF icons. * * @return int representation of a rgba string color * @throws RuntimeException thrown if property isn't a value diff --git a/platform/android/MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/location/LocationIndicatorLayerTest.java b/platform/android/MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/location/LocationIndicatorLayerTest.java index 0941b45e8..d05d1f84a 100644 --- a/platform/android/MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/location/LocationIndicatorLayerTest.java +++ b/platform/android/MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/location/LocationIndicatorLayerTest.java @@ -139,6 +139,18 @@ public class LocationIndicatorLayerTest extends BaseLayerTest { assertEquals(layer.getImageTiltDisplacement().getValue(), propertyValue); } + @Test + @UiThreadTest + public void testBearingTransition() { + Timber.i("bearingTransitionOptions"); + assertNotNull(layer); + + // Set and Get + TransitionOptions options = new TransitionOptions(300, 100); + layer.setBearingTransition(options); + assertEquals(layer.getBearingTransition(), options); + } + @Test @UiThreadTest public void testBearingAsConstant() { diff --git a/platform/android/package-lock.json b/platform/android/package-lock.json deleted file mode 100644 index ad918b101..000000000 --- a/platform/android/package-lock.json +++ /dev/null @@ -1,265 +0,0 @@ -{ - "name": "@mapbox/mapbox-gl-native-android", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@mapbox/mapbox-gl-native-android", - "version": "1.0.0", - "license": "BSD-2-Clause", - "devDependencies": { - "ejs": "^3.1.10", - "esm": "~3.2.25", - "lodash": "^4.17.21", - "pixelmatch": "^5.3.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dev": true, - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/pixelmatch": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", - "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", - "dev": true, - "dependencies": { - "pngjs": "^6.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } -} diff --git a/platform/android/package.json b/platform/android/package.json deleted file mode 100644 index c163a5d2f..000000000 --- a/platform/android/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@mapbox/mapbox-gl-native-android", - "version": "1.0.0", - "description": "Renders map tiles with the Mapbox Maps SDK for Android", - "keywords": [ - "mapbox", - "gl" - ], - "repository": { - "type": "git", - "url": "git@github.com:mapbox/mapbox-gl-native-android.git" - }, - "license": "BSD-2-Clause", - "devDependencies": { - "ejs": "^3.1.10", - "esm": "~3.2.25", - "lodash": "^4.17.21", - "pixelmatch": "^5.3.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=6" - }, - "scripts": {} -} diff --git a/platform/android/scripts/android-style-spec-overrides.mjs b/platform/android/scripts/android-style-spec-overrides.mjs new file mode 100644 index 000000000..f02857020 --- /dev/null +++ b/platform/android/scripts/android-style-spec-overrides.mjs @@ -0,0 +1,184 @@ +import styleSpec from "../../../scripts/style-spec.mjs"; + +/** @type {any} */ +let modifiedReferenceSpec = styleSpec; + +modifiedReferenceSpec.layer.type.values["location-indicator"] = {}; +modifiedReferenceSpec["layout_location-indicator"] = { + "top-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the top of the location indicator." + }, + "bearing-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the middle of the location indicator." + }, + "shadow-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the background of the location indicator." + } +}; + +modifiedReferenceSpec["paint_location-indicator"] = { + "perspective-compensation": { + "type": "number", + "default": "0.85", + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "doc": "The amount of the perspective compensation, between 0 and 1. A value of 1 produces a location indicator of constant width across the screen. A value of 0 makes it scale naturally according to the viewing projection." + }, + "image-tilt-displacement": { + "type": "number", + "property-type": "data-constant", + "default": "0", + "units": "pixels", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "doc": "The displacement off the center of the top image and the shadow image when the pitch of the map is greater than 0. This helps producing a three-dimensional appearence." + }, + "bearing": { + "type": "number", + "default": 0, + "period": 360, + "units": "degrees", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ ] + }, + "transition": true, + "doc": "The bearing of the location indicator." + }, + "location": { + "type": "array", + "default": [ + 0.0, + 0.0, + 0.0 + ], + "length": 3, + "value": "number", + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [] + }, + "transition": true, + "doc": "An array of [latitude, longitude, altitude] position of the location indicator." + }, + "accuracy-radius": { + "type": "number", + "units": "meters", + "default": 0, + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The accuracy, in meters, of the position source used to retrieve the position of the location indicator." + }, + "top-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the top image, as a scale factor applied to the size of the specified image." + }, + "bearing-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the bearing image, as a scale factor applied to the size of the specified image." + }, + "shadow-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the shadow image, as a scale factor applied to the size of the specified image." + }, + "accuracy-radius-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The color for drawing the accuracy radius, as a circle. To adjust transparency, set the alpha component of the color accordingly." + + }, + "accuracy-radius-border-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The color for drawing the accuracy radius border. To adjust transparency, set the alpha component of the color accordingly." + } +}; + +export default modifiedReferenceSpec; diff --git a/platform/android/scripts/generate-style-code.mjs b/platform/android/scripts/generate-style-code.mjs new file mode 100644 index 000000000..76965774a --- /dev/null +++ b/platform/android/scripts/generate-style-code.mjs @@ -0,0 +1,471 @@ +import fs from "node:fs"; +import path from "node:path"; +import ejs from "ejs"; +import spec from "./android-style-spec-overrides.mjs"; +import _ from "lodash"; + +import { writeIfModified, camelize, snakeCaseUpper, iff, camelizeWithLeadingLowercase } from "../../../scripts/style-code.mjs"; + +if (!import.meta.dirname) throw new Error("import.meta.dirname is undefined"); + +function absPath(relativePath) { + return path.join(import.meta.dirname, "..", relativePath); +} + +function setupGlobalEjsHelpers() { + const funcs = { + camelize, + snakeCaseUpper, + iff, + camelizeWithLeadingLowercase + }; + for (const [funcName, func] of Object.entries(funcs)) { + // @ts-ignore + global[funcName] = func; + } +} + +setupGlobalEjsHelpers(); + +// Specification parsing // +const lightProperties = Object.keys(spec[`light`]).reduce((memo, name) => { + var property = spec[`light`][name]; + property.name = name; + property['light-property'] = true; + property.doc = property.doc.replace(/°/g,'°'); + memo.push(property); + return memo; +}, []); + +// Collect layer types from spec +var layers = Object.keys(spec.layer.type.values).map((type) => { + const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => { + if (name !== 'visibility' && type !== 'location-indicator') { + spec[`layout_${type}`][name].name = name; + memo.push(spec[`layout_${type}`][name]); + } + return memo; + }, []); + + const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => { + if (type !== 'location-indicator') { + spec[`paint_${type}`][name].name = name; + memo.push(spec[`paint_${type}`][name]); + } + return memo; + }, []); + + const locationLayoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => { + if (name !== 'visibility' && type === 'location-indicator') { + spec[`layout_${type}`][name].name = name; + memo.push(spec[`layout_${type}`][name]); + } + return memo; + }, []); + + const locationPaintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => { + if (type === 'location-indicator') { + spec[`paint_${type}`][name].name = name; + memo.push(spec[`paint_${type}`][name]); + } + return memo; + }, []); + + return { + type: type, + doc: spec.layer.type.values[type].doc, + layoutProperties: layoutProperties, + paintProperties: paintProperties, + locationLayoutProperties: locationLayoutProperties, + locationPaintProperties: locationPaintProperties, + properties: layoutProperties.concat(paintProperties).concat(locationLayoutProperties).concat(locationPaintProperties) + }; +}); + +// Process all layer properties +const uniqueArrayEnum = (prop, enums) => { + if (prop.value !== 'enum') return false; + const enumsEqual = (val1, val2) => val1.length === val1.length && val1.every((val, i) => val === val2[i]); + return enums.filter(e => enumsEqual(Object.keys(prop.values).sort(), Object.keys(e.values).sort())).length == 0; +}; + +const layoutProperties = _(layers).map('layoutProperties').flatten().value(); +const paintProperties = _(layers).map('paintProperties').flatten().value(); +const locationLayoutProperties = _(layers).map('locationLayoutProperties').flatten().value(); +const locationPaintProperties = _(layers).map('locationPaintProperties').flatten().value(); +const allProperties = _(layoutProperties).union(paintProperties).union(lightProperties).value(); +let allEnumProperties = _(allProperties).filter({'type': 'enum'}).value(); +const uniqueArrayEnumProperties = _(allProperties).filter({'type': 'array'}).filter(prop => uniqueArrayEnum(prop, allEnumProperties)).value(); +const enumProperties = _(allEnumProperties).union(uniqueArrayEnumProperties).value(); + + +global.propertyType = function propertyType(property) { + switch (property.type) { + case 'boolean': + return 'Boolean'; + case 'number': + if (/bearing$/.test(property.name) && + property.period == 360 && + property.units =='degrees') { + return 'Double'; + } + return /location$/.test(property.name) ? 'Double' : 'Float'; + case 'formatted': + return 'Formatted'; + case 'string': + case 'resolvedImage': + return 'String'; + case 'enum': + return 'String'; + case 'color': + return 'String'; + case 'array': + return `${propertyType({type:property.value, name: property.name})}[]`; + default: + throw new Error(`unknown type for ${property.name}`); + } +} + +global.propertyJavaType = function propertyType(property) { + switch (property.type) { + case 'boolean': + return 'boolean'; + case 'number': + return 'float'; + case 'formatted': + return 'Formatted'; + case 'string': + case 'resolvedImage': + return 'String'; + case 'enum': + return 'String'; + case 'color': + return 'String'; + case 'array': + return `${propertyJavaType({type:property.value})}[]`; + default: + throw new Error(`unknown type for ${property.name}`); + } + } + +global.propertyJNIType = function propertyJNIType(property) { + switch (property.type) { + case 'boolean': + return 'jboolean'; + case 'number': + return 'jfloat'; + case 'String': + return 'String'; + case 'enum': + return 'String'; + case 'color': + return 'String'; + case 'array': + return `jarray<${propertyType({type:property.value})}[]>`; + default: + return 'jobject*'; + } +} + +global.propertyNativeType = function (property) { + if (/-translate-anchor$/.test(property.name)) { + return 'TranslateAnchorType'; + } + if (/-(rotation|pitch|illumination)-alignment$/.test(property.name)) { + return 'AlignmentType'; + } + if (/^(text|icon)-anchor$/.test(property.name)) { + return 'SymbolAnchorType'; + } + switch (property.type) { + case 'boolean': + return 'bool'; + case 'number': + return 'float'; + case 'formatted': + case 'string': + case 'resolvedImage': // TODO: replace once we implement image expressions + return 'std::string'; + case 'enum': + if(property['light-property']){ + return `Light${camelize(property.name)}Type`; + } + return `${camelize(property.name)}Type`; + case 'color': + return `Color`; + case 'array': + if (property.length) { + return `std::array<${propertyType({type: property.value})}, ${property.length}>`; + } else { + return `std::vector<${propertyType({type: property.value})}>`; + } + default: throw new Error(`unknown type for ${property.name}`) + } +} + +global.propertyTypeAnnotation = function propertyTypeAnnotation(property) { + switch (property.type) { + case 'enum': + return `@Property.${snakeCaseUpper(property.name)}`; + default: + return ""; + } +}; + +global.defaultExpressionJava = function(property) { + switch (property.type) { + case 'boolean': + return 'boolean'; + case 'number': + return 'number'; + case 'formatted': + return 'format'; + case 'resolvedImage': + return "image"; + case 'string': + case 'image': + return "string"; + case 'enum': + return "string"; + case 'color': + return 'toColor'; + case 'array': + return "array"; + default: return "string"; + } +} + +global.defaultValueJava = function(property) { + if(property.name.endsWith("-pattern")) { + return '"pedestrian-polygon"'; + } + if(property.name.endsWith("-font")) { + return 'new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}'; + } + switch (property.type) { + case 'boolean': + return 'true'; + case 'number': + if (/bearing$/.test(property.name) && + property.period == 360 && + property.units =='degrees') { + return '0.3'; + } + return '0.3f'; + case 'formatted': + return 'new Formatted(new FormattedSection("default"))' + case 'string': + case 'resolvedImage': + return '"' + property['default'] + '"'; + case 'enum': + return snakeCaseUpper(property.name) + "_" + snakeCaseUpper(Object.keys(property.values)[0]); + case 'color': + return '"rgba(255,128,0,0.7)"'; + case 'array': + switch (property.value) { + case 'string': + case 'enum': + if (property['default'] !== undefined) { + return '[' + property['default'] + ']'; + } else { + return 'new String[0]'; + } + case 'number': + var isDouble = /location$/.test(property.name) + var result = 'new ' + (isDouble ? 'Double' : 'Float') + '[] {'; + for (var i = 0; i < property.length; i++) { + result += isDouble ? '0.0' : '0f'; + if (i +1 != property.length) { + result += ', '; + } + } + return result + '}'; + } + default: throw new Error(`unknown type for ${property.name}`) + } +} + +/** + * Produces documentation for property factory methods + */ +global.propertyFactoryMethodDoc = function (property) { + var replaceIfPixels = function (doc) { + return doc.replace('pixels', 'density-independent pixels') + } + let doc = replaceIfPixels(property.doc); + // Match other items in back ticks + doc = doc.replace(/`(.+?)`/g, function (m, symbol, offset, str) { + if (str.substr(offset - 4, 3) !== 'CSS' && symbol[0].toUpperCase() != symbol[0] && _(enumProperties).filter({'name': symbol}).value().length > 0) { + // Property 'enums' + symbol = snakeCaseUpper(symbol); + return '{@link Property.' + symbol + '}'; + } else if( _(allProperties).filter({'name': symbol}).value().length > 0) { + // Other properties + return '{@link PropertyFactory#' + camelizeWithLeadingLowercase(symbol) + '}'; + } else { + // Left overs + return '`' + symbol + '`'; + } + }); + return doc; +}; + +/** + * Produces documentation for property value constants + */ +global.propertyValueDoc = function (property, value) { + + // Match references to other property names & values. + // Requires the format 'When `foo` is set to `bar`,'. + let doc = property.values[value].doc.replace(/When `(.+?)` is set to `(.+?)`(?: or `([^`]+?)`)?,/g, function (m, peerPropertyName, propertyValue, secondPropertyValue, offset, str) { + let otherProperty = snakeCaseUpper(peerPropertyName); + let otherValue = snakeCaseUpper(peerPropertyName) + '_' + snakeCaseUpper(propertyValue); + const firstPropertyValue = 'When {@link ' + `${otherProperty}` + '} is set to {@link Property#' + `${otherValue}` + '}'; + if (secondPropertyValue) { + return firstPropertyValue + ` or {@link Property#${snakeCaseUpper(peerPropertyName) + '_' + snakeCaseUpper(secondPropertyValue)}},`; + } else { + return firstPropertyValue + ','; + } + }); + + // Match references to our own property values. + // Requires the format 'is equivalent to `bar`'. + doc = doc.replace(/is equivalent to `(.+?)`/g, function(m, propertyValue, offset, str) { + propertyValue = snakeCaseUpper(property.name) + '_' + snakeCaseUpper(propertyValue); + return 'is equivalent to {@link Property#' + propertyValue + '}'; + }); + + // Match other items in back ticks + doc = doc.replace(/`(.+?)`/g, function (m, symbol, offset, str) { + if ('values' in property && Object.keys(property.values).indexOf(symbol) !== -1) { + // Property values + propertyValue = snakeCaseUpper(property.name) + '_' + snakeCaseUpper(symbol); + console.log("Transforming", symbol, propertyValue); + return '{@link Property#' + `${propertyValue}` + '}'; + } else if (str.substr(offset - 4, 3) !== 'CSS' && symbol[0].toUpperCase() != symbol[0]) { + // Property 'enums' + if (symbol === 'symbol-sort-key') { + return 'symbol sort key'; + } + + symbol = snakeCaseUpper(symbol); + return '{@link ' + symbol + '}'; + } else { + // Left overs + return symbol + } + }); + return doc; +}; + +global.isLightProperty = function (property) { + return property['light-property'] === true; +}; + +global.propertyValueType = function (property) { + switch (property['property-type']) { + default: + return `PropertyValue<${evaluatedType(property)}>`; + } +}; + +global.evaluatedType = function (property) { + if (/-translate-anchor$/.test(property.name)) { + return 'TranslateAnchorType'; + } + if (/-(rotation|pitch|illumination)-alignment$/.test(property.name)) { + return 'AlignmentType'; + } + if (/^(text|icon)-anchor$/.test(property.name)) { + return 'SymbolAnchorType'; + } + if (/position/.test(property.name)) { + return 'Position'; + } + switch (property.type) { + case 'boolean': + return 'bool'; + case 'number': + return 'float'; + case 'formatted': + case 'string': + case 'image': + return 'std::string'; + case 'enum': + return (isLightProperty(property) ? 'Light' : '') + `${camelize(property.name)}Type`; + case 'color': + return `Color`; + case 'array': + if (property.length) { + return `std::array<${evaluatedType({type: property.value})}, ${property.length}>`; + } else { + return `std::vector<${evaluatedType({type: property.value})}>`; + } + default: throw new Error(`unknown type for ${property.name}`) + } +}; + +global.supportsZoomFunction = function (property) { + return property.expression && property.expression.parameters.indexOf('zoom') > -1; +}; + +global.supportsPropertyFunction = function (property) { + return property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; +}; + +// Template processing // + +// Java + JNI Light (Peer model) +const lightJava = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/main/java/org/maplibre/android/style/light/light.java.ejs'), 'utf8'), {strict: true}); +const lightJavaUnitTests = ejs.compile(fs.readFileSync(absPath('MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/testapp/style/light.junit.ejs'), 'utf8'), {strict: true}); +writeIfModified(absPath(`MapLibreAndroid/src/main/java/org/maplibre/android/style/light/Light.java`), lightJava({properties: lightProperties})); +writeIfModified(absPath(`MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/testapp/style/LightTest.java`), lightJavaUnitTests({properties: lightProperties})); + +// Java +const layerJava = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/layer.java.ejs'), 'utf8'), {strict: true}); +const layerJavaUnitTests = ejs.compile(fs.readFileSync(absPath('MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/testapp/style/layer.junit.ejs'), 'utf8'), {strict: true}); + +for (const layer of layers) { + var srcDir = 'MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/' + var testDir = 'MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/testapp/style/' + if (layer.type === 'location-indicator') { + srcDir = 'MapLibreAndroid/src/main/java/org/maplibre/android/location/' + testDir = 'MapLibreAndroidTestApp/src/androidTest/java/org/maplibre/android/location/' + } + + writeIfModified(absPath(srcDir + `${camelize(layer.type)}Layer.java`), layerJava(layer)); + writeIfModified(absPath(testDir + `${camelize(layer.type)}LayerTest.java`), layerJavaUnitTests(layer)); +} + +// Jni +const layerHpp = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/cpp/style/layers/layer.hpp.ejs'), 'utf8'), {strict: true}); +const layerCpp = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/cpp/style/layers/layer.cpp.ejs'), 'utf8'), {strict: true}); + +for (const layer of layers) { + const layerFileName = layer.type.replace('-', '_'); + + writeIfModified(absPath(`MapLibreAndroid/src/cpp/style/layers/${layerFileName}_layer.hpp`), layerHpp(layer)); + writeIfModified(absPath(`MapLibreAndroid/src/cpp/style/layers/${layerFileName}_layer.cpp`), layerCpp(layer)); +} + +// Java PropertyFactory +const propertyFactoryTemplate = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/property_factory.java.ejs'), 'utf8'), {strict: true}); + +const propertyFactorySrcDir = absPath('MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/PropertyFactory.java') +writeIfModified( + propertyFactorySrcDir, + propertyFactoryTemplate({layoutProperties: layoutProperties, paintProperties: paintProperties, locationIndicator: false}) +); + +const locationPropertyFactorySrcDir = absPath('MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationPropertyFactory.java') +writeIfModified( + locationPropertyFactorySrcDir, + propertyFactoryTemplate({layoutProperties: locationLayoutProperties, paintProperties: locationPaintProperties, locationIndicator: true}) +); + +// Java Property +const enumPropertyJavaTemplate = ejs.compile(fs.readFileSync(absPath('MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/property.java.ejs'), 'utf8'), {strict: true}); +writeIfModified( + absPath(`MapLibreAndroid/src/main/java/org/maplibre/android/style/layers/Property.java`), + enumPropertyJavaTemplate({properties: enumProperties}) +); diff --git a/platform/darwin/scripts/generate-style-code.mjs b/platform/darwin/scripts/generate-style-code.mjs index 1b79fa1b9..dec8cd4fc 100644 --- a/platform/darwin/scripts/generate-style-code.mjs +++ b/platform/darwin/scripts/generate-style-code.mjs @@ -6,8 +6,13 @@ import assert from "assert"; import { readAndCompile, writeIfModified, camelize, unhyphenate } from "../../../scripts/style-code.mjs"; +import styleSpec from "../../../scripts/style-spec.mjs"; + +delete styleSpec.layer.type.values["location-indicator"]; +delete styleSpec["layout_location-indicator"] +delete styleSpec["paint_location-indicator"]; + import cocoaConventions from './style-spec-cocoa-conventions-v8.json' with { type: "json" }; -import styleSpec from '../../../scripts/style-spec-reference/v8.json' with { type: "json" }; import styleSpecOverrides from './style-spec-overrides-v8.json' with { type: "json" }; function setupGlobalEjsHelpers() { @@ -806,9 +811,6 @@ const layerH = readAndCompile('platform/darwin/src/MLNStyleLayer.h.ejs', root); const layerPrivateH = readAndCompile('platform/darwin/src/MLNStyleLayer_Private.h.ejs', root); const layerM = readAndCompile('platform/darwin/src/MLNStyleLayer.mm.ejs', root); const testLayers = readAndCompile('platform/darwin/test/MLNStyleLayerTests.mm.ejs', root); -const forStyleAuthorsMD = readAndCompile('platform/darwin/docs/guides/For_Style_Authors.md.ejs', root); -const ddsGuideMD = readAndCompile('platform/darwin/docs/guides/Migrating_to_Expressions.md.ejs', root); -const templatesMD = readAndCompile('platform/darwin/docs/guides/Tile_URL_Templates.md.ejs', root); const lightH = readAndCompile('platform/darwin/src/MLNLight.h.ejs', root); const lightM = readAndCompile('platform/darwin/src/MLNLight.mm.ejs', root); @@ -900,61 +902,3 @@ for (var layer of layers) { writeIfModified(`platform/darwin/test/${prefix}${camelize(layer.type)}${suffix}Tests.mm`, testLayers(layer), outLocation); } - -// Extract examples for guides from unit tests. -/*let examplesSrc = fs.readFileSync('platform/darwin/test/MLNDocumentationGuideTests.swift', 'utf8'); -const exampleRegex = /func test([\w$]+)\s*\(\)\s*\{[^]*?\n([ \t]+)\/\/#-example-code\n([^]+?)\n\2\/\/#-end-example-code\n/gm; - -let examples = {}; -let match; -while ((match = exampleRegex.exec(examplesSrc)) !== null) { - let testMethodName = match[1], - indentation = match[2], - exampleCode = match[3]; - - // Trim leading whitespace from the example code. - exampleCode = exampleCode.replace(new RegExp('^' + indentation, 'gm'), ''); - - examples[testMethodName] = exampleCode; -} - -global.guideExample = function (guide, exampleId, os) { - // Get the contents of the test method whose name matches the symbol path. - let testMethodName = `${guide}$${exampleId}`; - let example = examples[testMethodName]; - if (!example) { - console.error(`MLNDocumentationExampleTests.test${testMethodName}() not found.`); - process.exit(1); - } - - // Resolve conditional compilation blocks. - example = example.replace(/^(\s*)#if\s+os\((iOS|macOS)\)\n([^]*?)(?:^\1#else\n([^]*?))?^\1#endif\b\n?/gm, - function (m, indentation, ifOs, ifCase, elseCase) { - return (os === ifOs ? ifCase : elseCase).replace(new RegExp('^ ', 'gm'), ''); - }).replace(/\n$/, ''); - - return '```swift\n' + example + '\n```'; -}; - -writeIfModified(`platform/ios/docs/guides/For Style Authors.md`, forStyleAuthorsMD({ - os: 'iOS', - renamedProperties: renamedPropertiesByLayerType, - layers: layers, -}), outLocation); -writeIfModified(`platform/macos/docs/guides/For Style Authors.md`, forStyleAuthorsMD({ - os: 'macOS', - renamedProperties: renamedPropertiesByLayerType, - layers: layers, -}), outLocation); -writeIfModified(`platform/ios/docs/guides/Migrating to Expressions.md`, ddsGuideMD({ - os: 'iOS', -}), outLocation); -writeIfModified(`platform/macos/docs/guides/Migrating to Expressions.md`, ddsGuideMD({ - os: 'macOS', -}), outLocation); -writeIfModified(`platform/ios/docs/guides/Tile URL Templates.md`, templatesMD({ - os: 'iOS', -}), outLocation); -writeIfModified(`platform/macos/docs/guides/Tile URL Templates.md`, templatesMD({ - os: 'macOS', -}), rooutLocationot);*/ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7b18619b7..dd1949a95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@maplibre/maplibre-gl-style-spec': + specifier: ^20.3.1 + version: 20.3.1 minimatch: specifier: ^9.0.4 version: 9.0.4 @@ -34,14 +37,20 @@ devDependencies: '@octokit/rest': specifier: ^20.1.0 version: 20.1.0 + '@types/argparse': + specifier: ^2.0.16 + version: 2.0.16 + '@types/ejs': + specifier: ^3.1.5 + version: 3.1.5 '@types/node': - specifier: ^20.12.7 - version: 20.12.7 + specifier: ^20.16.1 + version: 20.16.1 argparse: specifier: ^2.0.1 version: 2.0.1 csscolorparser: - specifier: ~1.0.3 + specifier: ^1.0.3 version: 1.0.3 d3-queue: specifier: 3.0.7 @@ -848,6 +857,11 @@ packages: vlq: 1.0.1 dev: true + /@mapbox/jsonlint-lines-primitives@2.0.2: + resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} + engines: {node: '>= 0.6'} + dev: false + /@mapbox/mvt-fixtures@3.10.0: resolution: {integrity: sha512-HpObcr5eu7MOcxWqjj81fWjQ/VNUaAWKoK/rjxnd6NeEgN3uknrq6aGrkhC5vvZ20T2G6sWkikyITJ8mgPUa8g==} dependencies: @@ -867,12 +881,30 @@ packages: hasBin: true dev: true + /@mapbox/unitbezier@0.0.1: + resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==} + dev: false + /@mapbox/vector-tile@1.3.1: resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==} dependencies: '@mapbox/point-geometry': 0.1.0 dev: true + /@maplibre/maplibre-gl-style-spec@20.3.1: + resolution: {integrity: sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==} + hasBin: true + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/unitbezier': 0.0.1 + json-stringify-pretty-compact: 4.0.0 + minimist: 1.2.8 + quickselect: 2.0.0 + rw: 1.3.3 + sort-object: 3.0.3 + tinyqueue: 3.0.0 + dev: false + /@octokit/auth-token@4.0.0: resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} engines: {node: '>= 18'} @@ -1505,10 +1537,18 @@ packages: tslib: 2.6.2 dev: true - /@types/node@20.12.7: - resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + /@types/argparse@2.0.16: + resolution: {integrity: sha512-aMqBra2JlqpFeCWOinCtpRpiCkPIXH8hahW2+FkGzvWjfE5sAqtOcrjN5DRcMnTQqFDe6gb1CVYuGnBH0lhXwA==} + dev: true + + /@types/ejs@3.1.5: + resolution: {integrity: sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==} + dev: true + + /@types/node@20.16.1: + resolution: {integrity: sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==} dependencies: - undici-types: 5.26.5 + undici-types: 6.19.8 dev: true /@xmldom/xmldom@0.8.10: @@ -1551,6 +1591,11 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + dev: false + /array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -1597,6 +1642,11 @@ packages: engines: {node: '>=0.8'} dev: true + /assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + dev: false + /async-cache@1.1.0: resolution: {integrity: sha512-YDQc4vBn5NFhY6g6HhVshyi3Fy9+SQ5ePnE7JLDJn1DoL+i7ER+vMwtTNOYk9leZkYMnOwpBCWqyLDPw8Aig8g==} deprecated: No longer maintained. Use [lru-cache](http://npm.im/lru-cache) version 7.6 or higher, and provide an asynchronous `fetchMethod` option. @@ -1728,6 +1778,19 @@ packages: engines: {node: '>= 0.8'} dev: true + /bytewise-core@1.2.3: + resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} + dependencies: + typewise-core: 1.2.0 + dev: false + + /bytewise@1.1.0: + resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} + dependencies: + bytewise-core: 1.2.3 + typewise: 1.0.3 + dev: false + /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -2154,6 +2217,21 @@ packages: - supports-color dev: true + /extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 0.1.1 + dev: false + + /extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + dev: false + /extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: true @@ -2273,6 +2351,11 @@ packages: es-errors: 1.3.0 get-intrinsic: 1.2.4 + /get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + dev: false + /getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} dependencies: @@ -2485,6 +2568,18 @@ packages: dependencies: has-tostringtag: 1.0.2 + /is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + dev: false + + /is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: false + /is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -2500,6 +2595,13 @@ packages: dependencies: has-tostringtag: 1.0.2 + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: false + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2565,6 +2667,11 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: false + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: false + /isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: true @@ -2598,7 +2705,6 @@ packages: /json-stringify-pretty-compact@4.0.0: resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==} - dev: true /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} @@ -2789,7 +2895,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true /mock-property@1.0.3: resolution: {integrity: sha512-2emPTb1reeLLYwHxyVx993iYyCHEiRRO+y8NFXFPL5kl5q14sgTK76cXyEKkeKCHeRw35SfdkUJ10Q1KfHuiIQ==} @@ -3036,6 +3141,10 @@ packages: engines: {node: '>=0.6'} dev: true + /quickselect@2.0.0: + resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + dev: false + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -3129,6 +3238,10 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + /safe-array-concat@1.1.2: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} @@ -3224,6 +3337,16 @@ packages: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + /set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + dev: false + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true @@ -3277,6 +3400,28 @@ packages: plist: 3.1.0 dev: true + /sort-asc@0.2.0: + resolution: {integrity: sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-desc@0.2.0: + resolution: {integrity: sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==} + engines: {node: '>=0.10.0'} + dev: false + + /sort-object@3.0.3: + resolution: {integrity: sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==} + engines: {node: '>=0.10.0'} + dependencies: + bytewise: 1.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + sort-asc: 0.2.0 + sort-desc: 0.2.0 + union-value: 1.0.1 + dev: false + /spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: @@ -3299,6 +3444,13 @@ packages: resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} dev: false + /split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + dev: false + /sshpk@1.18.0: resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} engines: {node: '>=0.10.0'} @@ -3440,6 +3592,10 @@ packages: string.prototype.trim: 1.2.9 dev: true + /tinyqueue@3.0.0: + resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + dev: false + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -3530,6 +3686,16 @@ packages: hasBin: true dev: true + /typewise-core@1.2.0: + resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==} + dev: false + + /typewise@1.0.3: + resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} + dependencies: + typewise-core: 1.2.0 + dev: false + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -3538,10 +3704,20 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} dev: true + /union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + dev: false + /universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} dev: true diff --git a/scripts/style-code.mjs b/scripts/style-code.mjs index 354dae88e..41274baa0 100644 --- a/scripts/style-code.mjs +++ b/scripts/style-code.mjs @@ -42,15 +42,6 @@ export function unhyphenate (/** @type {string} **/ str) { return str.replace(/-/g, " "); }; -// Write out a list of files that this script is modifying so that we can check -/** @type {string[]} **/ -let files = []; -process.on('exit', function() { - const list = path.join(path.dirname(process.argv[1]), path.basename(process.argv[1], '.js') + '.list'); - console.log(`Writing files that this script modifies to: ${list}`); - fs.writeFileSync(list, files.join("\n")); -}); - /** * * @param {string} filename @@ -67,7 +58,6 @@ export function writeIfModified(filename, newContent, output) { fs.mkdirSync(info.dir, {recursive: true}); } - files.push(filename); try { const oldContent = fs.readFileSync(filename, 'utf8'); if (oldContent == newContent) { diff --git a/scripts/style-spec-reference/latest.mjs b/scripts/style-spec-reference/latest.mjs deleted file mode 100644 index ab337fd39..000000000 --- a/scripts/style-spec-reference/latest.mjs +++ /dev/null @@ -1,3 +0,0 @@ - -import spec from './v8.json'; -export default spec; diff --git a/scripts/style-spec-reference/v8.json b/scripts/style-spec-reference/v8.json index 525700a10..c9d35dc17 100644 --- a/scripts/style-spec-reference/v8.json +++ b/scripts/style-spec-reference/v8.json @@ -17,7 +17,13 @@ }, "metadata": { "type": "*", - "doc": "Arbitrary properties useful to track with the stylesheet, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'mapbox:'." + "doc": "Arbitrary properties useful to track with the stylesheet, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'maplibre:'.", + "example": { + "styleeditor:slimmode": true, + "styleeditor:comment": "Style generated 1677776383", + "styleeditor:version": "3.14.159265", + "example:object": { "String": "one", "Number": 2, "Boolean": false } + } }, "center": { "type": "array", @@ -57,26 +63,79 @@ "intensity": 0.4 } }, + "sky": { + "type": "sky", + "doc": "The map's sky configuration. **Note:** this definition is still experimental and is under develoment in maplibre-gl-js.", + "example": { + "sky-color": "#199EF3", + "sky-horizon-blend": 0.5, + "horizon-color": "#ffffff", + "horizon-fog-blend": 0.5, + "fog-color": "#0000ff", + "fog-ground-blend": 0.5, + "atmosphere-blend": ["interpolate", + ["linear"], + ["zoom"], + 0,1, + 10,1, + 12,0 + ] + } + }, + "projection": { + "type": "projection", + "doc": "The projection configuration. **Note:** this definition is still experimental and is under development in maplibre-gl-js.", + "example": { + "type": "globe" + } + }, + "terrain": { + "type": "terrain", + "doc": "The terrain configuration.", + "example": { + "source": "raster-dem-source", + "exaggeration": 0.5 + } + }, "sources": { "required": true, "type": "sources", - "doc": "Data source specifications.", + "doc": "Sources state which data the map should display. Specify the type of source with the `type` property. Adding a source isn't enough to make data appear on the map because sources don't contain styling details like color or width. Layers refer to a source and give it a visual representation. This makes it possible to style the same source in different ways, like differentiating between types of roads in a highways layer.\n\nTiled sources (vector and raster) must specify their details according to the [TileJSON specification](https://github.com/mapbox/tilejson-spec).", "example": { - "mapbox-streets": { + "maplibre-demotiles": { "type": "vector", - "url": "mapbox://mapbox.mapbox-streets-v6" + "url": "https://demotiles.maplibre.org/tiles/tiles.json" + }, + "maplibre-tilejson": { + "type": "vector", + "url": "http://api.example.com/tilejson.json" + }, + "maplibre-streets": { + "type": "vector", + "tiles": [ + "http://a.example.com/tiles/{z}/{x}/{y}.pbf", + "http://b.example.com/tiles/{z}/{x}/{y}.pbf" + ], + "maxzoom": 14 + }, + "wms-imagery": { + "type": "raster", + "tiles": [ + "http://a.example.com/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&width=256&height=256&layers=example" + ], + "tileSize": 256 } } }, "sprite": { - "type": "string", - "doc": "A base URL for retrieving the sprite image and metadata. The extensions `.png`, `.json` and scale factor `@2x.png` will be automatically appended. This property is required if any layer uses the `background-pattern`, `fill-pattern`, `line-pattern`, `fill-extrusion-pattern`, or `icon-image` properties. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).", - "example": "mapbox://sprites/mapbox/bright-v8" + "type": "sprite", + "doc": "An array of `{id: 'my-sprite', url: 'https://example.com/sprite'}` objects. Each object should represent a unique URL to load a sprite from and and a unique ID to use as a prefix when referencing images from that sprite (i.e. 'my-sprite:image'). All the URLs are internally extended to load both .json and .png files. If the `id` field is equal to 'default', the prefix is omitted (just 'image' instead of 'default:image'). All the IDs and URLs must be unique. For backwards compatibility, instead of an array, one can also provide a single string that represent a URL to load the sprite from. The images in this case won't be prefixed.", + "example": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite" }, "glyphs": { "type": "string", - "doc": "A URL template for loading signed-distance-field glyph sets in PBF format. The URL must include `{fontstack}` and `{range}` tokens. This property is required if any layer uses the `text-field` layout property. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).", - "example": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf" + "doc": "A URL template for loading signed-distance-field glyph sets in PBF format. \nThe URL must include:\n\n - `{fontstack}` - When requesting glyphs, this token is replaced with a comma separated list of fonts from a font stack specified in the text-font property of a symbol layer. \n\n - `{range}` - When requesting glyphs, this token is replaced with a range of 256 Unicode code points. For example, to load glyphs for the Unicode Basic Latin and Basic Latin-1 Supplement blocks, the range would be 0-255. The actual ranges that are loaded are determined at runtime based on what text needs to be displayed.\n\nThis property is required if any layer uses the `text-field` layout property. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).", + "example": "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf" }, "transition": { "type": "transition", @@ -90,15 +149,15 @@ "required": true, "type": "array", "value": "layer", - "doc": "Layers will be drawn in the order of this array.", + "doc": "A style's `layers` property lists all the layers available in that style. The type of layer is specified by the `type` property, and must be one of `background`, `fill`, `line`, `symbol`, `raster`, `circle`, `fill-extrusion`, `heatmap`, `hillshade`.\n\nExcept for layers of the `background` type, each layer needs to refer to a source. Layers take the data that they get from a source, optionally filter features, and then define how those features are styled.", "example": [ { - "id": "water", - "source": "mapbox-streets", - "source-layer": "water", - "type": "fill", + "id": "coastline", + "source": "maplibre", + "source-layer": "contries", + "type": "line", "paint": { - "fill-color": "#00ffff" + "line-color": "#198EC8" } } ] @@ -131,7 +190,7 @@ }, "url": { "type": "string", - "doc": "A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`." + "doc": "A URL to a TileJSON resource. Supported protocols are `http:` and `https:`." }, "tiles": { "type": "array", @@ -148,7 +207,7 @@ 180, 85.051129 ], - "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL." + "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by MapLibre." }, "scheme": { "type": "enum", @@ -181,6 +240,17 @@ "type": "promoteId", "doc": "A property to use as a feature id (for feature state). Either a property name, or an object of the form `{: }`. If specified as a string for a vector tile source, the same property is used across all its source layers." }, + "volatile": { + "type": "boolean", + "default": false, + "doc": "A setting to determine whether a source's tiles are cached locally.", + "sdk-support": { + "basic functionality": { + "android": "9.3.0", + "ios": "5.10.0" + } + } + }, "*": { "type": "*", "doc": "Other keys to configure the data source." @@ -199,7 +269,7 @@ }, "url": { "type": "string", - "doc": "A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`." + "doc": "A URL to a TileJSON resource. Supported protocols are `http:` and `https:`." }, "tiles": { "type": "array", @@ -216,7 +286,7 @@ 180, 85.051129 ], - "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL." + "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by MapLibre." }, "minzoom": { "type": "number", @@ -251,6 +321,17 @@ "type": "string", "doc": "Contains an attribution to be displayed when the map is shown to a user." }, + "volatile": { + "type": "boolean", + "default": false, + "doc": "A setting to determine whether a source's tiles are cached locally.", + "sdk-support": { + "basic functionality": { + "android": "9.3.0", + "ios": "5.10.0" + } + } + }, "*": { "type": "*", "doc": "Other keys to configure the data source." @@ -269,7 +350,7 @@ }, "url": { "type": "string", - "doc": "A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`." + "doc": "A URL to a TileJSON resource. Supported protocols are `http:` and `https:`." }, "tiles": { "type": "array", @@ -286,7 +367,7 @@ 180, 85.051129 ], - "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL." + "doc": "An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by MapLibre." }, "minzoom": { "type": "number", @@ -316,10 +397,64 @@ }, "mapbox": { "doc": "Mapbox Terrain RGB tiles. See https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb for more info." + }, + "custom": { + "doc": "Decodes tiles using the redFactor, blueFactor, greenFactor, baseShift parameters." } }, "default": "mapbox", - "doc": "The encoding used by this source. Mapbox Terrain RGB is used by default" + "doc": "The encoding used by this source. Mapbox Terrain RGB is used by default." + }, + "redFactor": { + "type": "number", + "default": 1.0, + "doc": "Value that will be multiplied by the red channel value when decoding. Only used on custom encodings.", + "sdk-support": { + "basic functionality": { + "js": "3.4" + } + } + }, + "blueFactor": { + "type": "number", + "default": 1.0, + "doc": "Value that will be multiplied by the blue channel value when decoding. Only used on custom encodings.", + "sdk-support": { + "basic functionality": { + "js": "3.4" + } + } + }, + "greenFactor": { + "type": "number", + "default": 1.0, + "doc": "Value that will be multiplied by the green channel value when decoding. Only used on custom encodings.", + "sdk-support": { + "basic functionality": { + "js": "3.4" + } + } + }, + "baseShift": { + "type": "number", + "default": 0.0, + "doc": "Value that will be added to the encoding mix when decoding. Only used on custom encodings.", + "sdk-support": { + "basic functionality": { + "js": "3.4" + } + } + }, + "volatile": { + "type": "boolean", + "default": false, + "doc": "A setting to determine whether a source's tiles are cached locally.", + "sdk-support": { + "basic functionality": { + "android": "9.3.0", + "ios": "5.10.0" + } + } }, "*": { "type": "*", @@ -338,6 +473,7 @@ "doc": "The data type of the GeoJSON source." }, "data": { + "required": true, "type": "*", "doc": "A URL to a GeoJSON file, or inline GeoJSON." }, @@ -357,6 +493,10 @@ "minimum": 0, "doc": "Size of the tile buffer on each side. A value of 0 produces no buffer. A value of 512 produces a buffer as wide as the tile itself. Larger values produce fewer rendering artifacts near tile edges and slower performance." }, + "filter": { + "type": "*", + "doc": "An expression for filtering features prior to processing them for rendering." + }, "tolerance": { "type": "number", "default": 0.375, @@ -365,7 +505,7 @@ "cluster": { "type": "boolean", "default": false, - "doc": "If the data is a collection of point features, setting this to true clusters the points by radius into groups. Cluster groups become new `Point` features in the source with additional properties:\n * `cluster` Is `true` if the point is a cluster \n * `cluster_id` A unqiue id for the cluster to be used in conjunction with the [cluster inspection methods](https://www.mapbox.com/mapbox-gl-js/api/#geojsonsource#getclusterexpansionzoom)\n * `point_count` Number of original points grouped into this cluster\n * `point_count_abbreviated` An abbreviated point count" + "doc": "If the data is a collection of point features, setting this to true clusters the points by radius into groups. Cluster groups become new `Point` features in the source with additional properties:\n * `cluster` Is `true` if the point is a cluster \n * `cluster_id` A unqiue id for the cluster to be used in conjunction with the [cluster inspection methods](https://maplibre.org/maplibre-gl-js/docs/API/classes/GeoJSONSource/#getclusterexpansionzoom)\n * `point_count` Number of original points grouped into this cluster\n * `point_count_abbreviated` An abbreviated point count" }, "clusterRadius": { "type": "number", @@ -375,7 +515,11 @@ }, "clusterMaxZoom": { "type": "number", - "doc": "Max zoom on which to cluster points if clustering is enabled. Defaults to one zoom less than maxzoom (so that last zoom features are not clustered)." + "doc": "Max zoom on which to cluster points if clustering is enabled. Defaults to one zoom less than maxzoom (so that last zoom features are not clustered). Clusters are re-evaluated at integer zoom levels so setting clusterMaxZoom to 14 means the clusters will be displayed until z15." + }, + "clusterMinPoints": { + "type": "number", + "doc": "Minimum number of points necessary to form a cluster if clustering is enabled. Defaults to `2`." }, "clusterProperties": { "type": "*", @@ -470,8 +614,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } }, @@ -481,8 +624,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } }, @@ -492,8 +634,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } }, @@ -503,8 +644,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } }, @@ -514,8 +654,7 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, @@ -525,8 +664,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } } }, @@ -536,19 +674,17 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } }, "hillshade": { - "doc": "Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB and Mapzen Terrarium tiles.", + "doc": "Client-side hillshading visualization based on DEM data. The implementation supports Mapbox Terrain RGB, Mapzen Terrarium tiles and custom encodings.", "sdk-support": { "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, @@ -558,8 +694,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } } } @@ -569,7 +704,10 @@ }, "metadata": { "type": "*", - "doc": "Arbitrary properties useful to track with the layer, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'mapbox:'." + "doc": "Arbitrary properties useful to track with the layer, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'maplibre:'.", + "example": { + "source:comment": "Hydrology FCCODE 460 - Narrow wash" + } }, "source": { "type": "string", @@ -632,8 +770,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -645,10 +782,14 @@ "doc": "Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.", "sdk-support": { "basic functionality": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.1.0", + "ios": "5.8.0" }, "data-driven styling": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.1.0", + "ios": "5.8.0" } }, "expression": { @@ -676,8 +817,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -689,10 +829,14 @@ "doc": "Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.", "sdk-support": { "basic functionality": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.2.0", + "ios": "5.9.0" }, "data-driven styling": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.2.0", + "ios": "5.9.0" } }, "expression": { @@ -720,8 +864,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -744,8 +887,7 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "property-type": "constant" @@ -768,8 +910,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "property-type": "constant" @@ -795,8 +936,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -826,14 +966,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.40.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -858,8 +996,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -883,8 +1020,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -900,10 +1036,14 @@ "doc": "Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.", "sdk-support": { "basic functionality": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.1.0", + "ios": "5.8.0" }, "data-driven styling": { - "js": "1.2.0" + "js": "1.2.0", + "android": "9.1.0", + "ios": "5.8.0" } }, "expression": { @@ -931,8 +1071,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -958,14 +1097,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "`line-center` value": { "js": "0.47.0", "android": "6.4.0", - "ios": "4.3.0", - "macos": "0.10.0" + "ios": "4.3.0" } }, "expression": { @@ -991,8 +1128,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1006,13 +1142,12 @@ "symbol-avoid-edges": { "type": "boolean", "default": false, - "doc": "If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries.", + "doc": "If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like MapLibre GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries.", "sdk-support": { "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1030,14 +1165,12 @@ "basic functionality": { "js": "0.53.0", "android": "7.4.0", - "ios": "4.11.0", - "macos": "0.14.0" + "ios": "4.11.0" }, "data-driven styling": { "js": "0.53.0", "android": "7.4.0", - "ios": "4.11.0", - "macos": "0.14.0" + "ios": "4.11.0" } }, "expression": { @@ -1053,23 +1186,22 @@ "type": "enum", "values": { "auto": { - "doc": "If `symbol-sort-key` is set, sort based on that. Otherwise sort symbols by their y-position relative to the viewport." + "doc": "Sorts symbols by `symbol-sort-key` if set. Otherwise, sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`." }, "viewport-y": { - "doc": "Symbols will be sorted by their y-position relative to the viewport." + "doc": "Sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`." }, "source": { - "doc": "Symbols will be rendered in the same order as the source data with no sorting applied." + "doc": "Sorts symbols by `symbol-sort-key` if set. Otherwise, no sorting is applied; symbols are rendered in the same order as the source data." } }, "default": "auto", - "doc": "Controls the order in which overlapping symbols in the same layer are rendered", + "doc": "Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use `symbol-sort-key`.", "sdk-support": { "basic functionality": { "js": "0.49.0", "android": "6.6.0", - "ios": "4.5.0", - "macos": "0.12.0" + "ios": "4.5.0" } }, "expression": { @@ -1085,14 +1217,48 @@ "default": false, "doc": "If true, the icon will be visible even if it collides with other previously drawn symbols.", "requires": [ - "icon-image" + "icon-image", + { + "!": "icon-overlap" + } ], "sdk-support": { "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" + } + }, + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "property-type": "data-constant" + }, + "icon-overlap": { + "type": "enum", + "values": { + "never": { + "doc": "The icon will be hidden if it collides with any other previously drawn symbol." + }, + "always": { + "doc": "The icon will be visible even if it collides with any other previously drawn symbol." + }, + "cooperative": { + "doc": "If the icon collides with another previously drawn symbol, the overlap mode for that symbol is checked. If the previous symbol was placed using `never` overlap mode, the new icon is hidden. If the previous symbol was placed using `always` or `cooperative` overlap mode, the new icon is visible." + } + }, + "doc": "Allows for control over whether to show an icon when it overlaps other symbols on the map. If `icon-overlap` is not set, `icon-allow-overlap` is used instead.", + "requires": [ + "icon-image" + ], + "sdk-support": { + "basic functionality": { + "js": "2.1.0", + "android": "https://github.com/maplibre/maplibre-native/issues/251", + "ios": "https://github.com/maplibre/maplibre-native/issues/251" } }, "expression": { @@ -1114,8 +1280,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1138,8 +1303,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1172,14 +1336,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "`auto` value": { "js": "0.25.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.3.0" + "ios": "3.4.0" } }, "expression": { @@ -1203,14 +1365,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.35.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -1248,8 +1408,12 @@ "basic functionality": { "js": "0.21.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.2.1" + "ios": "3.4.0" + }, + "stretchable icons": { + "js": "1.6.0", + "android": "9.2.0", + "ios": "5.8.0" } }, "expression": { @@ -1287,8 +1451,7 @@ "basic functionality": { "js": "0.21.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.2.1" + "ios": "3.4.0" } }, "expression": { @@ -1307,14 +1470,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.35.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -1339,14 +1500,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.21.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -1359,11 +1518,10 @@ "property-type": "data-driven" }, "icon-padding": { - "type": "number", - "default": 2, - "minimum": 0, + "type": "padding", + "default": [2], "units": "pixels", - "doc": "Size of the additional area around the icon bounding box used for detecting symbol collisions.", + "doc": "Size of additional area round the icon bounding box used for detecting symbol collisions.", "requires": [ "icon-image" ], @@ -1371,17 +1529,20 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" + }, + "data-driven styling": { + "js": "2.2.0" } }, "expression": { "interpolated": true, "parameters": [ - "zoom" + "zoom", + "feature" ] }, - "property-type": "data-constant" + "property-type": "data-driven" }, "icon-keep-upright": { "type": "boolean", @@ -1403,8 +1564,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1431,14 +1591,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -1490,14 +1648,12 @@ "basic functionality": { "js": "0.40.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" }, "data-driven styling": { "js": "0.40.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -1531,8 +1687,7 @@ "basic functionality": { "js": "0.39.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -1565,14 +1720,12 @@ "basic functionality": { "js": "0.21.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.2.1" + "ios": "3.4.0" }, "`auto` value": { "js": "0.25.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.3.0" + "ios": "3.4.0" } }, "expression": { @@ -1592,6 +1745,9 @@ "viewport": { "doc": "Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbol-placement`." }, + "viewport-glyph": { + "doc": "When `symbol-placement` is set to `point`, aligns text to the x-axis of the viewport. When `symbol-placement` is set to `line` or `line-center`, aligns glyphs to the x-axis of the viewport and places them along the line." + }, "auto": { "doc": "When `symbol-placement` is set to `point`, this is equivalent to `viewport`. When `symbol-placement` is set to `line` or `line-center`, this is equivalent to `map`." } @@ -1605,14 +1761,15 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "`auto` value": { "js": "0.25.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.3.0" + "ios": "3.4.0" + }, + "`viewport-glyph` value": { + "js": "2.1.8" } }, "expression": { @@ -1632,14 +1789,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -1666,14 +1821,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -1698,14 +1851,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.35.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -1730,14 +1881,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.40.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -1761,8 +1910,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -1785,14 +1933,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.40.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -1829,20 +1975,17 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.39.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" }, "auto": { "js": "0.54.0", "android": "7.4.0", - "ios": "4.10.0", - "macos": "0.14.0" + "ios": "4.10.0" } }, "expression": { @@ -1863,14 +2006,12 @@ "basic functionality": { "js": "0.54.0", "android": "7.4.0", - "ios": "4.10.0", - "macos": "0.14.0" + "ios": "4.10.0" }, "data-driven styling": { "js": "0.54.0", "android": "7.4.0", - "ios": "4.10.0", - "macos": "0.14.0" + "ios": "4.10.0" } }, "requires": [ @@ -1930,8 +2071,7 @@ "basic functionality": { "js": "0.54.0", "android": "7.4.0", - "ios": "4.10.0", - "macos": "0.14.0" + "ios": "4.10.0" } }, "expression": { @@ -1942,6 +2082,38 @@ }, "property-type": "data-constant" }, + "text-variable-anchor-offset": { + "type": "variableAnchorOffsetCollection", + "requires": [ + "text-field", + { + "symbol-placement": [ + "point" + ] + } + ], + "doc": "To increase the chance of placing high-priority labels on the map, you can provide an array of `text-anchor` locations, each paired with an offset value. The renderer will attempt to place the label at each location, in order, before moving on to the next location+offset. Use `text-justify: auto` to choose justification based on anchor position. \n\n The length of the array must be even, and must alternate between enum and point entries. i.e., each anchor location must be accompanied by a point, and that point defines the offset when the corresponding anchor location is used. Positive offset values indicate right and down, while negative values indicate left and up. Anchor locations may repeat, allowing the renderer to try multiple offsets to try and place a label using the same anchor. \n\n When present, this property takes precedence over `text-anchor`, `text-variable-anchor`, `text-offset`, and `text-radial-offset`. \n\n ```json \n { \"text-variable-anchor-offset\": [\"top\", [0, 4], \"left\", [3,0], \"bottom\", [1, 1]] } \n ``` \n\n When the renderer chooses the `top` anchor, `[0, 4]` will be used for `text-offset`; the text will be shifted down by 4 ems. \n\n When the renderer chooses the `left` anchor, `[3, 0]` will be used for `text-offset`; the text will be shifted right by 3 ems.", + "sdk-support": { + "basic functionality": { + "js": "3.3.0", + "ios": "https://github.com/maplibre/maplibre-native/issues/2358", + "android": "https://github.com/maplibre/maplibre-native/issues/2358" + }, + "data-driven styling": { + "js": "3.3.0", + "ios": "https://github.com/maplibre/maplibre-native/issues/2358", + "android": "https://github.com/maplibre/maplibre-native/issues/2358" + } + }, + "expression": { + "interpolated": true, + "parameters": [ + "zoom", + "feature" + ] + }, + "property-type": "data-driven" + }, "text-anchor": { "type": "enum", "values": { @@ -1985,14 +2157,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.39.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -2022,8 +2192,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -2058,8 +2227,7 @@ "basic functionality": { "js": "1.3.0", "android": "8.3.0", - "ios": "5.3.0", - "macos": "0.14.0" + "ios": "5.3.0" } }, "expression": { @@ -2083,14 +2251,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.35.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -2115,8 +2281,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -2147,8 +2312,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -2181,14 +2345,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -2220,14 +2382,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.35.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -2244,14 +2404,48 @@ "default": false, "doc": "If true, the text will be visible even if it collides with other previously drawn symbols.", "requires": [ - "text-field" + "text-field", + { + "!": "text-overlap" + } ], "sdk-support": { "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" + } + }, + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "property-type": "data-constant" + }, + "text-overlap": { + "type": "enum", + "values": { + "never": { + "doc": "The text will be hidden if it collides with any other previously drawn symbol." + }, + "always": { + "doc": "The text will be visible even if it collides with any other previously drawn symbol." + }, + "cooperative": { + "doc": "If the text collides with another previously drawn symbol, the overlap mode for that symbol is checked. If the previous symbol was placed using `never` overlap mode, the new text is hidden. If the previous symbol was placed using `always` or `cooperative` overlap mode, the new text is visible." + } + }, + "doc": "Allows for control over whether to show symbol text when it overlaps other symbols on the map. If `text-overlap` is not set, `text-allow-overlap` is used instead", + "requires": [ + "text-field" + ], + "sdk-support": { + "basic functionality": { + "js": "2.1.0", + "android": "https://github.com/maplibre/maplibre-native/issues/251", + "ios": "https://github.com/maplibre/maplibre-native/issues/251" } }, "expression": { @@ -2273,8 +2467,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -2297,8 +2490,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -2325,8 +2517,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -2349,8 +2540,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "property-type": "constant" @@ -2373,8 +2563,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "property-type": "constant" @@ -2529,136 +2718,248 @@ "type": "enum", "values": { "let": { - "doc": "Binds expressions to named variables, which can then be referenced in the result expression using [\"var\", \"variable_name\"].", + "doc": "Binds expressions to named variables, which can then be referenced in the result expression using `[\"var\", \"variable_name\"]`.\n\n - [Visualize population density](https://maplibre.org/maplibre-gl-js/docs/examples/visualize-population-density/)", + "example": { + "syntax": { + "method": ["string", "value", "expression"], + "result": "value" + }, + "value": ["let", "someNumber", 500, ["interpolate", ["linear"], ["var", "someNumber"], 274, "#edf8e9", 1551, "#006d2c"]] + }, "group": "Variable binding", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "var": { - "doc": "References variable bound using \"let\".", + "doc": "References variable bound using `let`.\n\n - [Visualize population density](https://maplibre.org/maplibre-gl-js/docs/examples/visualize-population-density/)", + "example": { + "syntax": { + "method": ["string"], + "result": "value" + }, + "value": ["var", "density"] + }, "group": "Variable binding", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "literal": { - "doc": "Provides a literal array or object value.", + "doc": "Provides a literal array or object value.\n\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)", + "example": { + "syntax": { + "method": ["JSON object or array"], + "result": "array | object" + }, + "value": ["literal",["DIN Offc Pro Italic", "Arial Unicode MS Regular"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "array": { - "doc": "Asserts that the input is an array (optionally with a specific item type and length). If, when the input expression is evaluated, it is not of the asserted type, then this assertion will cause the whole expression to be aborted.", + "doc": "Asserts that the input is an array (optionally with a specific item type and length). If, when the input expression is evaluated, it is not of the asserted type, then this assertion will cause the whole expression to be aborted.", + "example": { + "syntax": { + "method": ["value", "string?", "number?"], + "result": "array" + }, + "value": ["array", ["literal", ["a", "b", "c"]], "string", 3] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "at": { "doc": "Retrieves an item from an array.", + "example": { + "syntax": { + "method": ["value", "number"], + "result": "value" + }, + "value": ["at", ["literal", ["a", "b", "c"]], 1] + }, "group": "Lookup", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "in": { - "doc": "Determines whether an item exists in an array or a substring exists in a string.", + "doc": "Determines whether an item exists in an array or a substring exists in a string.\n\n - [Measure distances](https://maplibre.org/maplibre-gl-js/docs/examples/measure/)", + "example": { + "syntax": { + "method": ["value", "value"], + "result": "boolean" + }, + "value": ["in", "$type", "Point"] + }, "group": "Lookup", "sdk-support": { "basic functionality": { - "js": "1.6.0" + "js": "1.6.0", + "android": "9.1.0", + "ios": "5.8.0" + } + } + }, + "index-of": { + "doc": "Returns the first position at which an item can be found in an array or a substring can be found in a string, or `-1` if the input cannot be found. Accepts an optional index from where to begin the search. In a string, a UTF-16 surrogate pair counts as a single position.", + "example": { + "syntax": { + "method": ["value", "value", "number?"], + "result": "number" + }, + "value": ["index-of", "foo", ["baz", "bar", "hello", "foo", "world"]] + }, + "group": "Lookup", + "sdk-support": { + "basic functionality": { + "js": "1.10.0", + "android": "10.3.0", + "ios": "6.0.0" + } + } + }, + "slice": { + "doc": "Returns an item from an array or a substring from a string from a specified start index, or between a start index and an end index if set. The return value is inclusive of the start index but not of the end index. In a string, a UTF-16 surrogate pair counts as a single position.", + "example": { + "syntax": { + "method": ["value", "number", "number?"], + "result": "value" + }, + "value": ["slice", ["get", "name"], 0, 3] + }, + "group": "Lookup", + "sdk-support": { + "basic functionality": { + "js": "1.10.0", + "android": "10.3.0", + "ios": "6.0.0" } } }, "case": { - "doc": "Selects the first output whose corresponding test condition evaluates to true, or the fallback value otherwise.", + "doc": "Selects the first output whose corresponding test condition evaluates to true, or the fallback value otherwise.\n\n - [Create a hover effect](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/)\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["value", "value", "...", "fallback: value"], + "result": "value" + }, + "value": ["case", ["boolean", ["feature-state", "hover"], false], 1, 0.5 ] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "match": { - "doc": "Selects the output whose label value matches the input value, or the fallback value if no match is found. The input can be any expression (e.g. `[\"get\", \"building_type\"]`). Each label must be either:\n * a single literal value; or\n * an array of literal values, whose values must be all strings or all numbers (e.g. `[100, 101]` or `[\"c\", \"b\"]`). The input matches if any of the values in the array matches, similar to the `\"in\"` operator.\n\nEach label must be unique. If the input type does not match the type of the labels, the result will be the fallback value.", + "doc": "Selects the output whose label value matches the input value, or the fallback value if no match is found. The input can be any expression (e.g. `[\"get\", \"building_type\"]`). Each label must be either:\n - a single literal value; or\n - an array of literal values, whose values must be all strings or all numbers (e.g. `[100, 101]` or `[\"c\", \"b\"]`). The input matches if any of the values in the array matches, similar to the `\"in\"` operator.\nEach label must be unique. If the input type does not match the type of the labels, the result will be the fallback value.", + "example": { + "syntax": { + "method": ["value", "value", "...", "fallback: value"], + "result": "value" + }, + "value": ["match", ["get", "building_type"], "residential", "#f00", "commercial", "#0f0", "#000"] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "coalesce": { - "doc": "Evaluates each expression in turn until the first non-null value is obtained, and returns that value.", + "doc": "Evaluates each expression in turn until the first non-null value is obtained, and returns that value.\n\n - [Use a fallback image](https://maplibre.org/maplibre-gl-js/docs/examples/fallback-image/)", + "example": { + "syntax": { + "method": ["coalesce", "value", "fallback"], + "result": "value" + }, + "value": ["coalesce", ["image", ["concat", ["get", "icon"], "_15"]], ["image", "marker_15"] ] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "step": { - "doc": "Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of input and output values (\"stops\"). The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). Stop inputs must be numeric literals in strictly ascending order. Returns the output value of the stop just less than the input, or the first output if the input is less than the first stop.", + "doc": "Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of input and output values (\"stops\"). The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). Stop inputs must be numeric literals in strictly ascending order. Returns the output value of the stop just less than the input, or the first output if the input is less than the first stop.\n\n - [Create and style clusters](https://maplibre.org/maplibre-gl-js/docs/examples/cluster/)", + "example": { + "syntax": { + "method": ["step", "number", "number", "number", "..."], + "result": "number" + }, + "value": [ "step", ["get", "point_count"], 20, 100, 30, 750, 40] + }, "group": "Ramps, scales, curves", "sdk-support": { "basic functionality": { "js": "0.42.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "interpolate": { - "doc": "Produces continuous, smooth results by interpolating between pairs of input and output values (\"stops\"). The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). Stop inputs must be numeric literals in strictly ascending order. The output type must be `number`, `array`, or `color`.\n\nInterpolation types:\n- `[\"linear\"]`: interpolates linearly between the pair of stops just less than and just greater than the input.\n- `[\"exponential\", base]`: interpolates exponentially between the stops just less than and just greater than the input. `base` controls the rate at which the output increases: higher values make the output increase more towards the high end of the range. With values close to 1 the output increases linearly.\n- `[\"cubic-bezier\", x1, y1, x2, y2]`: interpolates using the cubic bezier curve defined by the given control points.", + "doc": "Produces continuous, smooth results by interpolating between pairs of input and output values (\"stops\"). The `input` may be any numeric expression (e.g., `[\"get\", \"population\"]`). Stop inputs must be numeric literals in strictly ascending order. The output type must be `number`, `array`, or `color`.\n\nInterpolation types:\n\n- `[\"linear\"]`, or an expression returning one of those types: Interpolates linearly between the pair of stops just less than and just greater than the input.\n- `[\"exponential\", base]`: Interpolates exponentially between the stops just less than and just greater than the input. `base` controls the rate at which the output increases: higher values make the output increase more towards the high end of the range. With values close to 1 the output increases linearly.\n- `[\"cubic-bezier\", x1, y1, x2, y2]`: Interpolates using the cubic bezier curve defined by the given control points.\n\n - [Animate map camera around a point](https://maplibre.org/maplibre-gl-js/docs/examples/animate-camera-around-point/)\n - [Change building color based on zoom level](https://maplibre.org/maplibre-gl-js/docs/examples/change-building-color-based-on-zoom-level/)\n - [Create a heatmap layer](https://maplibre.org/maplibre-gl-js/docs/examples/heatmap-layer/)\n - [Visualize population density](https://maplibre.org/maplibre-gl-js/docs/examples/visualize-population-density/)", + "example": { + "syntax": { + "method": ["[\"linear\"] | [\"exponential\", base] | [\"cubic-bezier\", x1, y1, x2, y2]", "number", "number", "number", "..."], + "result": "number | array | color" + }, + "value": ["interpolate", ["linear"], ["zoom"], 15, 0, 15.05, ["get", "height"]] + }, "group": "Ramps, scales, curves", "sdk-support": { "basic functionality": { "js": "0.42.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "interpolate-hcl": { "doc": "Produces continuous, smooth results by interpolating between pairs of input and output values (\"stops\"). Works like `interpolate`, but the output type must be `color`, and the interpolation is performed in the Hue-Chroma-Luminance color space.", + "example": { + "syntax": { + "method": ["[\"linear\"] | [\"exponential\", base] | [\"cubic-bezier\", x1, y1, x2, y2]", "number", "number", "number", "..."], + "result": "color" + }, + "value": ["interpolate-hcl", ["linear"], ["zoom"], 15, "#f00", 15.05, "#00f"] + }, "group": "Ramps, scales, curves", "sdk-support": { "basic functionality": { @@ -2668,6 +2969,13 @@ }, "interpolate-lab": { "doc": "Produces continuous, smooth results by interpolating between pairs of input and output values (\"stops\"). Works like `interpolate`, but the output type must be `color`, and the interpolation is performed in the CIELAB color space.", + "example": { + "syntax": { + "method": ["[\"linear\"] | [\"exponential\", base] | [\"cubic-bezier\", x1, y1, x2, y2]", "number", "number", "number", "..."], + "result": "color" + }, + "value": ["interpolate-lab", ["linear"], ["zoom"], 15, "#f00", 15.05, "#00f"] + }, "group": "Ramps, scales, curves", "sdk-support": { "basic functionality": { @@ -2677,158 +2985,231 @@ }, "ln2": { "doc": "Returns mathematical constant ln(2).", + "example": { + "syntax": { + "method": [], + "result": "number" + }, + "value": ["ln2"] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "pi": { "doc": "Returns the mathematical constant pi.", + "example": { + "syntax": { + "method": [], + "result": "number" + }, + "value": ["pi"] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "e": { "doc": "Returns the mathematical constant e.", + "example": { + "syntax": { + "method": [], + "result": "number" + }, + "value": ["e"] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "typeof": { "doc": "Returns a string describing the type of the given value.", + "example": { + "syntax": { + "method": ["value"], + "result": "string" + }, + "value": ["typeof", ["get", "name"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "string": { "doc": "Asserts that the input value is a string. If multiple values are provided, each one is evaluated in order until a string is obtained. If none of the inputs are strings, the expression is an error.", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "string" + }, + "value": ["string", ["get", "name"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "number": { "doc": "Asserts that the input value is a number. If multiple values are provided, each one is evaluated in order until a number is obtained. If none of the inputs are numbers, the expression is an error.", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "number" + }, + "value": ["number", ["get", "population"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "boolean": { - "doc": "Asserts that the input value is a boolean. If multiple values are provided, each one is evaluated in order until a boolean is obtained. If none of the inputs are booleans, the expression is an error.", + "doc": "Asserts that the input value is a boolean. If multiple values are provided, each one is evaluated in order until a boolean is obtained. If none of the inputs are booleans, the expression is an error.\n\n - [Create a hover effect](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/)", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "boolean" + }, + "value": ["boolean", ["feature-state", "hover"], false] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "object": { "doc": "Asserts that the input value is an object. If multiple values are provided, each one is evaluated in order until an object is obtained. If none of the inputs are objects, the expression is an error.", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "object" + }, + "value": ["object", ["get", "some-property"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "collator": { "doc": "Returns a `collator` for use in locale-dependent comparison operations. The `case-sensitive` and `diacritic-sensitive` options default to `false`. The `locale` argument specifies the IETF language tag of the locale to use. If none is provided, the default locale is used. If the requested locale is not available, the `collator` will use a system-defined fallback locale. Use `resolved-locale` to test the results of locale fallback behavior.", + "example": { + "syntax": { + "method": ["collator", "{ \"case-sensitive\": boolean, \"diacritic-sensitive\": boolean, \"locale\": string }"], + "result": "collator" + }, + "value": ["collator", {"case-sensitive": true, "diacritic-sensitive": true, "locale": "fr"}] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, "format": { - "doc": "Returns `formatted` text containing annotations for use in mixed-format `text-field` entries. For a `text-field` entries of a string type, following option object's properties are supported: If set, the `text-font` value overrides the font specified by the root layout properties. If set, the `font-scale` value specifies a scaling factor relative to the `text-size` specified in the root layout properties. If set, the `text-color` value overrides the color specified by the root paint properties for this layer.", + "doc": "Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#image) expression. Strings may be followed by a style override object that supports the following properties:\n- `\"text-font\"`: Overrides the font stack specified by the root layout property.\n- `\"text-color\"`: Overrides the color specified by the root paint property.\n- `\"font-scale\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)", + "example": { + "syntax": { + "method": ["value", "{ \"text-font\": string, \"text-color\": color, \"font-scale\": number }", "..."], + "result": "formatted" + }, + "value": ["format", ["upcase", ["get", "FacilityName"]], {"font-scale": 0.8}, "\n", {}, ["downcase", ["get", "Comments"]], {"font-scale": 0.6}] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.48.0", "android": "6.7.0", - "ios": "4.6.0", - "macos": "0.12.0" + "ios": "4.6.0" }, "text-font": { "js": "0.48.0", "android": "6.7.0", - "ios": "4.6.0", - "macos": "0.12.0" + "ios": "4.6.0" }, "font-scale": { "js": "0.48.0", "android": "6.7.0", - "ios": "4.6.0", - "macos": "0.12.0" + "ios": "4.6.0" }, "text-color": { "js": "1.3.0", "android": "7.3.0", - "ios": "4.10.0", - "macos": "0.14.0" + "ios": "4.10.0" }, "image": { - "js": "1.6.0" + "js": "1.6.0", + "android": "8.6.0", + "ios": "5.7.0" } } }, "image": { - "doc": "Returns an `image` type for use in `icon-image`, `*-pattern` entries and as a section in the `format` expression. If set, the `image` argument will check that the requested image exists in the style and will return either the resolved image name or `null`, depending on whether or not the image is currently in the style. This validation process is synchronous and requires the image to have been added to the style before requesting it in the `image` argument.", + "doc": "Returns an `image` type for use in `icon-image`, `*-pattern` entries and as a section in the `format` expression. If set, the `image` argument will check that the requested image exists in the style and will return either the resolved image name or `null`, depending on whether or not the image is currently in the style. This validation process is synchronous and requires the image to have been added to the style before requesting it in the `image` argument.\n\n - [Use a fallback image](https://maplibre.org/maplibre-gl-js/docs/examples/fallback-image/)", + "example": { + "syntax": { + "method": ["value"], + "result": "image" + }, + "value": ["image", "marker_15"] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "1.4.0", "android": "8.6.0", - "ios": "5.6.0" + "ios": "5.7.0" } } }, "number-format": { - "doc": "Converts the input number into a string representation using the providing formatting rules. If set, the `locale` argument specifies the locale to use, as a BCP 47 language tag. If set, the `currency` argument specifies an ISO 4217 code to use for currency-style formatting. If set, the `min-fraction-digits` and `max-fraction-digits` arguments specify the minimum and maximum number of fractional digits to include.", + "doc": "Converts the input number into a string representation using the providing formatting rules. If set, the `locale` argument specifies the locale to use, as a BCP 47 language tag. If set, the `currency` argument specifies an ISO 4217 code to use for currency-style formatting. If set, the `min-fraction-digits` and `max-fraction-digits` arguments specify the minimum and maximum number of fractional digits to include.\n\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["number", "{ \"locale\": string, \"currency\": string, \"min-fraction-digits\": number, \"max-fraction-digits\": number }"], + "result": "string" + }, + "value": ["number-format", ["get", "mag"], {"min-fraction-digits": 1, "max-fraction-digits": 1}] + }, "group": "Types", "sdk-support": { "basic functionality": { @@ -2837,139 +3218,212 @@ } }, "to-string": { - "doc": "Converts the input value to a string. If the input is `null`, the result is `\"\"`. If the input is a boolean, the result is `\"true\"` or `\"false\"`. If the input is a number, it is converted to a string as specified by the [\"NumberToString\" algorithm](https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type) of the ECMAScript Language Specification. If the input is a color, it is converted to a string of the form `\"rgba(r,g,b,a)\"`, where `r`, `g`, and `b` are numerals ranging from 0 to 255, and `a` ranges from 0 to 1. Otherwise, the input is converted to a string in the format specified by the [`JSON.stringify`](https://tc39.github.io/ecma262/#sec-json.stringify) function of the ECMAScript Language Specification.", + "doc": "Converts the input value to a string. If the input is `null`, the result is `\"\"`. If the input is a boolean, the result is `\"true\"` or `\"false\"`. If the input is a number, it is converted to a string as specified by the [\"NumberToString\" algorithm](https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type) of the ECMAScript Language Specification. If the input is a color, it is converted to a string of the form `\"rgba(r,g,b,a)\"`, where `r`, `g`, and `b` are numerals ranging from 0 to 255, and `a` ranges from 0 to 1. Otherwise, the input is converted to a string in the format specified by the [`JSON.stringify`](https://tc39.github.io/ecma262/#sec-json.stringify) function of the ECMAScript Language Specification.\n\n - [Create a time slider](https://maplibre.org/maplibre-gl-js/docs/examples/timeline-animation/)", + "example": { + "syntax": { + "method": ["value"], + "result": "string" + }, + "value": ["to-string", ["get", "mag"]] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "to-number": { "doc": "Converts the input value to a number, if possible. If the input is `null` or `false`, the result is 0. If the input is `true`, the result is 1. If the input is a string, it is converted to a number as specified by the [\"ToNumber Applied to the String Type\" algorithm](https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type) of the ECMAScript Language Specification. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "number" + }, + "value": ["to-number", "someProperty"] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "to-boolean": { "doc": "Converts the input value to a boolean. The result is `false` when then input is an empty string, 0, `false`, `null`, or `NaN`; otherwise it is `true`.", + "example": { + "syntax": { + "method": ["value"], + "result": "boolean" + }, + "value": ["to-boolean", "someProperty"] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "to-rgba": { "doc": "Returns a four-element array containing the input color's red, green, blue, and alpha components, in that order.", + "example": { + "syntax": { + "method": ["color"], + "result": "array" + }, + "value": ["to-rgba", "#ff0000"] + }, "group": "Color", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "to-color": { - "doc": "Converts the input value to a color. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.", + "doc": "Converts the input value to a color. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.\n\n - [Visualize population density](https://maplibre.org/maplibre-gl-js/docs/examples/visualize-population-density/)", + "example": { + "syntax": { + "method": ["value", "fallback: value", "fallback: value", "..."], + "result": "color" + }, + "value": ["to-color", "#edf8e9"] + }, "group": "Types", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "rgb": { "doc": "Creates a color value from red, green, and blue components, which must range between 0 and 255, and an alpha component of 1. If any component is out of range, the expression is an error.", + "example": { + "syntax": { + "method": ["number", "number", "number"], + "result": "color" + }, + "value": ["rgb", 255, 0, 0] + }, "group": "Color", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "rgba": { "doc": "Creates a color value from red, green, blue components, which must range between 0 and 255, and an alpha component which must range between 0 and 1. If any component is out of range, the expression is an error.", + "example": { + "syntax": { + "method": ["number", "number", "number", "number"], + "result": "color" + }, + "value": ["rgba", 255, 0, 0, 1] + }, "group": "Color", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "get": { - "doc": "Retrieves a property value from the current feature's properties, or from another object if a second argument is provided. Returns null if the requested property is missing.", + "doc": "Retrieves a property value from the current feature's properties, or from another object if a second argument is provided. Returns null if the requested property is missing.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)\n - [Extrude polygons for 3D indoor mapping](https://maplibre.org/maplibre-gl-js/docs/examples/3d-extrusion-floorplan/)", + "example": { + "syntax": { + "method": ["string"], + "result": "value" + }, + "value": ["get", "someProperty"] + }, "group": "Lookup", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "has": { - "doc": "Tests for the presence of an property value in the current feature's properties, or from another object if a second argument is provided.", + "doc": "Tests for the presence of an property value in the current feature's properties, or from another object if a second argument is provided.\n\n - [Create and style clusters](https://maplibre.org/maplibre-gl-js/docs/examples/cluster/)", + "example": { + "syntax": { + "method": ["string"], + "result": "boolean" + }, + "value": ["has", "someProperty"] + }, "group": "Lookup", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "length": { - "doc": "Gets the length of an array or string.", + "doc": "Gets the length of an array or string. In a string, a UTF-16 surrogate pair counts as a single position.", + "example": { + "syntax": { + "method": ["array"], + "result": "number" + }, + "value": ["length", ["get", "myArray"]] + }, "group": "Lookup", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "properties": { "doc": "Gets the feature properties object. Note that in some cases, it may be more efficient to use [\"get\", \"property_name\"] directly.", + "example": { + "syntax": { + "method": [], + "result": "value" + }, + "value": ["properties"] + }, "group": "Feature data", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "feature-state": { - "doc": "Retrieves a property value from the current feature's state. Returns null if the requested property is not present on the feature's state. A feature's state is not part of the GeoJSON or vector tile data, and must be set programmatically on each feature. Features are identified by their `id` attribute, which must be an integer or a string that can be cast to an integer. Note that [\"feature-state\"] can only be used with paint properties that support data-driven styling.", + "doc": "Retrieves a property value from the current feature's state. Returns null if the requested property is not present on the feature's state. A feature's state is not part of the GeoJSON or vector tile data, and must be set programmatically on each feature. When `source.promoteId` is not provided, features are identified by their `id` attribute, which must be an integer or a string that can be cast to an integer. When `source.promoteId` is provided, features are identified by their `promoteId` property, which may be a number, string, or any primitive data type. Note that [\"feature-state\"] can only be used with paint properties that support data-driven styling.\n\n - [Create a hover effect](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/)", + "example": { + "syntax": { + "method": ["string"], + "result": "value" + }, + "value": ["feature-state", "hover"] + }, "group": "Feature data", "sdk-support": { "basic functionality": { @@ -2978,67 +3432,104 @@ } }, "geometry-type": { - "doc": "Gets the feature's geometry type: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon.", + "doc": "Gets the feature's geometry type: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`.", + "example": { + "syntax": { + "method": [], + "result": "string" + }, + "value": ["==", ["geometry-type"], "Polygon"] + }, "group": "Feature data", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "id": { "doc": "Gets the feature's id, if it has one.", + "example": { + "syntax": { + "method": [], + "result": "value" + }, + "value": ["id"] + }, "group": "Feature data", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "zoom": { "doc": "Gets the current zoom level. Note that in style layout and paint properties, [\"zoom\"] may only appear as the input to a top-level \"step\" or \"interpolate\" expression.", + "example": { + "syntax": { + "method": [], + "result": "number" + }, + "value": ["interpolate",["linear"],["zoom"],15,0,15.05,["get","height"]] + }, "group": "Zoom", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "heatmap-density": { "doc": "Gets the kernel density estimation of a pixel in a heatmap layer, which is a relative measure of how many data points are crowded around a particular pixel. Can only be used in the `heatmap-color` property.", + "example": { + "syntax": { + "method": [], + "result": "number" + }, + "value": ["heatmap-density"] + }, "group": "Heatmap", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "line-progress": { "doc": "Gets the progress along a gradient line. Can only be used in the `line-gradient` property.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["line-progress", 0.5] + }, "group": "Feature data", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.6.0", - "macos": "0.12.0" + "ios": "4.6.0" } } }, "accumulated": { "doc": "Gets the value of a cluster property accumulated so far. Can only be used in the `clusterProperties` option of a clustered GeoJSON source.", + "example": { + "syntax": { + "method": ["string"], + "result": "value" + }, + "value": ["accumulated", "sum"] + }, "group": "Feature data", "sdk-support": { "basic functionality": { @@ -3048,414 +3539,637 @@ }, "+": { "doc": "Returns the sum of the inputs.", + "example": { + "syntax": { + "method": ["number", "number", "..."], + "result": "number" + }, + "value": ["+", 2, 3] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "*": { "doc": "Returns the product of the inputs.", + "example": { + "syntax": { + "method": ["number", "number", "..."], + "result": "number" + }, + "value": ["*", 2, 3] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "-": { "doc": "For two inputs, returns the result of subtracting the second input from the first. For a single input, returns the result of subtracting it from 0.", + "example": { + "syntax": { + "method": ["number", "number?"], + "result": "number" + }, + "value": ["-", 10] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "/": { - "doc": "Returns the result of floating point division of the first input by the second.", + "doc": "Returns the result of floating point division of the first input by the second.\n\n - [Visualize population density](https://maplibre.org/maplibre-gl-js/docs/examples/visualize-population-density/)", + "example": { + "syntax": { + "method": ["number", "number"], + "result": "number" + }, + "value": ["/", ["get", "population"], ["get", "sq-km"]] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "%": { "doc": "Returns the remainder after integer division of the first input by the second.", + "example": { + "syntax": { + "method": ["number", "number"], + "result": "number" + }, + "value": ["%", 10, 3] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "^": { "doc": "Returns the result of raising the first input to the power specified by the second.", + "example": { + "syntax": { + "method": ["number", "number"], + "result": "number" + }, + "value": ["^", 2, 3] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "sqrt": { "doc": "Returns the square root of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["sqrt", 9] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.42.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "log10": { "doc": "Returns the base-ten logarithm of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["log10", 8] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "ln": { "doc": "Returns the natural logarithm of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["ln", 8] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "log2": { "doc": "Returns the base-two logarithm of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["log2", 8] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "sin": { "doc": "Returns the sine of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["sin", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "cos": { "doc": "Returns the cosine of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["cos", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "tan": { "doc": "Returns the tangent of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["tan", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "asin": { "doc": "Returns the arcsine of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["asin", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "acos": { "doc": "Returns the arccosine of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["acos", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "atan": { "doc": "Returns the arctangent of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["atan", 1] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "min": { "doc": "Returns the minimum value of the inputs.", + "example": { + "syntax": { + "method": ["number", "number", "..."], + "result": "number" + }, + "value": ["min", 1, 2] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "max": { "doc": "Returns the maximum value of the inputs.", + "example": { + "syntax": { + "method": ["number", "number", "..."], + "result": "number" + }, + "value": ["max", 1, 2] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "round": { "doc": "Rounds the input to the nearest integer. Halfway values are rounded away from zero. For example, `[\"round\", -1.5]` evaluates to -2.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["round", 1.5] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "abs": { "doc": "Returns the absolute value of the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["abs", -1.5] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "ceil": { "doc": "Returns the smallest integer that is greater than or equal to the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["ceil", 1.5] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "floor": { "doc": "Returns the largest integer that is less than or equal to the input.", + "example": { + "syntax": { + "method": ["number"], + "result": "number" + }, + "value": ["floor", 1.5] + }, "group": "Math", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" + } + } + }, + "distance": { + "doc": "Returns the shortest distance in meters between the evaluated feature and the input geometry. The input value can be a valid GeoJSON of type `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection`. Distance values returned may vary in precision due to loss in precision from encoding geometries, particularly below zoom level 13.", + "example": { + "syntax": { + "method": ["GeoJSON geometry"], + "result": "number" + }, + "value": ["distance", { "type": "Point", "coordinates": [0, 0]}] + }, + "group": "Math", + "sdk-support": { + "basic functionality": { + "js": "4.2.0", + "android": "9.2.0", + "ios": "5.9.0" } } }, "==": { - "doc": "Returns `true` if the input values are equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "doc": "Returns `true` if the input values are equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\n\n - [Add multiple geometries from one GeoJSON source](https://maplibre.org/maplibre-gl-js/docs/examples/multiple-geometries/)\n - [Create a time slider](https://maplibre.org/maplibre-gl-js/docs/examples/timeline-animation/)\n - [Display buildings in 3D](https://maplibre.org/maplibre-gl-js/docs/examples/3d-buildings/)\n - [Filter symbols by toggling a list](https://maplibre.org/maplibre-gl-js/docs/examples/filter-markers/)", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": ["==", "$type", "Polygon"] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, "!=": { - "doc": "Returns `true` if the input values are not equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "doc": "Returns `true` if the input values are not equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\n\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": ["!=", "cluster", true] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, ">": { "doc": "Returns `true` if the first input is strictly greater than the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": [">", ["get", "mag"], 2] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, "<": { - "doc": "Returns `true` if the first input is strictly less than the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "doc": "Returns `true` if the first input is strictly less than the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\n\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": ["<", ["get", "mag"], 2] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, ">=": { - "doc": "Returns `true` if the first input is greater than or equal to the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "doc": "Returns `true` if the first input is greater than or equal to the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\n\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": [">=", ["get", "mag"], 6] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, "<=": { "doc": "Returns `true` if the first input is less than or equal to the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": ["<=", ["get", "mag"], 6] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "collator": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } }, "all": { - "doc": "Returns `true` if all the inputs are `true`, `false` otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to `false`, the result is `false` and no further input expressions are evaluated.", + "doc": "Returns `true` if all the inputs are `true`, `false` otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to `false`, the result is `false` and no further input expressions are evaluated.\n\n - [Display HTML clusters with custom properties](https://maplibre.org/maplibre-gl-js/docs/examples/cluster-html/)", + "example": { + "syntax": { + "method": ["boolean", "boolean", "..."], + "result": "boolean" + }, + "value": ["all", [">=", ["get", "mag"], 4], ["<", ["get", "mag"], 5]] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "any": { "doc": "Returns `true` if any of the inputs are `true`, `false` otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to `true`, the result is `true` and no further input expressions are evaluated.", + "example": { + "syntax": { + "method": ["boolean", "boolean", "..."], + "result": "boolean" + }, + "value": ["any", [">=", ["get", "mag"], 4], ["<", ["get", "mag"], 5]] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "!": { - "doc": "Logical negation. Returns `true` if the input is `false`, and `false` if the input is `true`.", + "doc": "Logical negation. Returns `true` if the input is `false`, and `false` if the input is `true`.\n\n - [Create and style clusters](https://maplibre.org/maplibre-gl-js/docs/examples/cluster/)", + "example": { + "syntax": { + "method": ["value", "value", "collator?"], + "result": "boolean" + }, + "value": ["!", ["has", "point_count"]] + }, "group": "Decision", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" + } + } + }, + "within": { + "doc": "Returns `true` if the evaluated feature is fully contained inside a boundary of the input geometry, `false` otherwise. The input value can be a valid GeoJSON of type `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection`. Supported features for evaluation:\n- `Point`: Returns `false` if a point is on the boundary or falls outside the boundary.\n- `LineString`: Returns `false` if any part of a line falls outside the boundary, the line intersects the boundary, or a line's endpoint is on the boundary.", + "example": { + "syntax": { + "method": ["GeoJSON geometry"], + "result": "boolean" + }, + "value": ["within", {"type": "Polygon","coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]]}] + }, + "group": "Decision", + "sdk-support": { + "basic functionality": { + "js": "1.9.0", + "android": "9.1.0", + "ios": "5.8.0" } } }, "is-supported-script": { - "doc": "Returns `true` if the input string is expected to render legibly. Returns `false` if the input string contains sections that cannot be rendered without potential loss of meaning (e.g. Indic scripts that require complex text shaping, or right-to-left scripts if the the `mapbox-gl-rtl-text` plugin is not in use in Mapbox GL JS).", + "doc": "Returns `true` if the input string is expected to render legibly. Returns `false` if the input string contains sections that cannot be rendered without potential loss of meaning (e.g. Indic scripts that require complex text shaping, or right-to-left scripts if the the `mapbox-gl-rtl-text` plugin is not in use in MapLibre GL JS).", + "example": { + "syntax": { + "method": ["string"], + "result": "boolean" + }, + "value": ["is-supported-script", "दिल्ली"] + }, "group": "String", "sdk-support": { "basic functionality": { @@ -3465,50 +4179,77 @@ } }, "upcase": { - "doc": "Returns the input string converted to uppercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.", + "doc": "Returns the input string converted to uppercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)", + "example": { + "syntax": { + "method": ["string"], + "result": "string" + }, + "value": ["upcase", ["get", "name"]] + }, "group": "String", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "downcase": { - "doc": "Returns the input string converted to lowercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.", + "doc": "Returns the input string converted to lowercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)", + "example": { + "syntax": { + "method": ["string"], + "result": "string" + }, + "value": ["downcase", ["get", "name"]] + }, "group": "String", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "concat": { - "doc": "Returns a `string` consisting of the concatenation of the inputs. Each input is converted to a string as if by `to-string`.", + "doc": "Returns a `string` consisting of the concatenation of the inputs. Each input is converted to a string as if by `to-string`.\n\n - [Add a generated icon to the map](https://maplibre.org/maplibre-gl-js/docs/examples/add-image-missing-generated/)\n - [Create a time slider](https://maplibre.org/maplibre-gl-js/docs/examples/timeline-animation/)\n - [Use a fallback image](https://maplibre.org/maplibre-gl-js/docs/examples/fallback-image/)\n - [Variable label placement](https://maplibre.org/maplibre-gl-js/docs/examples/variable-label-placement/)", + "example": { + "syntax": { + "method": ["string", "string", "..."], + "result": "string" + }, + "value": ["concat", "square-rgb-", ["get", "color"]] + }, "group": "String", "sdk-support": { "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } } }, "resolved-locale": { "doc": "Returns the IETF language tag of the locale being used by the provided `collator`. This can be used to determine the default system locale, or to determine if a requested locale was successfully loaded.", + "example": { + "syntax": { + "method": ["collator"], + "result": "string" + }, + "value": ["resolved-locale", [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "de"} + ]] + }, "group": "String", "sdk-support": { "basic functionality": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } } } @@ -3540,8 +4281,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } } }, @@ -3572,8 +4312,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } } }, @@ -3593,8 +4332,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } } }, @@ -3616,8 +4354,146 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" + } + } + } + }, + "sky": { + "sky-color": { + "type": "color", + "property-type": "data-constant", + "default": "#88C6FC", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The base color for the sky." + }, + "horizon-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The base color at the horizon." + }, + "fog-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The base color for the fog. Requires 3D terrain." + }, + "fog-ground-blend": { + "type": "number", + "property-type": "data-constant", + "default": 0.5, + "minimum": 0, + "maximum": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "How to blend the fog over the 3D terrain. Where 0 is the map center and 1 is the horizon." + }, + "horizon-fog-blend": { + "type": "number", + "property-type": "data-constant", + "default": 0.8, + "minimum": 0, + "maximum": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "How to blend the fog color and the horizon color. Where 0 is using the horizon color only and 1 is using the fog color only." + }, + "sky-horizon-blend": { + "type": "number", + "property-type": "data-constant", + "default": 0.8, + "minimum": 0, + "maximum": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "How to blend the the sky color and the horizon color. Where 1 is blending the color at the middle of the sky and 0 is not blending at all and using the sky color only." + }, + "atmosphere-blend": { + "type": "number", + "property-type": "data-constant", + "default": 0.8, + "minimum": 0, + "maximum": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "How to blend the atmosphere. Where 1 is visible atmosphere and 0 is hidden. It is best to interpolate this expression when using globe projection." + } + }, + "terrain": { + "source": { + "type": "string", + "doc": "The source for the terrain data.", + "required": true, + "sdk-support": { + "basic functionality": { + "js": "2.2.0" + } + } + }, + "exaggeration": { + "type": "number", + "minimum": 0, + "doc": "The exaggeration of the terrain - how high it will look.", + "default": 1.0, + "sdk-support": { + "basic functionality": { + "js": "2.2.0" + } + } + } + }, + "projection": { + "type": { + "type": "enum", + "doc": "The projection type.", + "default": "mercator", + "values": { + "mercator": { + "doc": "The Mercator projection." + }, + "globe": { + "doc": "The globe projection." } } } @@ -3642,8 +4518,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -3665,14 +4540,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.21.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -3699,14 +4572,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.19.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -3735,14 +4606,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.19.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -3770,8 +4639,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -3801,8 +4669,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -3821,13 +4688,11 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.49.0", "android": "6.5.0", - "macos": "0.11.0", "ios": "4.4.0" } }, @@ -3853,8 +4718,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -3879,14 +4743,12 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" }, "data-driven styling": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -3914,8 +4776,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -3945,8 +4806,7 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -3965,13 +4825,11 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" }, "data-driven styling": { "js": "0.49.0", "android": "6.5.0", - "macos": "0.11.0", "ios": "4.4.0" } }, @@ -3995,14 +4853,12 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" }, "data-driven styling": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -4029,14 +4885,12 @@ "basic functionality": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" }, "data-driven styling": { "js": "0.27.0", "android": "5.1.0", - "ios": "3.6.0", - "macos": "0.5.0" + "ios": "3.6.0" } }, "expression": { @@ -4057,8 +4911,7 @@ "sdk-support": { "basic functionality": { "js": "0.50.0", - "ios": "4.7.0", - "macos": "0.13.0" + "ios": "4.7.0" } }, "expression": { @@ -4082,14 +4935,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4116,14 +4967,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.23.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4151,8 +5000,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -4182,8 +5030,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -4205,14 +5052,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.39.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -4236,14 +5081,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4266,14 +5109,12 @@ "basic functionality": { "js": "0.12.1", "android": "3.0.0", - "ios": "3.1.0", - "macos": "0.1.0" + "ios": "3.1.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4297,14 +5138,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4333,8 +5172,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": {} }, @@ -4354,13 +5192,11 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.49.0", "android": "6.5.0", - "macos": "0.11.0", "ios": "4.4.0" } }, @@ -4395,8 +5231,7 @@ "basic functionality": { "js": "0.45.0", "android": "6.5.0", - "ios": "4.4.0", - "macos": "0.11.0" + "ios": "4.4.0" }, "data-driven styling": {} }, @@ -4421,14 +5256,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.18.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4450,14 +5283,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.18.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4479,14 +5310,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.20.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4510,14 +5339,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.20.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4545,8 +5372,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -4576,8 +5402,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -4604,8 +5429,7 @@ "basic functionality": { "js": "0.21.0", "android": "4.2.0", - "ios": "3.4.0", - "macos": "0.2.1" + "ios": "3.4.0" } }, "expression": { @@ -4632,8 +5456,7 @@ "basic functionality": { "js": "0.39.0", "android": "5.2.0", - "ios": "3.7.0", - "macos": "0.6.0" + "ios": "3.7.0" } }, "expression": { @@ -4655,14 +5478,12 @@ "basic functionality": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4684,14 +5505,12 @@ "basic functionality": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4715,14 +5534,12 @@ "basic functionality": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" }, "data-driven styling": { "js": "0.29.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4748,14 +5565,12 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "data-driven styling": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -4778,14 +5593,12 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "data-driven styling": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -4808,8 +5621,7 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -4849,8 +5661,7 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" }, "data-driven styling": {} }, @@ -4873,8 +5684,7 @@ "basic functionality": { "js": "0.41.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -4901,14 +5711,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4925,7 +5733,7 @@ "type": "color", "default": "#000000", "transition": true, - "doc": "The color of the icon. This can only be used with sdf icons.", + "doc": "The color of the icon. This can only be used with SDF icons.", "requires": [ "icon-image" ], @@ -4933,14 +5741,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4965,14 +5771,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -4991,7 +5795,7 @@ "minimum": 0, "transition": true, "units": "pixels", - "doc": "Distance of halo to the icon outline.", + "doc": "Distance of halo to the icon outline. \nThe unit is in pixels only for SDF sprites that were created with a blur radius of 8, multiplied by the display density. I.e., the radius needs to be 16 for `@2x` sprites, etc.", "requires": [ "icon-image" ], @@ -4999,14 +5803,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5033,14 +5835,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5071,8 +5871,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5103,8 +5902,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5129,14 +5927,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5162,14 +5958,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5194,14 +5988,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5228,14 +6020,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5262,14 +6052,12 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": { "js": "0.33.0", "android": "5.0.0", - "ios": "3.5.0", - "macos": "0.4.0" + "ios": "3.5.0" } }, "expression": { @@ -5300,8 +6088,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5332,8 +6119,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5357,8 +6143,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5380,8 +6165,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5403,8 +6187,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5426,8 +6209,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5449,8 +6231,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5472,8 +6253,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5500,8 +6280,7 @@ "basic functionality": { "js": "0.47.0", "android": "6.3.0", - "ios": "4.2.0", - "macos": "0.9.0" + "ios": "4.2.0" } }, "expression": { @@ -5518,13 +6297,12 @@ "minimum": 0, "transition": false, "units": "milliseconds", - "doc": "Fade duration when a new tile is added.", + "doc": "Fade duration when a new tile is added, or when a video is started or its coordinates are updated.", "sdk-support": { "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5548,8 +6326,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5576,8 +6353,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5599,8 +6375,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5620,8 +6395,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5641,8 +6415,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5662,8 +6435,7 @@ "basic functionality": { "js": "0.43.0", "android": "6.0.0", - "ios": "4.0.0", - "macos": "0.7.0" + "ios": "4.0.0" } }, "expression": { @@ -5690,8 +6462,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { @@ -5710,8 +6481,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" }, "data-driven styling": {} }, @@ -5734,8 +6504,7 @@ "basic functionality": { "js": "0.10.0", "android": "2.0.1", - "ios": "2.0.0", - "macos": "0.1.0" + "ios": "2.0.0" } }, "expression": { diff --git a/scripts/style-spec.mjs b/scripts/style-spec.mjs index 2d497938a..f2f5299d7 100644 --- a/scripts/style-spec.mjs +++ b/scripts/style-spec.mjs @@ -1,184 +1,204 @@ -import referenceSpec from "../scripts/style-spec-reference/v8.json" with { type: "json" }; +import referenceSpec from './style-spec-reference/v8.json' with { type: "json" }; + +// https://github.com/maplibre/maplibre-native/issues/2368 +referenceSpec['layout_symbol']['icon-padding']['type'] = 'number'; +// @ts-ignore +referenceSpec['layout_symbol']['icon-padding']['default'] = 2; + +// https://github.com/maplibre/maplibre-native/issues/2754 +referenceSpec['layout_symbol']['icon-padding']['property-type'] = 'data constant'; /** @type {any} */ let modifiedReferenceSpec = referenceSpec; +// https://github.com/maplibre/maplibre-native/issues/250 +delete modifiedReferenceSpec['layout_symbol']['text-rotation-alignment']["values"]['viewport-glyph'] + +// https://github.com/maplibre/maplibre-native/issues/2358 +delete modifiedReferenceSpec['layout_symbol']['text-variable-anchor-offset']; + +// https://github.com/maplibre/maplibre-native/issues/251 +delete modifiedReferenceSpec['layout_symbol']['icon-overlap']; +delete modifiedReferenceSpec['layout_symbol']['text-overlap']; +modifiedReferenceSpec["layout_symbol"]["text-allow-overlap"]["requires"] = referenceSpec["layout_symbol"]["text-allow-overlap"]["requires"].filter(val => JSON.stringify(val) !== '{"!":"text-overlap"}'); +modifiedReferenceSpec["layout_symbol"]["text-allow-overlap"]["requires"] = referenceSpec["layout_symbol"]["icon-allow-overlap"]["requires"].filter(val => JSON.stringify(val) !== '{"!":"icon-overlap"}'); + modifiedReferenceSpec.layer.type.values["location-indicator"] = {}; modifiedReferenceSpec["layout_location-indicator"] = { - "top-image": { - "type": "resolvedImage", - "property-type": "data-constant", - "expression": { - "interpolated": false, - "parameters": [ - "zoom" - ] - }, - "doc": "Name of image in sprite to use as the top of the location indicator." - }, - "bearing-image": { - "type": "resolvedImage", - "property-type": "data-constant", - "expression": { - "interpolated": false, - "parameters": [ - "zoom" - ] - }, - "doc": "Name of image in sprite to use as the middle of the location indicator." - }, - "shadow-image": { - "type": "resolvedImage", - "property-type": "data-constant", - "expression": { - "interpolated": false, - "parameters": [ - "zoom" - ] - }, - "doc": "Name of image in sprite to use as the background of the location indicator." - } + "top-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the top of the location indicator." + }, + "bearing-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the middle of the location indicator." + }, + "shadow-image": { + "type": "resolvedImage", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ + "zoom" + ] + }, + "doc": "Name of image in sprite to use as the background of the location indicator." + } }; modifiedReferenceSpec["paint_location-indicator"] = { - "perspective-compensation": { - "type": "number", - "default": "0.85", - "property-type": "data-constant", - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "doc": "The amount of the perspective compensation, between 0 and 1. A value of 1 produces a location indicator of constant width across the screen. A value of 0 makes it scale naturally according to the viewing projection." - }, - "image-tilt-displacement": { - "type": "number", - "property-type": "data-constant", - "default": "0", - "units": "pixels", - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "doc": "The displacement off the center of the top image and the shadow image when the pitch of the map is greater than 0. This helps producing a three-dimensional appearence." - }, - "bearing": { - "type": "number", - "default": 0, - "period": 360, - "units": "degrees", - "property-type": "data-constant", - "expression": { - "interpolated": false, - "parameters": [ ] - }, - "transition": true, - "doc": "The bearing of the location indicator." - }, - "location": { - "type": "array", - "default": [ - 0.0, - 0.0, - 0.0 - ], - "length": 3, - "value": "number", - "property-type": "data-constant", - "expression": { - "interpolated": true, - "parameters": [] - }, - "transition": true, - "doc": "An array of [latitude, longitude, altitude] position of the location indicator." - }, - "accuracy-radius": { - "type": "number", - "units": "meters", - "default": 0, - "property-type": "data-constant", - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The accuracy, in meters, of the position source used to retrieve the position of the location indicator." - }, - "top-image-size": { - "type": "number", - "units": "factor of the original icon size", - "property-type": "data-constant", - "default": 1, - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The size of the top image, as a scale factor applied to the size of the specified image." - }, - "bearing-image-size": { - "type": "number", - "units": "factor of the original icon size", - "property-type": "data-constant", - "default": 1, - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The size of the bearing image, as a scale factor applied to the size of the specified image." - }, - "shadow-image-size": { - "type": "number", - "units": "factor of the original icon size", - "property-type": "data-constant", - "default": 1, - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The size of the shadow image, as a scale factor applied to the size of the specified image." - }, - "accuracy-radius-color": { - "type": "color", - "property-type": "data-constant", - "default": "#ffffff", - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The color for drawing the accuracy radius, as a circle. To adjust transparency, set the alpha component of the color accordingly." + "perspective-compensation": { + "type": "number", + "default": "0.85", + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "doc": "The amount of the perspective compensation, between 0 and 1. A value of 1 produces a location indicator of constant width across the screen. A value of 0 makes it scale naturally according to the viewing projection." + }, + "image-tilt-displacement": { + "type": "number", + "property-type": "data-constant", + "default": "0", + "units": "pixels", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "doc": "The displacement off the center of the top image and the shadow image when the pitch of the map is greater than 0. This helps producing a three-dimensional appearence." + }, + "bearing": { + "type": "number", + "default": 0, + "period": 360, + "units": "degrees", + "property-type": "data-constant", + "expression": { + "interpolated": false, + "parameters": [ ] + }, + "transition": true, + "doc": "The bearing of the location indicator." + }, + "location": { + "type": "array", + "default": [ + 0.0, + 0.0, + 0.0 + ], + "length": 3, + "value": "number", + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [] + }, + "transition": true, + "doc": "An array of [latitude, longitude, altitude] position of the location indicator." + }, + "accuracy-radius": { + "type": "number", + "units": "meters", + "default": 0, + "property-type": "data-constant", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The accuracy, in meters, of the position source used to retrieve the position of the location indicator." + }, + "top-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the top image, as a scale factor applied to the size of the specified image." + }, + "bearing-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the bearing image, as a scale factor applied to the size of the specified image." + }, + "shadow-image-size": { + "type": "number", + "units": "factor of the original icon size", + "property-type": "data-constant", + "default": 1, + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The size of the shadow image, as a scale factor applied to the size of the specified image." + }, + "accuracy-radius-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The color for drawing the accuracy radius, as a circle. To adjust transparency, set the alpha component of the color accordingly." - }, - "accuracy-radius-border-color": { - "type": "color", - "property-type": "data-constant", - "default": "#ffffff", - "expression": { - "interpolated": true, - "parameters": [ - "zoom" - ] - }, - "transition": true, - "doc": "The color for drawing the accuracy radius border. To adjust transparency, set the alpha component of the color accordingly." - } + }, + "accuracy-radius-border-color": { + "type": "color", + "property-type": "data-constant", + "default": "#ffffff", + "expression": { + "interpolated": true, + "parameters": [ + "zoom" + ] + }, + "transition": true, + "doc": "The color for drawing the accuracy radius border. To adjust transparency, set the alpha component of the color accordingly." + } }; export default modifiedReferenceSpec; \ No newline at end of file diff --git a/test/BUILD.bazel b/test/BUILD.bazel index 94d2a64ea..2848fce98 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -87,4 +87,4 @@ cc_test( "tests", "//platform/linux:impl", ], -) \ No newline at end of file +)