diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..2b81149
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,57 @@
+name: Test
+
+# ユニットテストのゲート。
+#
+# これまで CI は api-surface.yml(公開 API の凍結)と deploy 系だけで、
+# **テストを走らせるワークフローが 1 つも無かった。** 凍結ゲートが見るのは
+# 型の形だけなので、シグネチャが同じまま中身が壊れる変更は素通りする。
+#
+# ブラウザを要する検証はここには入れない。`npm run smoke` は実 Chrome で
+# 全プロバイダを描画するもので、API キーと数分の実行時間を要する。CI に載せる
+# なら別ワークフロー・別トリガにすること。
+
+on:
+ pull_request:
+ types: [opened, reopened, synchronize, ready_for_review]
+ branches:
+ - main
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ if: github.event.pull_request.draft == false
+ runs-on: ubuntu-latest
+ name: Unit tests
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ submodules: recursive
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up Node
+ uses: actions/setup-node@v4
+ with:
+ # 各パッケージの `node --test "test/**/*.test.mjs"` は Node 21 からグロブを
+ # 展開する。20 ではパターンをそのままファイル名として探し、見つからずに落ちる。
+ node-version: 22
+ cache: npm
+
+ - name: Install
+ run: npm ci
+
+ # ワークスペース横断。各パッケージの `pretest` が自分の dist を作るので、
+ # ここで先に build する必要はない。
+ - name: Test
+ run: npm test
+
+ - name: Lint
+ run: npm run lint
diff --git a/.gitignore b/.gitignore
index 97d3ae6..3594ebe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,3 +81,10 @@ examples/reactnative-basic/android/.kotlin/
newkey.xcresult
ios-rest.xcresult
ios-final.xcresult
+
+# The vendored Rust renderer (wasm + its JS bindings) is a build artifact of the
+# mapconductor-vectortile repo, copied in by its scripts/sync-sdk.sh. It is
+# tracked on purpose: the package cannot be built or published without it, the
+# same way android-vectortile tracks its .so and ios-vectortile its XCFramework.
+!react-vectortile/vendor/
+!react-vectortile/vendor/**
diff --git a/.gitmodules b/.gitmodules
index 173269e..ad590b5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -88,3 +88,6 @@
[submodule "react-icons-weather"]
path = react-icons-weather
url = git@github.com:MapConductor/react-icons-weather.git
+[submodule "react-kml"]
+ path = react-kml
+ url = git@github.com:MapConductor/react-kml.git
diff --git a/examples/basic/package.json b/examples/basic/package.json
index 5f793e1..e6356e9 100644
--- a/examples/basic/package.json
+++ b/examples/basic/package.json
@@ -31,6 +31,8 @@
"@mapconductor/react-heatmap": "*",
"@mapconductor/react-icons": "*",
"@mapconductor/react-marker-clustering": "*",
+ "@mapconductor/react-vectorstyle": "*",
+ "@mapconductor/react-vectortile": "*",
"@zip.js/zip.js": "^2.8.26",
"maplibre-gl": "^6.0.0",
"prism-react-renderer": "^2.4.1",
@@ -38,7 +40,8 @@
"react-dom": "^19.2.7",
"react-router-dom": "^7.18.0",
"three": "^0.185.1",
- "@mapconductor/react-for-mappls": "*"
+ "@mapconductor/react-for-mappls": "*",
+ "@mapconductor/react-for-deckgl": "*"
},
"devDependencies": {
"@types/react": "^19.2.17",
diff --git a/examples/basic/public/streettree/street-tree-style.json b/examples/basic/public/streettree/street-tree-style.json
new file mode 100644
index 0000000..dc67595
--- /dev/null
+++ b/examples/basic/public/streettree/street-tree-style.json
@@ -0,0 +1,2907 @@
+{
+ "version": 8,
+ "name": "OSM Bright JA — trimmed for street trees",
+ "metadata": {
+ "mapbox:autocomposite": false,
+ "mapbox:groups": {
+ "1444849242106.713": {
+ "collapsed": false,
+ "name": "Places"
+ },
+ "1444849334699.1902": {
+ "collapsed": true,
+ "name": "Bridges"
+ },
+ "1444849345966.4436": {
+ "collapsed": false,
+ "name": "Roads"
+ },
+ "1444849354174.1904": {
+ "collapsed": true,
+ "name": "Tunnels"
+ },
+ "1444849364238.8171": {
+ "collapsed": false,
+ "name": "Buildings"
+ },
+ "1444849382550.77": {
+ "collapsed": false,
+ "name": "Water"
+ },
+ "1444849388993.3071": {
+ "collapsed": false,
+ "name": "Land"
+ }
+ },
+ "mapbox:type": "template",
+ "openmaptiles:mapbox:owner": "openmaptiles",
+ "openmaptiles:mapbox:source:url": "mapbox://openmaptiles.4qljc88t",
+ "openmaptiles:version": "3.x",
+ "maputnik:renderer": "mbgljs"
+ },
+ "center": [
+ 0,
+ 0
+ ],
+ "zoom": 1,
+ "bearing": 0,
+ "pitch": 0,
+ "sources": {
+ "openmaptiles": {
+ "type": "vector",
+ "url": "https://tile.openstreetmap.jp/data/planet.json"
+ },
+ "takeshima": {
+ "type": "vector",
+ "url": "https://tile.openstreetmap.jp/data/takeshima.json"
+ },
+ "hoppo": {
+ "type": "vector",
+ "url": "https://tile.openstreetmap.jp/data/hoppo.json"
+ }
+ },
+ "sprite": "https://tile.openstreetmap.jp/styles/osm-bright-ja/sprite",
+ "glyphs": "https://tile.openstreetmap.jp/fonts/{fontstack}/{range}.pbf",
+ "layers": [
+ {
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#f8f4f0"
+ }
+ },
+ {
+ "id": "landcover-glacier",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849388993.3071"
+ },
+ "source": "openmaptiles",
+ "source-layer": "landcover",
+ "filter": [
+ "==",
+ "subclass",
+ "glacier"
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "#fff",
+ "fill-opacity": {
+ "base": 1,
+ "stops": [
+ [
+ 0,
+ 0.9
+ ],
+ [
+ 10,
+ 0.3
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "landcover-wood",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849388993.3071"
+ },
+ "source": "openmaptiles",
+ "source-layer": "landcover",
+ "filter": [
+ "==",
+ "class",
+ "wood"
+ ],
+ "paint": {
+ "fill-antialias": {
+ "base": 1,
+ "stops": [
+ [
+ 0,
+ false
+ ],
+ [
+ 9,
+ true
+ ]
+ ]
+ },
+ "fill-color": "#6a4",
+ "fill-opacity": 0.1,
+ "fill-outline-color": "hsla(0, 0%, 0%, 0.03)"
+ }
+ },
+ {
+ "id": "landcover-grass",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849388993.3071"
+ },
+ "source": "openmaptiles",
+ "source-layer": "landcover",
+ "filter": [
+ "==",
+ "class",
+ "grass"
+ ],
+ "paint": {
+ "fill-color": "#d8e8c8",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "waterway_tunnel",
+ "type": "line",
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "minzoom": 14,
+ "filter": [
+ "all",
+ [
+ "in",
+ "class",
+ "river",
+ "stream",
+ "canal"
+ ],
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-dasharray": [
+ 2,
+ 4
+ ],
+ "line-width": {
+ "base": 1.3,
+ "stops": [
+ [
+ 13,
+ 0.5
+ ],
+ [
+ 20,
+ 6
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "waterway-other",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "class",
+ "canal",
+ "river",
+ "stream"
+ ],
+ [
+ "==",
+ "intermittent",
+ 0
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.3,
+ "stops": [
+ [
+ 13,
+ 0.5
+ ],
+ [
+ 20,
+ 2
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "waterway-other-intermittent",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "class",
+ "canal",
+ "river",
+ "stream"
+ ],
+ [
+ "==",
+ "intermittent",
+ 1
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.3,
+ "stops": [
+ [
+ 13,
+ 0.5
+ ],
+ [
+ 20,
+ 2
+ ]
+ ]
+ },
+ "line-dasharray": [
+ 4,
+ 3
+ ]
+ }
+ },
+ {
+ "id": "waterway-stream-canal",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "in",
+ "class",
+ "canal",
+ "stream"
+ ],
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "intermittent",
+ 0
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.3,
+ "stops": [
+ [
+ 13,
+ 0.5
+ ],
+ [
+ 20,
+ 6
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "waterway-stream-canal-intermittent",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "in",
+ "class",
+ "canal",
+ "stream"
+ ],
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "intermittent",
+ 1
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.3,
+ "stops": [
+ [
+ 13,
+ 0.5
+ ],
+ [
+ 20,
+ 6
+ ]
+ ]
+ },
+ "line-dasharray": [
+ 4,
+ 3
+ ]
+ }
+ },
+ {
+ "id": "waterway-river",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "river"
+ ],
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "intermittent",
+ 0
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 10,
+ 0.8
+ ],
+ [
+ 20,
+ 6
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "waterway-river-intermittent",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "river"
+ ],
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "intermittent",
+ 1
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#a0c8f0",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 10,
+ 0.8
+ ],
+ [
+ 20,
+ 6
+ ]
+ ]
+ },
+ "line-dasharray": [
+ 3,
+ 2.5
+ ]
+ }
+ },
+ {
+ "id": "water-offset",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "water",
+ "maxzoom": 8,
+ "filter": [
+ "==",
+ "$type",
+ "Polygon"
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "#a0c8f0",
+ "fill-opacity": 1,
+ "fill-translate": {
+ "base": 1,
+ "stops": [
+ [
+ 6,
+ [
+ 2,
+ 0
+ ]
+ ],
+ [
+ 8,
+ [
+ 0,
+ 0
+ ]
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "water",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "water",
+ "filter": [
+ "all",
+ [
+ "!=",
+ "intermittent",
+ 1
+ ]
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "hsl(210, 67%, 85%)"
+ }
+ },
+ {
+ "id": "water-intermittent",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "water",
+ "filter": [
+ "all",
+ [
+ "==",
+ "intermittent",
+ 1
+ ]
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "hsl(210, 67%, 85%)",
+ "fill-opacity": 0.7
+ }
+ },
+ {
+ "id": "water-pattern",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "water",
+ "filter": [
+ "all"
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-pattern": "wave",
+ "fill-translate": [
+ 0,
+ 2.5
+ ]
+ }
+ },
+ {
+ "id": "landcover-ice-shelf",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "landcover",
+ "filter": [
+ "==",
+ "subclass",
+ "ice_shelf"
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "#fff",
+ "fill-opacity": {
+ "base": 1,
+ "stops": [
+ [
+ 0,
+ 0.9
+ ],
+ [
+ 10,
+ 0.3
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "landcover-sand",
+ "type": "fill",
+ "metadata": {
+ "mapbox:group": "1444849382550.77"
+ },
+ "source": "openmaptiles",
+ "source-layer": "landcover",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "sand"
+ ]
+ ],
+ "layout": {
+ "visibility": "visible"
+ },
+ "paint": {
+ "fill-color": "rgba(245, 238, 188, 1)",
+ "fill-opacity": 1
+ }
+ },
+ {
+ "id": "tunnel-minor-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "minor"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 0.5
+ ],
+ [
+ 13,
+ 1
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "tunnel-secondary-tertiary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 8,
+ 1.5
+ ],
+ [
+ 20,
+ 17
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "tunnel-trunk-primary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary",
+ "trunk"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 5,
+ 0.4
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "tunnel-motorway-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ],
+ "layout": {
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-dasharray": [
+ 0.5,
+ 0.25
+ ],
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 5,
+ 0.4
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "tunnel-minor",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "minor_road"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 13.5,
+ 0
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "tunnel-secondary-tertiary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 10
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "tunnel-trunk-primary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary",
+ "trunk"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "tunnel-motorway",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849354174.1904"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ],
+ "layout": {
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-motorway-link-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway_link"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 1
+ ],
+ [
+ 13,
+ 3
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-link-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link",
+ "trunk_link"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 1
+ ],
+ [
+ 13,
+ 3
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-minor-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "minor",
+ "service",
+ "track"
+ ]
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 0.5
+ ],
+ [
+ 13,
+ 1
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "highway-secondary-tertiary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-cap": "butt",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 8,
+ 1.5
+ ],
+ [
+ 20,
+ 17
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "highway-primary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 5,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary"
+ ]
+ ],
+ "layout": {
+ "line-cap": "butt",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 7,
+ 0
+ ],
+ [
+ 8,
+ 0.6
+ ],
+ [
+ 9,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-trunk-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 5,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "trunk"
+ ]
+ ],
+ "layout": {
+ "line-cap": "butt",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 5,
+ 0
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-motorway-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 4,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ],
+ "layout": {
+ "line-cap": "butt",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 4,
+ 0
+ ],
+ [
+ 5,
+ 0.4
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-motorway-link",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 12,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway_link"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12.5,
+ 0
+ ],
+ [
+ 13,
+ 1.5
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-link",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link",
+ "trunk_link"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12.5,
+ 0
+ ],
+ [
+ 13,
+ 1.5
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-minor",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!=",
+ "brunnel",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "minor",
+ "service",
+ "track"
+ ]
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 13.5,
+ 0
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "highway-secondary-tertiary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 8,
+ 0.5
+ ],
+ [
+ 20,
+ 13
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "highway-primary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "primary"
+ ]
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 8.5,
+ 0
+ ],
+ [
+ 9,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-trunk",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "in",
+ "class",
+ "trunk"
+ ]
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "highway-motorway",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849345966.4436"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "minzoom": 5,
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "all",
+ [
+ "!in",
+ "brunnel",
+ "bridge",
+ "tunnel"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ]
+ ],
+ "layout": {
+ "line-cap": "round",
+ "line-join": "round",
+ "visibility": "visible"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-motorway-link-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "==",
+ "class",
+ "motorway_link"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 1
+ ],
+ [
+ 13,
+ 3
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-link-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link",
+ "trunk_link"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 1
+ ],
+ [
+ 13,
+ 3
+ ],
+ [
+ 14,
+ 4
+ ],
+ [
+ 20,
+ 15
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-secondary-tertiary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 8,
+ 1.5
+ ],
+ [
+ 20,
+ 28
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "bridge-trunk-primary-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "primary",
+ "trunk"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 5,
+ 0.4
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 26
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-motorway-casing",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 5,
+ 0.4
+ ],
+ [
+ 6,
+ 0.6
+ ],
+ [
+ 7,
+ 1.5
+ ],
+ [
+ 20,
+ 22
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-motorway-link",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "==",
+ "class",
+ "motorway_link"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12.5,
+ 0
+ ],
+ [
+ 13,
+ 1.5
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-link",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "primary_link",
+ "secondary_link",
+ "tertiary_link",
+ "trunk_link"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12.5,
+ 0
+ ],
+ [
+ 13,
+ 1.5
+ ],
+ [
+ 14,
+ 2.5
+ ],
+ [
+ 20,
+ 11.5
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-secondary-tertiary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "secondary",
+ "tertiary"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 20
+ ]
+ ]
+ }
+ },
+ "minzoom": 13
+ },
+ {
+ "id": "bridge-trunk-primary",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "in",
+ "class",
+ "primary",
+ "trunk"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "bridge-motorway",
+ "type": "line",
+ "metadata": {
+ "mapbox:group": "1444849334699.1902"
+ },
+ "source": "openmaptiles",
+ "source-layer": "transportation",
+ "filter": [
+ "all",
+ [
+ "==",
+ "brunnel",
+ "bridge"
+ ],
+ [
+ "==",
+ "class",
+ "motorway"
+ ]
+ ],
+ "layout": {
+ "line-join": "round"
+ },
+ "paint": {
+ "line-color": "#d9d5cd",
+ "line-width": {
+ "base": 1.2,
+ "stops": [
+ [
+ 6.5,
+ 0
+ ],
+ [
+ 7,
+ 0.5
+ ],
+ [
+ 20,
+ 18
+ ]
+ ]
+ }
+ }
+ },
+ {
+ "id": "waterway-name",
+ "type": "symbol",
+ "source": "openmaptiles",
+ "source-layer": "waterway",
+ "minzoom": 13,
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ [
+ "has",
+ "name"
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "symbol-spacing": 350,
+ "text-field": "{name}",
+ "text-font": [
+ "migu1c-regular"
+ ],
+ "text-letter-spacing": 0.2,
+ "text-max-width": 5,
+ "text-rotation-alignment": "map",
+ "text-size": 14
+ },
+ "paint": {
+ "text-color": "#74aee9",
+ "text-halo-color": "rgba(255,255,255,0.7)",
+ "text-halo-width": 1.5
+ }
+ },
+ {
+ "id": "water-name-lakeline",
+ "type": "symbol",
+ "source": "openmaptiles",
+ "source-layer": "water_name",
+ "filter": [
+ "==",
+ "$type",
+ "LineString"
+ ],
+ "layout": {
+ "symbol-placement": "line",
+ "symbol-spacing": 350,
+ "text-field": "{name}",
+ "text-font": [
+ "migu1c-regular"
+ ],
+ "text-letter-spacing": 0.2,
+ "text-max-width": 5,
+ "text-rotation-alignment": "map",
+ "text-size": 14
+ },
+ "paint": {
+ "text-color": "#74aee9",
+ "text-halo-color": "rgba(255,255,255,0.7)",
+ "text-halo-width": 1.5
+ }
+ },
+ {
+ "id": "water-name-ocean",
+ "type": "symbol",
+ "source": "openmaptiles",
+ "source-layer": "water_name",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "Point"
+ ],
+ [
+ "==",
+ "class",
+ "ocean"
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "point",
+ "symbol-spacing": 350,
+ "text-field": "{name}",
+ "text-font": [
+ "migu1c-regular"
+ ],
+ "text-letter-spacing": 0.2,
+ "text-max-width": 5,
+ "text-rotation-alignment": "map",
+ "text-size": 14
+ },
+ "paint": {
+ "text-color": "#74aee9",
+ "text-halo-color": "rgba(255,255,255,0.7)",
+ "text-halo-width": 1.5
+ }
+ },
+ {
+ "id": "water-name-other",
+ "type": "symbol",
+ "source": "openmaptiles",
+ "source-layer": "water_name",
+ "filter": [
+ "all",
+ [
+ "==",
+ "$type",
+ "Point"
+ ],
+ [
+ "!in",
+ "class",
+ "ocean"
+ ]
+ ],
+ "layout": {
+ "symbol-placement": "point",
+ "symbol-spacing": 350,
+ "text-field": "{name}",
+ "text-font": [
+ "migu1c-regular"
+ ],
+ "text-letter-spacing": 0.2,
+ "text-max-width": 5,
+ "text-rotation-alignment": "map",
+ "text-size": {
+ "stops": [
+ [
+ 0,
+ 10
+ ],
+ [
+ 6,
+ 14
+ ]
+ ]
+ },
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#74aee9",
+ "text-halo-color": "rgba(255,255,255,0.7)",
+ "text-halo-width": 1.5
+ }
+ },
+ {
+ "id": "place-other",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "!in",
+ "class",
+ "city",
+ "town",
+ "village",
+ "country",
+ "continent"
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-bold"
+ ],
+ "text-letter-spacing": 0.1,
+ "text-max-width": 9,
+ "text-size": {
+ "base": 1.2,
+ "stops": [
+ [
+ 12,
+ 10
+ ],
+ [
+ 15,
+ 14
+ ]
+ ]
+ },
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#633",
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 1.2
+ }
+ },
+ {
+ "id": "place-village",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "==",
+ "class",
+ "village"
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-regular"
+ ],
+ "text-max-width": 8,
+ "text-size": {
+ "base": 1.2,
+ "stops": [
+ [
+ 10,
+ 12
+ ],
+ [
+ 15,
+ 22
+ ]
+ ]
+ },
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#333",
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 1.2
+ }
+ },
+ {
+ "id": "place-town",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "==",
+ "class",
+ "town"
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-regular"
+ ],
+ "text-max-width": 8,
+ "text-size": {
+ "base": 1.2,
+ "stops": [
+ [
+ 10,
+ 14
+ ],
+ [
+ 15,
+ 24
+ ]
+ ]
+ },
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#333",
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 1.2
+ }
+ },
+ {
+ "id": "place-city",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "!=",
+ "capital",
+ 2
+ ],
+ [
+ "==",
+ "class",
+ "city"
+ ]
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-regular"
+ ],
+ "text-max-width": 8,
+ "text-size": {
+ "base": 1.2,
+ "stops": [
+ [
+ 7,
+ 14
+ ],
+ [
+ 11,
+ 24
+ ]
+ ]
+ },
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#333",
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 1.2
+ }
+ },
+ {
+ "id": "place-city-capital",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "==",
+ "capital",
+ 2
+ ],
+ [
+ "==",
+ "class",
+ "city"
+ ]
+ ],
+ "layout": {
+ "icon-image": "star_11",
+ "icon-size": 0.8,
+ "text-anchor": "left",
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-regular"
+ ],
+ "text-max-width": 8,
+ "text-offset": [
+ 0.4,
+ 0
+ ],
+ "text-size": {
+ "base": 1.2,
+ "stops": [
+ [
+ 7,
+ 14
+ ],
+ [
+ 11,
+ 24
+ ]
+ ]
+ },
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#333",
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 1.2
+ }
+ },
+ {
+ "id": "place-country-other",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "country"
+ ],
+ [
+ ">=",
+ "rank",
+ 3
+ ],
+ [
+ "!has",
+ "iso_a2"
+ ]
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu1c-regular"
+ ],
+ "text-max-width": 6.25,
+ "text-size": {
+ "stops": [
+ [
+ 3,
+ 11
+ ],
+ [
+ 7,
+ 17
+ ]
+ ]
+ },
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#334",
+ "text-halo-blur": 1,
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 2
+ }
+ },
+ {
+ "id": "place-country-3",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "country"
+ ],
+ [
+ ">=",
+ "rank",
+ 3
+ ],
+ [
+ "has",
+ "iso_a2"
+ ]
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-bold"
+ ],
+ "text-max-width": 6.25,
+ "text-size": {
+ "stops": [
+ [
+ 3,
+ 11
+ ],
+ [
+ 7,
+ 17
+ ]
+ ]
+ },
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#334",
+ "text-halo-blur": 1,
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 2
+ }
+ },
+ {
+ "id": "place-country-2",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "country"
+ ],
+ [
+ "==",
+ "rank",
+ 2
+ ],
+ [
+ "has",
+ "iso_a2"
+ ]
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-bold"
+ ],
+ "text-max-width": 6.25,
+ "text-size": {
+ "stops": [
+ [
+ 2,
+ 11
+ ],
+ [
+ 5,
+ 17
+ ]
+ ]
+ },
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#334",
+ "text-halo-blur": 1,
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 2
+ }
+ },
+ {
+ "id": "place-country-1",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "filter": [
+ "all",
+ [
+ "==",
+ "class",
+ "country"
+ ],
+ [
+ "==",
+ "rank",
+ 1
+ ],
+ [
+ "has",
+ "iso_a2"
+ ]
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-bold"
+ ],
+ "text-max-width": 6.25,
+ "text-size": {
+ "stops": [
+ [
+ 1,
+ 11
+ ],
+ [
+ 4,
+ 17
+ ]
+ ]
+ },
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#334",
+ "text-halo-blur": 1,
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 2
+ }
+ },
+ {
+ "id": "place-continent",
+ "type": "symbol",
+ "metadata": {
+ "mapbox:group": "1444849242106.713"
+ },
+ "source": "openmaptiles",
+ "source-layer": "place",
+ "maxzoom": 1,
+ "filter": [
+ "==",
+ "class",
+ "continent"
+ ],
+ "layout": {
+ "text-field": "{name}",
+ "text-font": [
+ "migu2m-bold"
+ ],
+ "text-max-width": 6.25,
+ "text-size": 14,
+ "text-transform": "uppercase",
+ "visibility": "visible"
+ },
+ "paint": {
+ "text-color": "#334",
+ "text-halo-blur": 1,
+ "text-halo-color": "rgba(255,255,255,0.8)",
+ "text-halo-width": 2
+ }
+ }
+ ],
+ "id": "bright"
+}
diff --git a/examples/basic/public/streettree/tokyo-trees.bin b/examples/basic/public/streettree/tokyo-trees.bin
new file mode 100644
index 0000000..3448c1c
Binary files /dev/null and b/examples/basic/public/streettree/tokyo-trees.bin differ
diff --git a/examples/basic/src/ClientMapRoutes.tsx b/examples/basic/src/ClientMapRoutes.tsx
index fd7afe6..be4d08e 100644
--- a/examples/basic/src/ClientMapRoutes.tsx
+++ b/examples/basic/src/ClientMapRoutes.tsx
@@ -39,11 +39,14 @@ const MarkerLabelPositionPage = lazy(() => import('./pages/marker/labelposition/
const MarkerAnimationPage = lazy(() => import('./pages/marker/animation/MarkerAnimationPage').then(m => ({ default: m.MarkerAnimationPage })));
const PostOfficePage = lazy(() => import('./pages/marker/postoffice/PostOfficePage').then(m => ({ default: m.PostOfficePage })));
const PostOfficeClusterPage = lazy(() => import('./pages/marker/postofficecluster/PostOfficeClusterPage').then(m => ({ default: m.PostOfficeClusterPage })));
+const StreetTreePage = lazy(() => import('./pages/marker/streettree/StreetTreePage').then(m => ({ default: m.StreetTreePage })));
const PolygonClickPage = lazy(() => import('./pages/polygon/click/PolygonClickPage').then(m => ({ default: m.PolygonClickPage })));
const PolygonGeodesicPage = lazy(() => import('./pages/polygon/geodesic/PolygonGeodesicPage').then(m => ({ default: m.PolygonGeodesicPage })));
const PolygonHolePage = lazy(() => import('./pages/polygon/hole/PolygonHolePage').then(m => ({ default: m.PolygonHolePage })));
const PolylineClickPage = lazy(() => import('./pages/polyline/click/PolylineClickPage').then(m => ({ default: m.PolylineClickPage })));
const RasterLayerPage = lazy(() => import('./pages/rasterlayer/RasterLayerPage').then(m => ({ default: m.RasterLayerPage })));
+const VectorTileLayerPage = lazy(() => import('./pages/vectortile/VectorTileLayerPage').then(m => ({ default: m.VectorTileLayerPage })));
+const StyleAdjustmentsPage = lazy(() => import('./pages/vectorstyle/StyleAdjustmentsPage').then(m => ({ default: m.StyleAdjustmentsPage })));
const HeatmapLayerPage = lazy(() => import('./pages/heatmaplayer/HeatmapLayerPage').then(m => ({ default: m.HeatmapLayerPage })));
const BasicGeoJSONPage = lazy(() => import('./pages/geojson/basic/BasicGeoJSONPage').then(m => ({ default: m.BasicGeoJSONPage })));
const GeoJSONLayerPage = lazy(() => import('./pages/geojson/layer/GeoJSONLayerPage').then(m => ({ default: m.GeoJSONLayerPage })));
@@ -97,11 +100,14 @@ function pageContent(page: string | undefined) {
case 'polygon-hole': return ;
case 'ground-image': return ;
case 'raster-layer': return ;
+ case 'vector-tile': return ;
+ case 'style-adjustments': return ;
case 'info-bubble-simple': return ;
case 'info-bubble-styled': return ;
case 'info-bubble-multiple': return ;
case 'info-bubble-rich': return ;
case 'post-office-cluster': return ;
+ case 'street-tree': return ;
case 'heatmap-layer': return ;
case 'geojson-basic': return ;
case 'geojson-layer': return ;
@@ -121,7 +127,7 @@ function ProviderPageRoute() {
if (requestedPage === 'camera-sync' || requestedPage === 'hello-map') {
return ;
}
- if (provider !== 'maplibre' && provider !== 'maplibre-3d' && provider !== 'mapbox' && provider !== 'leaflet' && provider !== 'openlayers' && provider !== 'google-maps' && provider !== 'google-maps-3d' && provider !== 'arcgis' && provider !== 'arcgis-3d' && provider !== 'mapkit' && provider !== 'azuremaps' && provider !== 'cesium' && provider !== 'here' && provider !== 'tomtom' && provider !== 'maptiler' && provider !== 'longdo' && provider !== 'mappls') {
+ if (provider !== 'maplibre' && provider !== 'maplibre-3d' && provider !== 'mapbox' && provider !== 'leaflet' && provider !== 'openlayers' && provider !== 'google-maps' && provider !== 'google-maps-3d' && provider !== 'arcgis' && provider !== 'arcgis-3d' && provider !== 'mapkit' && provider !== 'azuremaps' && provider !== 'cesium' && provider !== 'here' && provider !== 'tomtom' && provider !== 'maptiler' && provider !== 'longdo' && provider !== 'mappls' && provider !== 'deckgl') {
return ;
}
diff --git a/examples/basic/src/MapViewContainer.tsx b/examples/basic/src/MapViewContainer.tsx
index 8ca1d9c..6045a30 100644
--- a/examples/basic/src/MapViewContainer.tsx
+++ b/examples/basic/src/MapViewContainer.tsx
@@ -8,6 +8,7 @@ import type {
MapDesignTypeInterface,
MapViewStateInterface,
MarkerTilingOptions,
+ MapViewStyle,
} from '@mapconductor/js-sdk-core';
import { type InitialCamera, DEFAULT_CAMERA } from './common';
import { SingletonMapSlot, useSingletonMapState, type SingletonMapId } from './SingletonMaps';
@@ -50,6 +51,9 @@ interface MapViewContainerProps {
* 指定された場合は restrictBounds より優先される。
*/
cameraRestriction?: CameraRestriction | null;
+ /** 地図の見た目そのもの。`createVectorStyle()` が作る。 */
+ mapStyle?: MapViewStyle | null;
+ onStyleDiagnostics?: (diagnostics: readonly string[]) => void;
}
function SingletonProviderView({
@@ -63,6 +67,8 @@ function SingletonProviderView({
onStateReady,
restrictBounds,
cameraRestriction: cameraRestrictionProp,
+ mapStyle,
+ onStyleDiagnostics,
}: ProviderViewProps & { id: SingletonMapId }) {
const cameraPosition = useInitialCameraPosition(initialCamera);
const state = useSingletonMapState(id, cameraPosition);
@@ -85,6 +91,8 @@ function SingletonProviderView({
onCameraMove={onCameraMove}
onCameraMoveEnd={onCameraMoveEnd}
cameraRestriction={cameraRestriction}
+ mapStyle={mapStyle}
+ onStyleDiagnostics={onStyleDiagnostics}
>
{children}
@@ -102,6 +110,8 @@ export function MapViewContainer({
markerTilingOptions,
onStateReady,
restrictBounds,
+ mapStyle,
+ onStyleDiagnostics,
}: MapViewContainerProps) {
const location = useLocation();
const isGoogle3D = location.pathname.startsWith('/google-maps-3d');
@@ -121,6 +131,7 @@ export function MapViewContainer({
const isMapTiler = location.pathname.startsWith('/maptiler');
const isLongdo = location.pathname.startsWith('/longdo');
const isMappls = location.pathname.startsWith('/mappls');
+ const isDeckGL = location.pathname.startsWith('/deckgl');
const commonProps: ProviderViewProps = {
children,
@@ -133,6 +144,8 @@ export function MapViewContainer({
onStateReady,
restrictBounds,
cameraRestriction,
+ mapStyle,
+ onStyleDiagnostics,
};
switch (true) {
@@ -192,6 +205,10 @@ export function MapViewContainer({
return ;
}
+ case isDeckGL: {
+ return ;
+ }
+
default: {
return (
No provider can be detected
diff --git a/examples/basic/src/SingletonMaps.tsx b/examples/basic/src/SingletonMaps.tsx
index 15690da..8e3dfee 100644
--- a/examples/basic/src/SingletonMaps.tsx
+++ b/examples/basic/src/SingletonMaps.tsx
@@ -39,6 +39,10 @@ import { TomTomDesign, useTomTomViewState } from '@mapconductor/react-for-tomtom
import { MapTilerDesign, useMapTilerViewState } from '@mapconductor/react-for-maptiler';
import { LongdoDesign, useLongdoViewState } from '@mapconductor/react-for-longdo';
import { MapplsDesign, useMapplsViewState } from '@mapconductor/react-for-mappls';
+// deck.gl は読み込み時に `globalThis.deck` を取り合う(別バージョンが居ると例外)。
+// Longdo の web SDK が自前の deck.gl 8 系を積んでいるので、deck.gl の地図を出さない
+// ページでは評価しないこと。状態とデザインは deck.gl を引かない `/state` から取る。
+import { DeckGLDesign, useDeckGLMapViewState } from '@mapconductor/react-for-deckgl/state';
import type { SingletonMapContent } from './providers/singleton/types';
export type { SingletonMapContent };
@@ -60,7 +64,8 @@ export type SingletonMapId =
| 'tomtom'
| 'maptiler'
| 'longdo'
- | 'mappls';
+ | 'mappls'
+ | 'deckgl';
type AnyMapViewState = MapViewStateInterface>;
type AnyMapDesignType = MapDesignTypeInterface;
@@ -127,6 +132,7 @@ const LazyHereSingletonView = lazy(() => import('./providers/singleton/HereSingl
const LazyTomTomSingletonView = lazy(() => import('./providers/singleton/TomTomSingletonView'));
const LazyMapTilerSingletonView = lazy(() => import('./providers/singleton/MapTilerSingletonView'));
const LazyMapplsSingletonView = lazy(() => import('./providers/singleton/MapplsSingletonView'));
+const LazyDeckGLSingletonView = lazy(() => import('./providers/singleton/DeckGLSingletonView'));
const LazyLongdoSingletonView = lazy(() => import('./providers/singleton/LongdoSingletonView'));
export function SingletonMapsProvider({ children }: { children: ReactNode }) {
@@ -162,6 +168,7 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
const mapTilerState = useMapTilerViewState({ apiKey: mapTilerApiKey, mapDesignType: MapTilerDesign.Streets, cameraPosition: DEFAULT_CAMERA });
const longdoState = useLongdoViewState({ apiKey: longdoApiKey, mapDesignType: LongdoDesign.Normal, cameraPosition: DEFAULT_CAMERA });
const mapplsState = useMapplsViewState({ apiKey: mapplsApiKey, mapDesignType: MapplsDesign.Default, cameraPosition: DEFAULT_CAMERA });
+ const deckglState = useDeckGLMapViewState({ mapDesignType: DeckGLDesign.Standard, cameraPosition: DEFAULT_CAMERA });
const statesById = useMemo>(() => ({
'google-2d': google2DState,
@@ -181,9 +188,10 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
maptiler: mapTilerState,
longdo: longdoState,
mappls: mapplsState,
+ deckgl: deckglState,
}), [
google2DState, google3DState, maplibre2DState, maplibre3DState, mapboxState,
- leafletState, openLayersState, arcgis2DState, arcgis3DState, mapkitState, azuremapsState, cesiumState, hereState, tomtomState, mapTilerState, longdoState, mapplsState,
+ leafletState, openLayersState, arcgis2DState, arcgis3DState, mapkitState, azuremapsState, cesiumState, hereState, tomtomState, mapTilerState, longdoState, mapplsState, deckglState,
]);
// Capture each provider's default map design once, up front, before any page
@@ -268,6 +276,8 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
onCameraMoveStart={content['google-2d']?.onCameraMoveStart}
onCameraMove={content['google-2d']?.onCameraMove}
onCameraMoveEnd={content['google-2d']?.onCameraMoveEnd}
+ mapStyle={content['google-2d']?.mapStyle}
+ onStyleDiagnostics={content['google-2d']?.onStyleDiagnostics}
>
{content['google-2d'] && {content['google-2d']!.children} }
@@ -286,6 +296,8 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
onCameraMoveStart={content['google-3d']?.onCameraMoveStart}
onCameraMove={content['google-3d']?.onCameraMove}
onCameraMoveEnd={content['google-3d']?.onCameraMoveEnd}
+ mapStyle={content['google-3d']?.mapStyle}
+ onStyleDiagnostics={content['google-3d']?.onStyleDiagnostics}
>
{content['google-3d'] && {content['google-3d']!.children} }
@@ -351,6 +363,10 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
id: 'mappls',
node: ,
},
+ {
+ id: 'deckgl',
+ node: ,
+ },
];
return (
@@ -365,7 +381,7 @@ export function SingletonMapsProvider({ children }: { children: ReactNode }) {
);
}
-export function SingletonMapSlot({ id, children, onMapClick, onCameraMoveStart, onCameraMove, onCameraMoveEnd, cameraRestriction }: SingletonMapSlotProps) {
+export function SingletonMapSlot({ id, children, onMapClick, onCameraMoveStart, onCameraMove, onCameraMoveEnd, cameraRestriction, mapStyle, onStyleDiagnostics }: SingletonMapSlotProps) {
const { register, unregister } = useSingletonMapsContext();
const owner = useId();
@@ -378,6 +394,8 @@ export function SingletonMapSlot({ id, children, onMapClick, onCameraMoveStart,
onCameraMove,
onCameraMoveEnd,
cameraRestriction,
+ mapStyle,
+ onStyleDiagnostics,
});
return () => unregister(id, owner);
}, [
@@ -389,6 +407,8 @@ export function SingletonMapSlot({ id, children, onMapClick, onCameraMoveStart,
onCameraMove,
onCameraMoveEnd,
cameraRestriction,
+ mapStyle,
+ onStyleDiagnostics,
register,
unregister,
]);
diff --git a/examples/basic/src/app/AppHeader.tsx b/examples/basic/src/app/AppHeader.tsx
index ba0c5fd..0ea3fa7 100644
--- a/examples/basic/src/app/AppHeader.tsx
+++ b/examples/basic/src/app/AppHeader.tsx
@@ -18,6 +18,7 @@ const PROVIDERS: Array<{ value: MapProvider; label: string }> = [
{ value: 'maptiler', label: 'MapTiler' },
{ value: 'longdo', label: 'Longdo' },
{ value: 'mappls', label: 'Mappls' },
+ { value: 'deckgl', label: 'deck.gl' },
{ value: 'google', label: 'Google Maps' },
{ value: 'google-3d', label: 'Google Maps 3D' },
];
diff --git a/examples/basic/src/app/appRouting.tsx b/examples/basic/src/app/appRouting.tsx
index fd99b29..aec273a 100644
--- a/examples/basic/src/app/appRouting.tsx
+++ b/examples/basic/src/app/appRouting.tsx
@@ -3,13 +3,13 @@ import { SamplePageLayout } from '../components/SamplePageLayout';
import { getLanguageFromPath } from '../samples/i18n';
import { DEFAULT_SAMPLE_PAGE, isKnownSamplePage, isSupportedLanguage, resolveProviderForPage, type SupportedLanguage } from '../samples/sampleRegistry';
-export type MapProvider = 'maplibre' | 'mapbox' | 'leaflet' | 'openlayers' | 'google' | 'google-3d' | 'arcgis' | 'arcgis-3d' | 'mapkit' | 'azuremaps' | 'cesium' | 'here' | 'tomtom' | 'maptiler' | 'longdo' | 'mappls';
+export type MapProvider = 'maplibre' | 'mapbox' | 'leaflet' | 'openlayers' | 'google' | 'google-3d' | 'arcgis' | 'arcgis-3d' | 'mapkit' | 'azuremaps' | 'cesium' | 'here' | 'tomtom' | 'maptiler' | 'longdo' | 'mappls' | 'deckgl';
const providerByPath = new Map([
['maplibre', 'maplibre'], ['maplibre-3d', 'maplibre'], ['mapbox', 'mapbox'],
['leaflet', 'leaflet'], ['openlayers', 'openlayers'], ['google-maps', 'google'],
['google', 'google'], ['google-maps-3d', 'google-3d'], ['google-3d', 'google-3d'],
- ['arcgis', 'arcgis'], ['arcgis-3d', 'arcgis-3d'], ['mapkit', 'mapkit'], ['azuremaps', 'azuremaps'], ['cesium', 'cesium'], ['here', 'here'], ['tomtom', 'tomtom'], ['maptiler', 'maptiler'], ['longdo', 'longdo'], ['mappls', 'mappls'],
+ ['arcgis', 'arcgis'], ['arcgis-3d', 'arcgis-3d'], ['mapkit', 'mapkit'], ['azuremaps', 'azuremaps'], ['cesium', 'cesium'], ['here', 'here'], ['tomtom', 'tomtom'], ['maptiler', 'maptiler'], ['longdo', 'longdo'], ['mappls', 'mappls'], ['deckgl', 'deckgl'],
]);
export function parseSamplePath(pathname: string) {
@@ -28,7 +28,7 @@ export function providerPath(provider: MapProvider, page: string): string {
maplibre: resolveProviderForPage('maplibre', page),
mapbox: 'mapbox', leaflet: 'leaflet', openlayers: 'openlayers',
google: 'google-maps', 'google-3d': 'google-maps-3d',
- arcgis: 'arcgis', 'arcgis-3d': 'arcgis-3d', mapkit: 'mapkit', azuremaps: 'azuremaps', cesium: 'cesium', here: 'here', tomtom: 'tomtom', maptiler: 'maptiler', longdo: 'longdo', mappls: 'mappls',
+ arcgis: 'arcgis', 'arcgis-3d': 'arcgis-3d', mapkit: 'mapkit', azuremaps: 'azuremaps', cesium: 'cesium', here: 'here', tomtom: 'tomtom', maptiler: 'maptiler', longdo: 'longdo', mappls: 'mappls', deckgl: 'deckgl',
};
return paths[provider];
}
diff --git a/examples/basic/src/index.css b/examples/basic/src/index.css
index c309657..59e0bf9 100644
--- a/examples/basic/src/index.css
+++ b/examples/basic/src/index.css
@@ -610,6 +610,11 @@ body,
inset: 0;
z-index: 0;
visibility: hidden;
+ /* `visibility` alone is not enough: a descendant can set its own
+ `visibility: visible` and come back -- Longdo's built-in MapLibre
+ attribution does, and stayed on screen under every other provider.
+ Opacity is not inherited, so nothing inside can undo it. */
+ opacity: 0;
pointer-events: none;
}
@@ -619,6 +624,7 @@ body,
.singleton-map-layer.active {
visibility: visible;
+ opacity: 1;
pointer-events: auto;
}
@@ -724,6 +730,17 @@ body,
margin-bottom: 4px;
}
+/* The category name doubles as its draw/skip switch, in the label row. */
+.category-visibility {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.category-visibility input {
+ width: auto;
+}
+
.checkbox-control {
display: flex;
align-items: center;
@@ -1021,3 +1038,17 @@ body,
.hello-map-notes li {
margin: 4px 0;
}
+
+/* ベクタースタイルのページが出す診断行。ルールが当たらなかった、この地図が
+ 受け取れなかった、スタイルが読めなかった — どれも「ほぼ動いた」に見えるので
+ 目立たせる。 */
+.diagnostic {
+ margin: 2px 0;
+ font-size: 11px;
+ line-height: 1.35;
+ color: #b45309;
+}
+
+.diagnostic.error {
+ color: #b91c1c;
+}
diff --git a/examples/basic/src/pages/common/showBasemap.ts b/examples/basic/src/pages/common/showBasemap.ts
new file mode 100644
index 0000000..9325217
--- /dev/null
+++ b/examples/basic/src/pages/common/showBasemap.ts
@@ -0,0 +1,65 @@
+import {
+ VectorStyleSupportKey,
+ type MapDesignTypeInterface,
+ type MapViewStateInterface,
+} from '@mapconductor/js-sdk-core';
+import { ArcGISDesign, ArcGISMapViewState } from '@mapconductor/react-for-arcgis';
+import { AzureMapsDesign, AzureMapsViewState } from '@mapconductor/react-for-azuremaps';
+import { CesiumDesign, CesiumMapViewState } from '@mapconductor/react-for-cesium';
+// Import the state-only entry point. The full deck.gl barrel installs a
+// versioned `globalThis.deck`; Mappls loads its own deck runtime and fails
+// when it finds a different version already registered on the page.
+import { DeckGLDesign, DeckGLMapViewState } from '@mapconductor/react-for-deckgl/state';
+import { GoogleMapDesign, GoogleMapViewState } from '@mapconductor/react-for-googlemaps';
+import { HereMapDesign, HereViewState } from '@mapconductor/react-for-here';
+import { LeafletDesign, LeafletMapViewState } from '@mapconductor/react-for-leaflet';
+import { LongdoDesign, LongdoViewState } from '@mapconductor/react-for-longdo';
+import { MapboxDesign, MapboxViewState } from '@mapconductor/react-for-mapbox';
+import { MapLibreDesign, MapLibreViewState } from '@mapconductor/react-for-maplibre';
+import { MapTilerDesign, MapTilerViewState } from '@mapconductor/react-for-maptiler';
+import { OpenLayersDesign, OpenLayersMapViewState } from '@mapconductor/react-for-openlayers';
+import { TomTomDesign, TomTomViewState } from '@mapconductor/react-for-tomtom';
+
+/**
+ * Blanks the backend's own basemap, or restores it.
+ *
+ * Each provider says "draw nothing" with its own design value (`None`, or
+ * Azure's `Blank`). MapKit and Mappls have none; there the opaque tiles cover
+ * the basemap, which is still fetched for nobody.
+ */
+export function showBasemap(state: MapViewStateInterface>, visible: boolean) {
+ // A map that takes the style directly gets it *as* its design from the
+ // layer; blanking first would only load one style to throw it away. Going
+ // back to the provider's own basemap is still done here.
+ if (!visible && state.serviceRegistry.has(VectorStyleSupportKey)) return;
+ if (state instanceof MapLibreViewState) {
+ state.mapDesignType = visible ? MapLibreDesign.OsmBrightJa : MapLibreDesign.None;
+ } else if (state instanceof GoogleMapViewState) {
+ // The 3D map has no "none" mode, and the same state class serves both.
+ const map = state.getMapViewHolder()?.map as { tagName?: string } | undefined;
+ if (map?.tagName === 'GMP-MAP-3D') return;
+ state.mapDesignType = visible ? GoogleMapDesign.Normal : GoogleMapDesign.None;
+ } else if (state instanceof ArcGISMapViewState) {
+ state.mapDesignType = visible ? ArcGISDesign.OsmStandard : ArcGISDesign.None;
+ } else if (state instanceof MapboxViewState) {
+ state.mapDesignType = visible ? MapboxDesign.Streets : MapboxDesign.None;
+ } else if (state instanceof MapTilerViewState) {
+ state.mapDesignType = visible ? MapTilerDesign.Streets : MapTilerDesign.None;
+ } else if (state instanceof TomTomViewState) {
+ state.mapDesignType = visible ? TomTomDesign.Standard : TomTomDesign.None;
+ } else if (state instanceof LongdoViewState) {
+ state.mapDesignType = visible ? LongdoDesign.Normal : LongdoDesign.None;
+ } else if (state instanceof HereViewState) {
+ state.mapDesignType = visible ? HereMapDesign.NormalDay : HereMapDesign.None;
+ } else if (state instanceof LeafletMapViewState) {
+ state.mapDesignType = visible ? LeafletDesign.OpenStreetMap : LeafletDesign.None;
+ } else if (state instanceof OpenLayersMapViewState) {
+ state.mapDesignType = visible ? OpenLayersDesign.OpenStreetMap : OpenLayersDesign.None;
+ } else if (state instanceof DeckGLMapViewState) {
+ state.mapDesignType = visible ? DeckGLDesign.Standard : DeckGLDesign.None;
+ } else if (state instanceof CesiumMapViewState) {
+ state.mapDesignType = visible ? CesiumDesign.Default : CesiumDesign.None;
+ } else if (state instanceof AzureMapsViewState) {
+ state.mapDesignType = visible ? AzureMapsDesign.Road : AzureMapsDesign.Blank;
+ }
+}
diff --git a/examples/basic/src/pages/heatmaplayer/HeatmapLayerPage.tsx b/examples/basic/src/pages/heatmaplayer/HeatmapLayerPage.tsx
index deca661..4b4089c 100644
--- a/examples/basic/src/pages/heatmaplayer/HeatmapLayerPage.tsx
+++ b/examples/basic/src/pages/heatmaplayer/HeatmapLayerPage.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState, type ReactNode } from 'react';
+import { lazy, Suspense, useEffect, useState, type ReactNode } from 'react';
import { useLocation } from 'react-router-dom';
import { createGeoPoint, createMapCameraPosition } from '@mapconductor/js-sdk-core';
import { MapLibreDesign, MapLibreMapView2D, useMapLibreViewState, type MapLibreViewState } from '@mapconductor/react-for-maplibre';
@@ -9,6 +9,12 @@ import { ArcGISDesign, ArcGISMapView2D, useArcGISViewState, type ArcGISViewState
import { TomTomDesign, TomTomMapView2D, useTomTomViewState, type TomTomViewState } from '@mapconductor/react-for-tomtom';
import { MapTilerDesign, MapTilerMapView2D, useMapTilerViewState, type MapTilerViewState } from '@mapconductor/react-for-maptiler';
import { MapplsDesign, MapplsMapView2D, useMapplsViewState, type MapplsViewState } from '@mapconductor/react-for-mappls';
+// deck.gl は読み込み時に `globalThis.deck` を取り合う(別バージョンが居ると例外)。
+// このモジュールは全プロバイダのページから評価されるので、描画コンポーネントだけ遅延読み込みにする。
+import { DeckGLDesign, useDeckGLMapViewState, type DeckGLMapViewStateInterface } from '@mapconductor/react-for-deckgl/state';
+const LazyDeckGLMapView = lazy(() =>
+ import('@mapconductor/react-for-deckgl').then(m => ({ default: m.DeckGLMapView })),
+);
import { HeatmapOverlay, HeatmapPoints, HeatmapPointState } from '@mapconductor/react-heatmap';
import { ControlPanel } from '../../components/ControlPanel';
import { SingletonMapSlot, useSingletonMapState } from '../../SingletonMaps';
@@ -215,12 +221,29 @@ function MapTilerHeatmapLayerPage() {
);
}
+function DeckGLHeatmapLayerPage() {
+ const mapViewState = useDeckGLMapViewState({
+ mapDesignType: DeckGLDesign.Light,
+ cameraPosition: INIT_CAMERA_POSITION,
+ });
+ return (
+ (
+
+ {children}
+
+ )}
+ />
+ );
+}
+
export function HeatmapLayerPage() {
const location = useLocation();
if (location.pathname.startsWith('/google-maps')) return ;
if (location.pathname.startsWith('/maptiler')) return ;
if (location.pathname.startsWith('/tomtom')) return ;
if (location.pathname.startsWith('/mappls')) return ;
+ if (location.pathname.startsWith('/deckgl')) return ;
if (location.pathname.startsWith('/mapbox')) return ;
if (location.pathname.startsWith('/leaflet')) return ;
if (location.pathname.startsWith('/openlayers')) return ;
diff --git a/examples/basic/src/pages/map/camerasync/cameraSyncProviderRegistry.tsx b/examples/basic/src/pages/map/camerasync/cameraSyncProviderRegistry.tsx
index e7d493a..583b670 100644
--- a/examples/basic/src/pages/map/camerasync/cameraSyncProviderRegistry.tsx
+++ b/examples/basic/src/pages/map/camerasync/cameraSyncProviderRegistry.tsx
@@ -1,4 +1,4 @@
-import type { ReactNode } from 'react';
+import { lazy, Suspense, type ReactNode } from 'react';
import type { MapCameraPosition } from '@mapconductor/js-sdk-core';
import {
GoogleMapView,
@@ -61,6 +61,14 @@ import {
MapplsMapView2D,
type MapplsViewState,
} from '@mapconductor/react-for-mappls';
+import type { DeckGLMapViewStateInterface } from '@mapconductor/react-for-deckgl/state';
+
+// deck.gl は読み込み時に `globalThis.deck` を取り合い、別バージョンが既に居ると例外を
+// 投げる。Longdo の web SDK が自前の deck.gl 8 系を積んでいるため、既定ペインの Longdo が
+// 居るだけで壊れてしまう。deck.gl のペインを選んだときだけ読み込む。
+const LazyDeckGLMapView = lazy(() =>
+ import('@mapconductor/react-for-deckgl').then(m => ({ default: m.DeckGLMapView })),
+);
interface MapViewRenderProps {
paneState: PaneState;
@@ -195,6 +203,16 @@ const adapters: CameraSyncProviderAdapter[] = [
id: 'mappls', label: 'Mappls', altitude: (_pane, position) => convertedAltitude(position, googleZoom),
render: props => renderMappls(props),
},
+ {
+ // deck.gl works in unified zoom once the driver has applied its +1 offset,
+ // so the Google-reference altitude applies unchanged (same as MapLibre).
+ id: 'deckgl', label: 'deck.gl', altitude: (_pane, position) => convertedAltitude(position, googleZoom),
+ render: ({ paneState: pane, children, ...events }) => (
+
+ {children}
+
+ ),
+ },
];
export const cameraSyncProviders: readonly CameraSyncProviderAdapter[] = adapters;
diff --git a/examples/basic/src/pages/map/camerasync/cameraSyncProviders.tsx b/examples/basic/src/pages/map/camerasync/cameraSyncProviders.tsx
index 50d8a14..f73148a 100644
--- a/examples/basic/src/pages/map/camerasync/cameraSyncProviders.tsx
+++ b/examples/basic/src/pages/map/camerasync/cameraSyncProviders.tsx
@@ -45,6 +45,7 @@ import { TomTomDesign, useTomTomViewState } from '@mapconductor/react-for-tomtom
import { MapTilerDesign, useMapTilerViewState } from '@mapconductor/react-for-maptiler';
import { LongdoDesign, useLongdoViewState } from '@mapconductor/react-for-longdo';
import { MapplsDesign, useMapplsViewState } from '@mapconductor/react-for-mappls';
+import { DeckGLDesign, useDeckGLMapViewState } from '@mapconductor/react-for-deckgl/state';
type ProviderStateMap = Record;
@@ -79,6 +80,7 @@ export function useCameraSyncProviderStates(prefix: 'left' | 'right'): ProviderS
const mapTilerState = useMapTilerViewState({ id: `camera-sync-${prefix}-maptiler`, apiKey: mapTilerApiKey, mapDesignType: prefix === 'left' ? MapTilerDesign.Streets : MapTilerDesign.StreetsLight, cameraPosition: INITIAL_CAMERA });
const longdoState = useLongdoViewState({ id: `camera-sync-${prefix}-longdo`, apiKey: longdoApiKey, mapDesignType: LongdoDesign.Normal, cameraPosition: INITIAL_CAMERA });
const mapplsState = useMapplsViewState({ id: `camera-sync-${prefix}-mappls`, apiKey: mapplsApiKey, mapDesignType: MapplsDesign.Default, cameraPosition: INITIAL_CAMERA });
+ const deckglState = useDeckGLMapViewState({ id: `camera-sync-${prefix}-deckgl`, mapDesignType: DeckGLDesign.Standard, cameraPosition: INITIAL_CAMERA });
return {
maplibre: paneState('maplibre', mapLibreState),
@@ -98,5 +100,6 @@ export function useCameraSyncProviderStates(prefix: 'left' | 'right'): ProviderS
maptiler: paneState('maptiler', mapTilerState),
longdo: paneState('longdo', longdoState),
mappls: paneState('mappls', mapplsState),
+ deckgl: paneState('deckgl', deckglState),
};
}
diff --git a/examples/basic/src/pages/map/camerasync/types.ts b/examples/basic/src/pages/map/camerasync/types.ts
index e11c4af..c6f2755 100644
--- a/examples/basic/src/pages/map/camerasync/types.ts
+++ b/examples/basic/src/pages/map/camerasync/types.ts
@@ -24,7 +24,8 @@ export type PaneProvider =
| 'tomtom'
| 'maptiler'
| 'longdo'
- | 'mappls';
+ | 'mappls'
+ | 'deckgl';
export interface CameraLocationInfo {
name: string;
diff --git a/examples/basic/src/pages/map/design/MapDesignPage.tsx b/examples/basic/src/pages/map/design/MapDesignPage.tsx
index 4698c76..6bd8098 100644
--- a/examples/basic/src/pages/map/design/MapDesignPage.tsx
+++ b/examples/basic/src/pages/map/design/MapDesignPage.tsx
@@ -31,6 +31,7 @@ const DESIGN_OPTIONS_LOADERS: Record Promise> =
tomtom: () => import('../../../providers/designOptions/tomtomDesignOptions').then(m => m.TOMTOM_DESIGNS),
longdo: () => import('../../../providers/designOptions/longdoDesignOptions').then(m => m.LONGDO_DESIGNS),
mappls: () => import('../../../providers/designOptions/mapplsDesignOptions').then(m => m.MAPPLS_DESIGNS),
+ deckgl: () => import('../../../providers/designOptions/deckglDesignOptions').then(m => m.DECKGL_DESIGNS),
};
export function MapDesignPage() {
diff --git a/examples/basic/src/pages/marker/postoffice/PostOfficeMapProvider.tsx b/examples/basic/src/pages/marker/postoffice/PostOfficeMapProvider.tsx
index f3f1c85..cc42ded 100644
--- a/examples/basic/src/pages/marker/postoffice/PostOfficeMapProvider.tsx
+++ b/examples/basic/src/pages/marker/postoffice/PostOfficeMapProvider.tsx
@@ -1,4 +1,4 @@
-import { useMemo, type ReactNode } from 'react';
+import { lazy, Suspense, useMemo, type ReactNode } from 'react';
import { useLocation } from 'react-router-dom';
import {
type MapCameraPosition,
@@ -22,6 +22,13 @@ import { MapTilerDesign, MapTilerMapView2D, useMapTilerViewState } from '@mapcon
import '@mapconductor/react-for-maptiler/style.css';
import { LongdoDesign, LongdoMapView2D, useLongdoViewState } from '@mapconductor/react-for-longdo';
import { MapplsDesign, MapplsMapView2D, useMapplsViewState } from '@mapconductor/react-for-mappls';
+// deck.gl は読み込み時に `globalThis.deck` を取り合う(別バージョンが居ると例外)。
+// このモジュールは全プロバイダのページから評価されるので、Longdo など自前の deck.gl を
+// 積んだ SDK のページを壊さないよう、描画コンポーネントだけ遅延読み込みにする。
+import { DeckGLDesign, useDeckGLMapViewState } from '@mapconductor/react-for-deckgl/state';
+const LazyDeckGLMapView = lazy(() =>
+ import('@mapconductor/react-for-deckgl').then(m => ({ default: m.DeckGLMapView })),
+);
import { SingletonMapSlot, useSingletonMapState } from '../../../SingletonMaps';
export type PostOfficeMapState = MapViewStateInterface>;
@@ -261,12 +268,25 @@ function MapplsProvider({ cameraPosition, markerTilingOptions, children }: PostO
});
}
+function DeckGLProviderView({ cameraPosition, markerTilingOptions, children }: PostOfficeMapProviderProps) {
+ const state = useDeckGLMapViewState({ mapDesignType: DeckGLDesign.Standard, cameraPosition });
+ return children({
+ mapViewState: state,
+ renderMapView: (content, onMapClick) => (
+
+ {content}
+
+ ),
+ });
+}
+
export function PostOfficeMapProvider(props: PostOfficeMapProviderProps) {
const pathname = useLocation().pathname;
if (pathname.startsWith('/google-maps')) return ;
if (pathname.startsWith('/maptiler')) return ;
if (pathname.startsWith('/longdo')) return ;
if (pathname.startsWith('/mappls')) return ;
+ if (pathname.startsWith('/deckgl')) return ;
if (pathname.startsWith('/tomtom')) return ;
if (pathname.startsWith('/mapbox')) return ;
if (pathname.startsWith('/leaflet')) return ;
diff --git a/examples/basic/src/pages/marker/streettree/StreetTreeInfoBubble.tsx b/examples/basic/src/pages/marker/streettree/StreetTreeInfoBubble.tsx
new file mode 100644
index 0000000..2afe28c
--- /dev/null
+++ b/examples/basic/src/pages/marker/streettree/StreetTreeInfoBubble.tsx
@@ -0,0 +1,23 @@
+import type { MarkerState } from '@mapconductor/js-sdk-core';
+import { InfoBubble } from '@mapconductor/js-sdk-react';
+import type { StreetTree } from './streetTreeData';
+
+export function StreetTreeInfoBubble({ marker }: { marker: MarkerState }) {
+ const tree = marker.extra as unknown as StreetTree;
+ if (!tree) return null;
+ return (
+
+
+
{tree.species}
+
+
+ 樹高 {tree.heightM.toFixed(1)} m
+ 幹周 {tree.girthCm} cm
+ 行政区 {tree.ward}
+ 路線 {tree.roadName}
+
+
+
+
+ );
+}
diff --git a/examples/basic/src/pages/marker/streettree/StreetTreePage.tsx b/examples/basic/src/pages/marker/streettree/StreetTreePage.tsx
new file mode 100644
index 0000000..b9b5ecf
--- /dev/null
+++ b/examples/basic/src/pages/marker/streettree/StreetTreePage.tsx
@@ -0,0 +1,109 @@
+import { useCallback, useState } from 'react';
+import {
+ MarkerTilingOptions,
+ type MapDesignTypeInterface,
+ type MapViewStateInterface,
+ type MarkerState,
+} from '@mapconductor/js-sdk-core';
+import { Markers } from '@mapconductor/js-sdk-react';
+import { MapLibreDesign } from '@mapconductor/react-for-maplibre';
+import { MapViewContainer } from '../../../MapViewContainer';
+import { ControlPanel } from '../../../components/ControlPanel';
+import { useSampleI18n } from '../../../samples/i18n';
+import { StreetTreeInfoBubble } from './StreetTreeInfoBubble';
+import { browserStreetTreeDataSource } from './streetTreeData';
+import { useStreetTreeMarkers } from './useStreetTreeMarkers';
+
+const INIT_CAMERA = { lat: 35.6812, lng: 139.7671, zoom: 11 };
+
+const MARKER_TILING_OPTIONS: MarkerTilingOptions = {
+ ...MarkerTilingOptions.Default,
+ // Trees are planted a few metres apart along a road, so below street level
+ // most of them sit on top of one another. Thinning them to one per icon
+ // width halves the tile bytes and shows the same map.
+ declutterPx: 14,
+ iconScaleCallback: (_state, zoom) =>
+ zoom > 15 ? 1.4 : zoom > 13 ? 1.0 : zoom > 11 ? 0.7 : 0.5,
+};
+
+export function StreetTreePage() {
+ const { t } = useSampleI18n();
+ const [selected, setSelected] = useState(null);
+ const selectMarker = useCallback((marker: MarkerState) => setSelected(marker), []);
+ const { error, markerStates, trees, species, isLoading } =
+ useStreetTreeMarkers(browserStreetTreeDataSource, selectMarker);
+
+ /**
+ * Swaps in a basemap stripped down to what a tree map needs: land, water,
+ * the major roads and the place names, with the finer streets appearing from
+ * zoom 13. The default style draws 51 transportation line layers, and at this
+ * density they compete with the trees for every pixel.
+ *
+ * MapLibre only, by construction: the design type is provider-specific, and
+ * this one carries a style URL. On any other provider the page runs on
+ * whatever that provider's default is.
+ */
+ const applyTreeStyle = useCallback(
+ (state: MapViewStateInterface>) => {
+ const maplibre = state as unknown as { mapDesignType?: unknown };
+ if (!('mapDesignType' in maplibre)) return;
+ const design = state.mapDesignType as { styleJsonURL?: string } | undefined;
+ if (design && !('styleJsonURL' in design)) return;
+ maplibre.mapDesignType = new MapLibreDesign(
+ 'street-tree',
+ `${import.meta.env.BASE_URL}streettree/street-tree-style.json`,
+ );
+ },
+ [],
+ );
+
+ if (error) {
+ return (
+
+
データの読み込みに失敗しました: {error}
+
+ );
+ }
+
+ return (
+ setSelected(null)}
+ onStateReady={applyTreeStyle}
+ >
+
+ {selected && }
+
+
+ {isLoading
+ ? t({
+ en: 'Loading…',
+ ja: '読み込み中…',
+ 'es-419': 'Cargando…',
+ de: 'Wird geladen…',
+ th: 'กำลังโหลด…',
+ hi: 'लोड हो रहा है…',
+ })
+ : t({
+ en: `${trees?.length ?? 0} trees, ${species?.length ?? 0} species, one colour each. Tap a tree for its record.`,
+ ja: `${trees?.length ?? 0} 本・${species?.length ?? 0} 種、樹種ごとに色分け。タップで詳細が出ます。`,
+ 'es-419': `${trees?.length ?? 0} árboles, ${species?.length ?? 0} especies, un color cada una. Toca un árbol para ver su registro.`,
+ de: `${trees?.length ?? 0} Bäume, ${species?.length ?? 0} Arten, je eine Farbe. Für Details antippen.`,
+ th: `${trees?.length ?? 0} ต้น ${species?.length ?? 0} ชนิด สีละชนิด แตะเพื่อดูรายละเอียด`,
+ hi: `${trees?.length ?? 0} पेड़, ${species?.length ?? 0} प्रजातियाँ, हर एक का एक रंग। विवरण के लिए टैप करें।`,
+ })}
+
+
+
+ );
+}
diff --git a/examples/basic/src/pages/marker/streettree/streetTreeData.ts b/examples/basic/src/pages/marker/streettree/streetTreeData.ts
new file mode 100644
index 0000000..eaab1ca
--- /dev/null
+++ b/examples/basic/src/pages/marker/streettree/streetTreeData.ts
@@ -0,0 +1,113 @@
+/**
+ * Tokyo's street trees: 144,183 of them, from the metropolitan government's
+ * open data.
+ *
+ * A harder shape than the post office set. There are six times as many, they
+ * sit inside one metropolitan area rather than spread over a country, and each
+ * species draws its own colour — so the renderer cannot collapse two trees of
+ * different species that land on the same pixel.
+ *
+ * Species with fewer than a hundred trees are folded into one bucket. The
+ * distribution has a long tail: a hundred species cover 96% of the trees, and
+ * the remaining three hundred would be indistinguishable colours nobody could
+ * read off a legend. The bucket is still the fifth largest group, so it is not
+ * a rounding error being hidden.
+ */
+export interface StreetTree {
+ // MarkerState.extra is Serializable, which wants an index signature: the SDK
+ // carries this across the marker abstraction without knowing what it is.
+ [key: string]: unknown;
+ latitude: number;
+ longitude: number;
+ species: string;
+ speciesIndex: number;
+ /** Height in metres, as recorded in the survey. */
+ heightM: number;
+ /** Trunk circumference in centimetres. */
+ girthCm: number;
+ ward: string;
+ roadName: string;
+}
+
+export interface StreetTreeData {
+ trees: StreetTree[];
+ /** The species table the icon colours are indexed by. */
+ species: string[];
+}
+
+/** Magic, then a version byte the reader checks by length rather than value. */
+const MAGIC = 'TREE';
+const HEADER_BYTES = 5;
+
+/** lat, lon, species, height, girth, ward, road. */
+const RECORD_BYTES = 20;
+
+/**
+ * Reads the packed asset: the magic, three string tables, then one fixed
+ * record per tree, all little-endian.
+ *
+ * The source is a 12 MB Shift-JIS CSV. Parsing that in the browser would
+ * measure CSV parsing rather than the map, and the packed form is 2.8 MB.
+ * android-sdk and ios-sdk read the same bytes.
+ */
+export function decodeStreetTrees(buffer: ArrayBuffer): StreetTreeData {
+ const view = new DataView(buffer);
+ const bytes = new Uint8Array(buffer);
+ const utf8 = new TextDecoder();
+ let at = HEADER_BYTES;
+
+ const magic = utf8.decode(bytes.subarray(0, MAGIC.length));
+ if (magic !== MAGIC) throw new Error('unexpected street tree asset format');
+
+ const table = (): string[] => {
+ const count = view.getUint32(at, true);
+ at += 4;
+ const names: string[] = new Array(count);
+ for (let index = 0; index < count; index++) {
+ const length = view.getUint16(at, true);
+ at += 2;
+ names[index] = utf8.decode(bytes.subarray(at, at + length));
+ at += length;
+ }
+ return names;
+ };
+
+ const species = table();
+ const wards = table();
+ const roads = table();
+
+ const count = view.getUint32(at, true);
+ at += 4;
+ const trees: StreetTree[] = new Array(count);
+ for (let index = 0; index < count; index++) {
+ const speciesIndex = view.getUint16(at + 8, true);
+ trees[index] = {
+ latitude: view.getFloat32(at, true),
+ longitude: view.getFloat32(at + 4, true),
+ speciesIndex,
+ species: species[speciesIndex],
+ heightM: view.getFloat32(at + 10, true),
+ girthCm: view.getUint16(at + 14, true),
+ ward: wards[view.getUint16(at + 16, true)],
+ roadName: roads[view.getUint16(at + 18, true)],
+ };
+ at += RECORD_BYTES;
+ }
+ return { trees, species };
+}
+
+export interface StreetTreeDataSource {
+ load(): Promise;
+}
+
+export function createStreetTreeDataSource(baseUrl: string): StreetTreeDataSource {
+ return {
+ async load() {
+ const response = await fetch(`${baseUrl}streettree/tokyo-trees.bin`);
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
+ return decodeStreetTrees(await response.arrayBuffer());
+ },
+ };
+}
+
+export const browserStreetTreeDataSource = createStreetTreeDataSource(import.meta.env.BASE_URL);
diff --git a/examples/basic/src/pages/marker/streettree/treeIcons.ts b/examples/basic/src/pages/marker/streettree/treeIcons.ts
new file mode 100644
index 0000000..5b3dc7e
--- /dev/null
+++ b/examples/basic/src/pages/marker/streettree/treeIcons.ts
@@ -0,0 +1,69 @@
+import { ImageIcon } from '@mapconductor/js-sdk-core';
+
+/**
+ * One coloured dot per species, shared by every tree of that species.
+ *
+ * Baked once into a canvas. Building an icon per marker would measure icon
+ * generation rather than drawing, and there are 144,183 markers against a
+ * hundred or so species.
+ */
+/**
+ * `sizeCssPx` は **CSS ピクセル**。タイルは 256px の canvas に描かれて 256 CSS px
+ * として表示されるので、ここは devicePixelRatio を掛けない -- 掛けると画面が
+ * 精細なほど大きくなってしまう。
+ *
+ * ios-sdk はポイント、android-sdk は dp で同じ 10 を使う。android は一時期ここだけ
+ * 生ピクセルで作っていて、端末が精細なほど小さく見えていた。
+ */
+export function createSpeciesIcons(count: number, sizeCssPx = 10): ImageIcon[] {
+ return Array.from({ length: count }, (_unused, index) => {
+ const canvas = document.createElement('canvas');
+ canvas.width = sizeCssPx;
+ canvas.height = sizeCssPx;
+ const context = canvas.getContext('2d');
+ if (context) {
+ const radius = sizeCssPx / 2 - 1;
+ context.beginPath();
+ context.arc(sizeCssPx / 2, sizeCssPx / 2, radius, 0, Math.PI * 2);
+ context.fillStyle = speciesColour(index, count);
+ context.fill();
+ context.strokeStyle = 'rgba(0, 0, 0, 0.43)';
+ context.lineWidth = 1;
+ context.stroke();
+ }
+ return new ImageIcon(canvas, {
+ iconSize: sizeCssPx,
+ anchor: { x: 0.5, y: 0.5 },
+ infoAnchor: { x: 0.5, y: 0 },
+ });
+ });
+}
+
+/**
+ * Golden-angle hue rotation, so neighbouring species indices do not come out
+ * as neighbouring colours. The last entry is the "other" bucket, which reads
+ * as grey rather than competing with a named species for a hue.
+ *
+ * Matches android-sdk's StreetTreeIcons and ios-sdk's StreetTreeIcons, so a
+ * species is the same colour on all three.
+ */
+function speciesColour(index: number, count: number): string {
+ if (index === count - 1) return 'rgb(150, 150, 155)';
+ return hsvToCss((index * 137.508) % 360, 0.7, 0.8);
+}
+
+function hsvToCss(hue: number, saturation: number, value: number): string {
+ const sector = hue / 60;
+ const chroma = value * saturation;
+ const second = chroma * (1 - Math.abs((sector % 2) - 1));
+ const [r, g, b] =
+ sector < 1 ? [chroma, second, 0]
+ : sector < 2 ? [second, chroma, 0]
+ : sector < 3 ? [0, chroma, second]
+ : sector < 4 ? [0, second, chroma]
+ : sector < 5 ? [second, 0, chroma]
+ : [chroma, 0, second];
+ const base = value - chroma;
+ const byte = (channel: number) => Math.round((channel + base) * 255);
+ return `rgb(${byte(r)}, ${byte(g)}, ${byte(b)})`;
+}
diff --git a/examples/basic/src/pages/marker/streettree/useStreetTreeMarkers.ts b/examples/basic/src/pages/marker/streettree/useStreetTreeMarkers.ts
new file mode 100644
index 0000000..d8e7a9a
--- /dev/null
+++ b/examples/basic/src/pages/marker/streettree/useStreetTreeMarkers.ts
@@ -0,0 +1,54 @@
+import { useEffect, useMemo, useState } from 'react';
+import {
+ createGeoPoint,
+ createMarkerState,
+ type ImageIcon,
+ type MarkerState,
+} from '@mapconductor/js-sdk-core';
+import { createSpeciesIcons } from './treeIcons';
+import type { StreetTree, StreetTreeDataSource } from './streetTreeData';
+
+interface StreetTreeMarkerResult {
+ error: string | null;
+ markerStates: MarkerState[];
+ trees: StreetTree[] | null;
+ species: string[] | null;
+ isLoading: boolean;
+}
+
+export function useStreetTreeMarkers(
+ dataSource: StreetTreeDataSource,
+ onMarkerClick: (marker: MarkerState) => void,
+): StreetTreeMarkerResult {
+ const [trees, setTrees] = useState(null);
+ const [species, setSpecies] = useState(null);
+ const [icons, setIcons] = useState(null);
+ const [error, setError] = useState(null);
+
+ useEffect(() => {
+ let active = true;
+ dataSource.load().then(data => {
+ if (!active) return;
+ setTrees(data.trees);
+ setSpecies(data.species);
+ setIcons(createSpeciesIcons(data.species.length));
+ }).catch(reason => {
+ if (active) setError(String(reason));
+ });
+ return () => { active = false; };
+ }, [dataSource]);
+
+ const markerStates = useMemo(
+ () => (trees ?? []).map((tree, index) =>
+ createMarkerState({
+ id: String(index),
+ position: createGeoPoint({ latitude: tree.latitude, longitude: tree.longitude }),
+ extra: tree,
+ icon: icons?.[tree.speciesIndex] ?? null,
+ onClick: onMarkerClick,
+ })),
+ [icons, onMarkerClick, trees],
+ );
+
+ return { error, markerStates, trees, species, isLoading: trees === null && error === null };
+}
diff --git a/examples/basic/src/pages/vectorstyle/StyleAdjustmentsPage.tsx b/examples/basic/src/pages/vectorstyle/StyleAdjustmentsPage.tsx
new file mode 100644
index 0000000..a1edfe8
--- /dev/null
+++ b/examples/basic/src/pages/vectorstyle/StyleAdjustmentsPage.tsx
@@ -0,0 +1,226 @@
+import { useCallback, useEffect, useMemo, useState } from 'react';
+import type { MapDesignTypeInterface, MapViewStateInterface } from '@mapconductor/js-sdk-core';
+import { buildStyleRules, createVectorStyle, LayerRole, NO_STYLE_RULES } from '@mapconductor/react-vectorstyle';
+import { VectorTileRasteriser } from '@mapconductor/react-vectortile';
+import { ControlPanel, SliderControl } from '../../components/ControlPanel';
+import { MapViewContainer } from '../../MapViewContainer';
+import { useSampleI18n } from '../../samples/i18n';
+import { showBasemap } from '../common/showBasemap';
+
+const INIT_CAMERA = { lat: 35.6812, lng: 139.7671, zoom: 12 };
+
+/**
+ * OpenStreetMap in the Shortbread schema: layers name a standard source
+ * layer, so a rule can say "roads" without knowing this style's layer ids.
+ * The same document the android and iOS samples adjust.
+ */
+const STYLE_URL = 'https://tiles.versatiles.org/assets/styles/colorful/style.json';
+
+type Preset = 'roads' | 'night' | 'water' | 'asAuthored';
+
+const PRESETS: readonly Preset[] = ['roads', 'night', 'water', 'asAuthored'];
+
+const grey = (level: number) => {
+ const channel = Math.round(Math.max(0, Math.min(1, level)) * 255);
+ return `rgb(${channel},${channel},${channel})`;
+};
+
+/** android の `StylePreset` / iOS の `StylePreset` と同じ 4 つ。 */
+function rulesFor(preset: Preset, roadLightness: number) {
+ const road = grey(roadLightness);
+ switch (preset) {
+ case 'asAuthored':
+ return NO_STYLE_RULES;
+ case 'roads':
+ return buildStyleRules((rules) => {
+ rules.all({ color: '#000000' });
+ rules.role(LayerRole.label, { visible: false });
+ rules.role(LayerRole.roadCasing, { color: grey(0.19) });
+ rules.role(LayerRole.road, { color: road, widthScale: 1.4 });
+ });
+ case 'night':
+ return buildStyleRules((rules) => {
+ rules.all({ colorFilter: { darken: 0.55 } });
+ rules.role(LayerRole.road, { color: road });
+ rules.role(LayerRole.water, { color: 'rgb(10,28,43)' });
+ });
+ case 'water':
+ return buildStyleRules((rules) => {
+ rules.all({ visible: false });
+ rules.role(LayerRole.background, { visible: true, color: grey(0.95) });
+ rules.role(LayerRole.water, { visible: true, color: 'rgb(46,112,184)' });
+ });
+ }
+}
+
+/**
+ * The same adjustments on every backend, through whichever road that backend
+ * can take.
+ *
+ * MapLibre, Mapbox and MapTiler read the style themselves: they are handed
+ * the author's document and then the *differences* each rule change makes,
+ * so moving the slider sets a few hundred paint properties and the map never
+ * reloads a tile. Every other provider here has no vector renderer, and on
+ * the web there is no rasteriser to draw the style into tiles for them yet —
+ * they say so in the diagnostics rather than showing a map that quietly
+ * ignored the rules. android and iOS have one, which is why the same page
+ * there works everywhere.
+ */
+export function StyleAdjustmentsPage() {
+ const { t } = useSampleI18n();
+ // Held, not rebuilt: `createVectorStyle` compares a rasteriser by
+ // identity, so a new one each render would look like a different style
+ // and tear the map down on every frame. `@State` on iOS, `remember` on
+ // android, `useMemo` here.
+ const rasteriser = useMemo(() => new VectorTileRasteriser(), []);
+ const [preset, setPreset] = useState('roads');
+ const [roadLightness, setRoadLightness] = useState(1);
+ const [fromCurrentDesign, setFromCurrentDesign] = useState(false);
+ const [styleJson, setStyleJson] = useState(null);
+ const [failure, setFailure] = useState(null);
+ const [diagnostics, setDiagnostics] = useState([]);
+ const [mapViewState, setMapViewState] =
+ useState> | null>(null);
+ const onStateReady = useCallback(
+ (state: MapViewStateInterface>) => setMapViewState(state),
+ [],
+ );
+
+ // A style *is* the basemap, so the backend's own one comes down while
+ // one is drawn — but only where it has to. `showBasemap` leaves the
+ // three that read styles alone (they replace their own design), and
+ // while adjusting the map's own style nothing is blanked at all: there
+ // the point is the design the backend is already drawing.
+ //
+ // The page's own choice must not follow the shared map onto other pages.
+ useEffect(() => {
+ if (!mapViewState) return;
+ showBasemap(mapViewState, fromCurrentDesign);
+ return () => showBasemap(mapViewState, true);
+ }, [mapViewState, fromCurrentDesign]);
+
+ useEffect(() => {
+ let cancelled = false;
+ fetch(STYLE_URL)
+ .then((response) => response.text())
+ .then((text) => {
+ if (!cancelled) setStyleJson(text);
+ })
+ .catch((error: unknown) => {
+ if (!cancelled) setFailure(String(error));
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, []);
+
+ // A new object on every slider frame, by design: what decides whether the
+ // map reloads is the style's *key*, not its identity. Same rules, same
+ // key, and the installed style takes the difference in place.
+ const style = useMemo(() => {
+ if (!fromCurrentDesign && !styleJson) return null;
+ return createVectorStyle({
+ document: fromCurrentDesign ? 'currentDesign' : { text: styleJson as string },
+ rules: rulesFor(preset, roadLightness),
+ rasteriser,
+ });
+ }, [fromCurrentDesign, styleJson, preset, roadLightness, rasteriser]);
+
+ return (
+
+
+
+ {PRESETS.map((id) => (
+ setPreset(id)}
+ >
+ {t(PRESET_LABELS[id])}
+
+ ))}
+
+
+
+ setFromCurrentDesign(event.target.checked)}
+ />
+
+ {t({
+ en: "Adjust the map's own style",
+ ja: '地図自身のスタイルを調整する',
+ 'es-419': 'Ajustar el estilo propio del mapa',
+ de: 'Den eigenen Stil der Karte anpassen',
+ th: 'ปรับสไตล์ของแผนที่เอง',
+ hi: 'मानचित्र की अपनी शैली समायोजित करें',
+ })}
+
+
+
+
+
+ {/* A rule that matched nothing, an adjustment this backend
+ would not take, a style that could not be read: these all
+ look like "it nearly worked" and nothing else reports them. */}
+ {failure ? {failure}
: null}
+ {diagnostics.map((line) => (
+
+ {line}
+
+ ))}
+
+
+ );
+}
+
+const PRESET_LABELS = {
+ roads: { en: 'Roads', ja: '道路', 'es-419': 'Vías', de: 'Straßen', th: 'ถนน', hi: 'सड़कें' },
+ night: { en: 'Night', ja: 'ナイト', 'es-419': 'Noche', de: 'Nacht', th: 'กลางคืน', hi: 'रात' },
+ water: { en: 'Water', ja: '水域', 'es-419': 'Agua', de: 'Wasser', th: 'น้ำ', hi: 'जल' },
+ asAuthored: {
+ en: 'As authored',
+ ja: '元のまま',
+ 'es-419': 'Como se creó',
+ de: 'Wie erstellt',
+ th: 'ตามต้นฉบับ',
+ hi: 'मूल रूप में',
+ },
+} as const;
diff --git a/examples/basic/src/pages/vectortile/VectorTileLayerPage.tsx b/examples/basic/src/pages/vectortile/VectorTileLayerPage.tsx
new file mode 100644
index 0000000..6dfe40f
--- /dev/null
+++ b/examples/basic/src/pages/vectortile/VectorTileLayerPage.tsx
@@ -0,0 +1,229 @@
+import { useCallback, useEffect, useMemo, useState } from 'react';
+import { type MapDesignTypeInterface, type MapViewStateInterface } from '@mapconductor/js-sdk-core';
+import { VectorTileLayer } from '@mapconductor/react-vectortile';
+import { ControlPanel, SliderControl } from '../../components/ControlPanel';
+import { MapViewContainer } from '../../MapViewContainer';
+import { showBasemap } from '../common/showBasemap';
+import { useSampleI18n } from '../../samples/i18n';
+import type { Phrase } from '../../samples/language';
+import {
+ CATEGORY_ORDER,
+ DEFAULT_PALETTE,
+ TINTED,
+ styleRulesFor,
+ type Category,
+ type ColourCategory,
+ type Palette,
+} from './categories';
+
+const INIT_CAMERA = { lat: 35.6812, lng: 139.7671, zoom: 12 };
+
+/**
+ * OpenStreetMap data in the Shortbread schema, which is what lets the SDK give
+ * every layer a role: a layer names a standard source layer, so the water can
+ * be found without knowing this particular style's layer ids.
+ */
+const STYLE_URL = 'https://tiles.versatiles.org/assets/styles/colorful/style.json';
+
+
+const CATEGORY_LABELS: Record = {
+ water: { en: 'Water', ja: '水域', 'es-419': 'Agua', de: 'Wasser', th: 'แหล่งน้ำ', hi: 'जल' },
+ land: { en: 'Land', ja: '陸地', 'es-419': 'Terreno', de: 'Land', th: 'พื้นดิน', hi: 'भूमि' },
+ street: { en: 'Roads', ja: '道路', 'es-419': 'Carreteras', de: 'Straßen', th: 'ถนน', hi: 'सड़कें' },
+ building: { en: 'Buildings', ja: '建物', 'es-419': 'Edificios', de: 'Gebäude', th: 'อาคาร', hi: 'इमारतें' },
+ label: { en: 'Labels', ja: 'ラベル', 'es-419': 'Etiquetas', de: 'Beschriftungen', th: 'ป้ายชื่อ', hi: 'लेबल' },
+};
+
+/**
+ * Renders a MapLibre vector style as raster tiles, and repaints it live.
+ *
+ * The point of the colour pickers is not the colours. Changing them replaces
+ * the style and re-rasterises the tiles already in memory — no vector tile is
+ * fetched again, because the geometry did not change, only the paint applied to
+ * it. That is what makes this practical on backends that cannot read a vector
+ * style at all: they see an ordinary raster layer throughout.
+ */
+export function VectorTileLayerPage() {
+ const { t } = useSampleI18n();
+ const [baseStyle, setBaseStyle] = useState(null);
+ const [failure, setFailure] = useState(null);
+ const [palette, setPalette] = useState(DEFAULT_PALETTE);
+ const [hidden, setHidden] = useState>({
+ water: false,
+ land: false,
+ street: false,
+ building: false,
+ label: false,
+ });
+ const [strength, setStrength] = useState(0.6);
+ const [opacity, setOpacity] = useState(1);
+ const [diagnostics, setDiagnostics] = useState([]);
+ const [asBasemap, setAsBasemap] = useState(false);
+ const [mapViewState, setMapViewState] =
+ useState> | null>(null);
+ const onStateReady = useCallback(
+ (state: MapViewStateInterface>) => setMapViewState(state),
+ [],
+ );
+
+ useEffect(() => {
+ if (!mapViewState) return;
+ showBasemap(mapViewState, !asBasemap);
+ // The page's own choice must not follow the singleton map onto other pages.
+ return () => showBasemap(mapViewState, true);
+ }, [mapViewState, asBasemap]);
+
+ useEffect(() => {
+ let cancelled = false;
+ fetch(STYLE_URL)
+ .then((response) => response.json())
+ .then((json: object) => {
+ if (!cancelled) setBaseStyle(json);
+ })
+ .catch((error: unknown) => {
+ if (!cancelled) setFailure(String(error));
+ });
+ return () => {
+ cancelled = true;
+ };
+ }, []);
+
+ /**
+ * The knobs, as the rules handed to the layer: what to leave out and what
+ * to blend towards. Memoised on the inputs that actually change them --
+ * a slider emits on every frame, and compiling a 257-layer style per
+ * frame for an unchanged palette would be waste.
+ *
+ * `undefined` rather than an empty rule set when nothing is adjusted: the
+ * layer then never loads the compiler at all.
+ */
+ const rules = useMemo(
+ () => styleRulesFor(hidden, palette, strength),
+ [hidden, palette, strength],
+ );
+
+ return (
+
+ {baseStyle ? (
+
+ ) : null}
+
+
+ setAsBasemap(event.target.checked)}
+ />
+
+ {t({
+ en: 'As basemap (hide the provider\'s own)',
+ ja: 'ベースマップとして使う(プロバイダの地図を隠す)',
+ 'es-419': 'Como mapa base (ocultar el del proveedor)',
+ de: 'Als Basiskarte (die des Anbieters ausblenden)',
+ th: 'ใช้เป็นแผนที่ฐาน (ซ่อนของผู้ให้บริการ)',
+ hi: 'बेसमैप के रूप में (प्रदाता का छिपाएँ)',
+ })}
+
+
+ {CATEGORY_ORDER.map((category) => (
+
+
+
+
+ setHidden((current) => ({
+ ...current,
+ [category]: !event.target.checked,
+ }))
+ }
+ />
+ {t(CATEGORY_LABELS[category])}
+
+
+ {TINTED.includes(category as ColourCategory) ? (
+
+ setPalette((current) => ({
+ ...current,
+ [category]: event.target.value,
+ }))
+ }
+ />
+ ) : null}
+
+ ))}
+
+
+
+ {failure
+ ? t({
+ en: `The style could not be loaded: ${failure}`,
+ ja: `スタイルを読み込めませんでした: ${failure}`,
+ 'es-419': `No se pudo cargar el estilo: ${failure}`,
+ de: `Der Stil konnte nicht geladen werden: ${failure}`,
+ th: `ไม่สามารถโหลดสไตล์ได้: ${failure}`,
+ hi: `स्टाइल लोड नहीं हो सकी: ${failure}`,
+ })
+ : t({
+ en: 'Recolouring reuses the vector tiles already fetched — only the rasterisation is redone. Unticking a category hides its layers, so they are never drawn. Labels ride on a second, transparent layer above the ground.',
+ ja: '色の変更は取得済みのベクタータイルを再利用し、ラスタライズだけをやり直します。チェックを外した種別はレイヤーごと非表示になり、描画されません。ラベルは地物の上に重なる透明なレイヤーに描かれます。',
+ 'es-419': 'Recolorear reutiliza las teselas vectoriales ya descargadas: solo se rehace la rasterización. Las etiquetas van en una segunda capa transparente sobre el terreno.',
+ de: 'Das Umfärben nutzt die bereits geladenen Vektorkacheln weiter — nur die Rasterung wird wiederholt. Beschriftungen liegen auf einer zweiten, transparenten Ebene darüber.',
+ th: 'การเปลี่ยนสีใช้เวกเตอร์ไทล์ที่ดาวน์โหลดไว้แล้ว โดยทำแรสเตอร์ใหม่เท่านั้น ป้ายชื่อวาดบนเลเยอร์โปร่งใสอีกชั้นที่ซ้อนอยู่ด้านบน',
+ hi: 'रंग बदलने पर पहले से लाई गई वेक्टर टाइलें ही दोबारा उपयोग होती हैं — केवल रैस्टराइज़ेशन दोहराया जाता है। लेबल ऊपर एक अलग पारदर्शी लेयर पर बनते हैं।',
+ })}
+
+ {diagnostics.length > 0 ? (
+ {diagnostics.join(' / ')}
+ ) : null}
+
+
+ );
+}
diff --git a/examples/basic/src/pages/vectortile/categories.ts b/examples/basic/src/pages/vectortile/categories.ts
new file mode 100644
index 0000000..ac082d9
--- /dev/null
+++ b/examples/basic/src/pages/vectortile/categories.ts
@@ -0,0 +1,88 @@
+import { LayerRole, buildStyleRules, NO_STYLE_RULES, type StyleRules } from '@mapconductor/react-vectorstyle';
+
+/** A category that can be painted as well as switched off. */
+export type ColourCategory = 'water' | 'land' | 'street' | 'building';
+
+/** Everything the page can switch off, painted or not. */
+export type Category = ColourCategory | 'label';
+
+export type Palette = Record;
+
+/**
+ * What the sample's knobs are, and the roles each one reaches.
+ *
+ * Several roles per knob, because a knob is a thing on the map and a role is
+ * a thing in the style. What a reader calls "land" is the background the map
+ * is drawn on (`background`) *plus* the landuse patches on it (`land`) *plus*
+ * the sites (`landuse`) — paint or hide only the middle one and the ground
+ * stays exactly as it was. "Water" is both the areas and the rivers
+ * (`waterway`).
+ *
+ * Roles rather than the style's own layer ids: the same word means the same
+ * thing in someone else's style, which is the point of them. android-sdk の
+ * `VectorTileCategory` と ios-sdk の `VectorTileCategory` も同じ並び・同じ
+ * 既定色。
+ */
+export const ROLES_BY_CATEGORY: Record = {
+ water: [LayerRole.water, LayerRole.waterway],
+ land: [LayerRole.background, LayerRole.land, LayerRole.landuse],
+ // A casing is a road too, so this reaches it.
+ street: [LayerRole.road],
+ building: [LayerRole.building],
+ // Every symbol layer: place names, POIs, road shields, the one-way
+ // arrows painted along a street. On the raster path these are the
+ // transparent overlay, so switching them off empties that half.
+ label: [LayerRole.label],
+};
+
+export const CATEGORY_ORDER: Category[] = ['water', 'land', 'street', 'building', 'label'];
+
+/**
+ * The categories with a colour, in order.
+ *
+ * Labels are not among them. Not an oversight: the tint pulls every matched
+ * layer towards one colour, and doing that to text would flatten the whole
+ * legend — the green of a park label, the blue of a river's — by merely
+ * opening the page. They can still be switched off, which is what a label
+ * knob is actually wanted for.
+ */
+export const TINTED: ColourCategory[] = ['water', 'land', 'street', 'building'];
+
+export const DEFAULT_PALETTE: Palette = {
+ water: '#3a7ca5',
+ land: '#f2efe6',
+ street: '#ffffff',
+ building: '#d9d0c9',
+};
+
+/**
+ * The knobs as the rules handed to the layer.
+ *
+ * Unticking a category switches its layers off in the document the renderer
+ * is given, so they are not drawn at all. A colour *blends* rather than
+ * replaces: a real basemap tells forest from grass from farmland with a dozen
+ * greens, and flattening each category to one picked colour throws that away
+ * — the map stops looking like a map. `strength` of 0 leaves the style as its
+ * author wrote it, and nothing is compiled at all.
+ */
+export function styleRulesFor(
+ hidden: Record,
+ palette: Palette,
+ strength: number,
+): StyleRules | undefined {
+ const gone = CATEGORY_ORDER.filter((category) => hidden[category]);
+ if (gone.length === 0 && strength <= 0) return undefined;
+ const rules = buildStyleRules((r) => {
+ for (const category of gone) {
+ for (const role of ROLES_BY_CATEGORY[category]) r.role(role, { visible: false });
+ }
+ if (strength <= 0) return;
+ for (const category of TINTED) {
+ if (hidden[category]) continue;
+ for (const role of ROLES_BY_CATEGORY[category]) {
+ r.role(role, { colorFilter: { mix: { color: palette[category], amount: strength } } });
+ }
+ }
+ });
+ return rules.json === NO_STYLE_RULES.json ? undefined : rules;
+}
diff --git a/examples/basic/src/providers/designOptions/deckglDesignOptions.ts b/examples/basic/src/providers/designOptions/deckglDesignOptions.ts
new file mode 100644
index 0000000..82e6d81
--- /dev/null
+++ b/examples/basic/src/providers/designOptions/deckglDesignOptions.ts
@@ -0,0 +1,22 @@
+import { DeckGLDesign } from '@mapconductor/react-for-deckgl';
+import { GSI_STANDARD_ATTRIBUTION_RULES } from '../../gsiAttributions';
+import type { MapDesignOption } from './types';
+
+const GSI_STANDARD_DESIGN = new DeckGLDesign({
+ id: 'gsi-standard',
+ tileUrl: 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
+ tileSize: 256,
+ minZoom: 5,
+ maxZoom: 18,
+ backgroundColor: '#f2efe9',
+ attributionRules: GSI_STANDARD_ATTRIBUTION_RULES,
+});
+
+export const DECKGL_DESIGNS: MapDesignOption[] = [
+ { label: 'Standard', design: DeckGLDesign.Standard },
+ { label: 'Light', design: DeckGLDesign.Light },
+ { label: 'Dark', design: DeckGLDesign.Dark },
+ { label: 'Satellite', design: DeckGLDesign.Satellite },
+ { label: 'GSI Standard', design: GSI_STANDARD_DESIGN },
+ { label: 'None', design: DeckGLDesign.None },
+];
diff --git a/examples/basic/src/providers/singleton/ArcGISSingletonView.tsx b/examples/basic/src/providers/singleton/ArcGISSingletonView.tsx
index 2087089..aaa9f5f 100644
--- a/examples/basic/src/providers/singleton/ArcGISSingletonView.tsx
+++ b/examples/basic/src/providers/singleton/ArcGISSingletonView.tsx
@@ -12,6 +12,8 @@ export default function ArcGISSingletonView({ state, content, useSceneView }: {
+ {content && {content.children} }
+
+ );
+}
diff --git a/examples/basic/src/providers/singleton/HereSingletonView.tsx b/examples/basic/src/providers/singleton/HereSingletonView.tsx
index 40eba08..5f146c9 100644
--- a/examples/basic/src/providers/singleton/HereSingletonView.tsx
+++ b/examples/basic/src/providers/singleton/HereSingletonView.tsx
@@ -19,6 +19,8 @@ export default function HereSingletonView({ state, content }: {
state={state}
platform={platform}
cameraRestriction={content?.cameraRestriction}
+ mapStyle={content?.mapStyle}
+ onStyleDiagnostics={content?.onStyleDiagnostics}
onMapClick={content?.onMapClick}
onCameraMoveStart={content?.onCameraMoveStart}
onCameraMove={content?.onCameraMove}
diff --git a/examples/basic/src/providers/singleton/LeafletSingletonView.tsx b/examples/basic/src/providers/singleton/LeafletSingletonView.tsx
index d3aa827..f073649 100644
--- a/examples/basic/src/providers/singleton/LeafletSingletonView.tsx
+++ b/examples/basic/src/providers/singleton/LeafletSingletonView.tsx
@@ -11,6 +11,8 @@ export default function LeafletSingletonView({ state, content }: {
void;
}
diff --git a/examples/basic/src/providers/types.ts b/examples/basic/src/providers/types.ts
index a603c19..35f44a1 100644
--- a/examples/basic/src/providers/types.ts
+++ b/examples/basic/src/providers/types.ts
@@ -7,6 +7,7 @@ import type {
MapDesignTypeInterface,
MapViewStateInterface,
MarkerTilingOptions,
+ MapViewStyle,
} from '@mapconductor/js-sdk-core';
import type { InitialCamera } from '../common';
@@ -28,4 +29,7 @@ export interface ProviderViewProps {
restrictBounds?: GeoRectBounds;
/** 矩形 + minZoom/maxZoom を丸ごと指定したいページ向け。restrictBounds より優先。 */
cameraRestriction?: CameraRestriction | null;
+ /** 地図の見た目そのもの。`createVectorStyle()` が作る。 */
+ mapStyle?: MapViewStyle | null;
+ onStyleDiagnostics?: (diagnostics: readonly string[]) => void;
}
diff --git a/examples/basic/src/samples/documentation/index.ts b/examples/basic/src/samples/documentation/index.ts
index bd46673..3be4ffe 100644
--- a/examples/basic/src/samples/documentation/index.ts
+++ b/examples/basic/src/samples/documentation/index.ts
@@ -28,6 +28,7 @@ import polygonGeodesic from './pages/polygon-geodesic';
import polygonHole from './pages/polygon-hole';
import groundImage from './pages/ground-image';
import rasterLayer from './pages/raster-layer';
+import vectorTile from './pages/vector-tile';
import infoBubbleSimple from './pages/info-bubble-simple';
import infoBubbleStyled from './pages/info-bubble-styled';
import infoBubbleMultiple from './pages/info-bubble-multiple';
@@ -63,6 +64,7 @@ const DOCUMENTATION: Record = {
'polygon-hole': polygonHole,
'ground-image': groundImage,
'raster-layer': rasterLayer,
+ 'vector-tile': vectorTile,
'info-bubble-simple': infoBubbleSimple,
'info-bubble-styled': infoBubbleStyled,
'info-bubble-multiple': infoBubbleMultiple,
diff --git a/examples/basic/src/samples/documentation/pages/vector-tile.ts b/examples/basic/src/samples/documentation/pages/vector-tile.ts
new file mode 100644
index 0000000..16c407d
--- /dev/null
+++ b/examples/basic/src/samples/documentation/pages/vector-tile.ts
@@ -0,0 +1,55 @@
+import type { SamplePageDoc } from '../types';
+
+const doc: SamplePageDoc = {
+ code: `
+
+ `,
+ state: `const [palette, setPalette] = useState({
+ water: '#3a7ca5',
+ land: '#f2efe6',
+ street: '#ffffff',
+ building: '#d9d0c9',
+});
+// A rule reaches layers by role, so the same words work in someone
+// else's style. mix blends each layer's own colour toward the picked
+// one; visible: false leaves the layers out of the document, so they
+// are not drawn at all.
+const rules = buildStyleRules((r) => {
+ r.role(LayerRole.water, { colorFilter: { mix: { color: palette.water, amount: strength } } });
+ r.role(LayerRole.building, { visible: false });
+});`,
+ explanation: {
+ en: [
+ 'Draws a MapLibre vector style on any backend by rasterising it in the browser and serving the result as ordinary raster tiles.',
+ 'The backend never sees a vector style, which is what makes this work on Google Maps, MapKit, Cesium and the rest — none of them can read one.',
+ 'Changing a colour replaces the style and re-rasterises the vector tiles already in memory. Nothing is fetched again: the geometry did not change, only the paint applied to it. Symbol layers are not drawn, because placing labels without collisions needs to see neighbouring tiles.',
+ ],
+ ja: [
+ 'ブラウザ上でMapLibreのベクタースタイルをラスタライズし、通常のラスタータイルとして配信することで、どのバックエンドでもベクタースタイルを描画します。',
+ 'バックエンドはベクタースタイルを一切見ません。だからこそ、それを読めないGoogle Maps・MapKit・Cesiumなどでも動作します。',
+ '色を変更するとスタイルを差し替え、すでにメモリ上にあるベクタータイルを再ラスタライズします。ジオメトリは変わらず塗りだけが変わるため、再取得は発生しません。ラベルの衝突判定には隣接タイルを見る必要があるため、シンボルレイヤーは描画されません。',
+ ],
+ 'es-419': [
+ 'Dibuja un estilo vectorial de MapLibre en cualquier backend rasterizándolo en el navegador y sirviéndolo como teselas ráster comunes.',
+ 'El backend nunca ve un estilo vectorial, y por eso esto funciona en Google Maps, MapKit, Cesium y los demás, que no pueden leerlo.',
+ 'Cambiar un color reemplaza el estilo y vuelve a rasterizar las teselas vectoriales que ya están en memoria. No se descarga nada de nuevo: la geometría no cambió, solo el pintado. Las capas de símbolos no se dibujan, porque colocar etiquetas sin colisiones exige ver las teselas vecinas.',
+ ],
+ de: [
+ 'Zeichnet einen MapLibre-Vektorstil auf jedem Backend, indem er im Browser gerastert und als gewöhnliche Rasterkacheln ausgeliefert wird.',
+ 'Das Backend sieht nie einen Vektorstil — deshalb funktioniert das auch mit Google Maps, MapKit, Cesium und allen anderen, die keinen lesen können.',
+ 'Eine Farbänderung ersetzt den Stil und rastert die bereits geladenen Vektorkacheln neu. Nichts wird erneut geladen: die Geometrie blieb gleich, nur die Farbgebung änderte sich. Symbolebenen werden nicht gezeichnet, da kollisionsfreie Beschriftung die Nachbarkacheln kennen müsste.',
+ ],
+ th: [
+ 'วาดสไตล์เวกเตอร์ของ MapLibre บนแบ็กเอนด์ใดก็ได้ โดยแรสเตอร์ในเบราว์เซอร์แล้วส่งออกเป็นไทล์ราสเตอร์ธรรมดา',
+ 'แบ็กเอนด์ไม่เคยเห็นสไตล์เวกเตอร์เลย จึงใช้งานได้กับ Google Maps, MapKit, Cesium และตัวอื่นที่อ่านสไตล์เวกเตอร์ไม่ได้',
+ 'การเปลี่ยนสีจะแทนที่สไตล์และแรสเตอร์เวกเตอร์ไทล์ที่มีอยู่ในหน่วยความจำใหม่ ไม่มีการดาวน์โหลดซ้ำ เพราะเรขาคณิตไม่เปลี่ยน เปลี่ยนแค่สีที่ทาลงไป เลเยอร์สัญลักษณ์จะไม่ถูกวาด เพราะการวางป้ายโดยไม่ชนกันต้องมองเห็นไทล์ข้างเคียง',
+ ],
+ hi: [
+ 'ब्राउज़र में रैस्टराइज़ करके और परिणाम को सामान्य रास्टर टाइलों के रूप में परोसकर किसी भी बैकएंड पर MapLibre वेक्टर स्टाइल बनाता है।',
+ 'बैकएंड कभी वेक्टर स्टाइल नहीं देखता — इसीलिए यह Google Maps, MapKit, Cesium और उन सभी पर काम करता है जो उसे पढ़ नहीं सकते।',
+ 'रंग बदलने पर स्टाइल बदल जाती है और मेमोरी में मौजूद वेक्टर टाइलें दोबारा रैस्टराइज़ होती हैं। कुछ भी दोबारा नहीं लाया जाता: ज्यामिति वही रही, केवल रंग बदला। सिंबल लेयर नहीं बनाई जातीं, क्योंकि बिना टकराव के लेबल रखने के लिए पड़ोसी टाइलें देखनी पड़ती हैं।',
+ ],
+ },
+};
+
+export default doc;
diff --git a/examples/basic/src/samples/sampleRegistry.ts b/examples/basic/src/samples/sampleRegistry.ts
index 8d667b5..3659b24 100644
--- a/examples/basic/src/samples/sampleRegistry.ts
+++ b/examples/basic/src/samples/sampleRegistry.ts
@@ -31,6 +31,7 @@ export const SAMPLE_PAGES: SamplePageDefinition[] = [
{ id: 'marker-animation', label: { en: 'Marker Animation', ja: 'マーカーアニメーション', 'es-419': 'Animación de marcadores', de: 'Marker-Animation', th: 'แอนิเมชันมาร์กเกอร์', hi: 'मार्कर एनिमेशन' }, group: 'Marker' },
{ id: 'post-office', label: { en: 'Post Office', ja: '郵便局', 'es-419': 'Oficinas postales', de: 'Postfilialen', th: 'ที่ทำการไปรษณีย์', hi: 'डाकघर' }, group: 'Marker', unavailableProviders: ['google-maps-3d'] },
{ id: 'post-office-cluster', label: { en: 'Post Office Cluster', ja: '郵便局クラスタリング', 'es-419': 'Agrupación de oficinas postales', de: 'Postfilialen-Clustering', th: 'การจัดกลุ่มที่ทำการไปรษณีย์', hi: 'डाकघरों की क्लस्टरिंग' }, group: 'Marker' },
+ { id: 'street-tree', label: { en: 'Street Trees', ja: '街路樹', 'es-419': 'Árboles urbanos', de: 'Straßenbäume', th: 'ต้นไม้ริมถนน', hi: 'सड़क के पेड़' }, group: 'Marker', unavailableProviders: ['google-maps-3d'] },
{ id: 'circle', label: { en: 'Circle', ja: '円', 'es-419': 'Círculo', de: 'Kreis', th: 'วงกลม', hi: 'वृत्त' }, group: 'Shape' },
{ id: 'polyline', label: { en: 'Polyline', ja: 'ポリライン', 'es-419': 'Polilínea', de: 'Polylinie', th: 'โพลีไลน์', hi: 'पॉलीलाइन' }, group: 'Shape' },
{ id: 'polyline-click', label: { en: 'Polyline Click', ja: 'ポリラインのクリック', 'es-419': 'Clic en polilínea', de: 'Polylinien-Klick', th: 'การคลิกโพลีไลน์', hi: 'पॉलीलाइन क्लिक' }, group: 'Shape' },
@@ -40,6 +41,8 @@ export const SAMPLE_PAGES: SamplePageDefinition[] = [
{ id: 'polygon-hole', label: { en: 'Polygon Hole', ja: '穴付きポリゴン', 'es-419': 'Polígono con huecos', de: 'Polygon mit Loch', th: 'โพลีกอนแบบมีรู', hi: 'छेद वाला पॉलीगॉन' }, group: 'Shape', unavailableProviders: ['google-maps-3d'] },
{ id: 'ground-image', label: { en: 'Ground Image', ja: '地表画像', 'es-419': 'Imagen sobre el terreno', de: 'Bodenbild', th: 'ภาพบนพื้นผิว', hi: 'ग्राउंड इमेज' }, group: 'Overlay', unavailableProviders: ['google-maps-3d'] },
{ id: 'raster-layer', label: { en: 'Raster Layer', ja: 'ラスターレイヤー', 'es-419': 'Capa ráster', de: 'Rasterebene', th: 'เลเยอร์ราสเตอร์', hi: 'रास्टर लेयर' }, group: 'Overlay', unavailableProviders: ['google-maps-3d'] },
+ { id: 'vector-tile', label: { en: 'Vector Tile Layer', ja: 'ベクタータイルレイヤー', 'es-419': 'Capa de teselas vectoriales', de: 'Vektorkachel-Ebene', th: 'เลเยอร์เวกเตอร์ไทล์', hi: 'वेक्टर टाइल लेयर' }, group: 'Overlay', unavailableProviders: ['google-maps-3d'] },
+ { id: 'style-adjustments', label: { en: 'Style Adjustments', ja: 'スタイル調整', 'es-419': 'Ajustes de estilo', de: 'Stil-Anpassungen', th: 'การปรับแต่งสไตล์', hi: 'स्टाइल समायोजन' }, group: 'Overlay', unavailableProviders: ['google-maps-3d'] },
{ id: 'info-bubble-simple', label: { en: 'Simple Bubble', ja: 'シンプル吹き出し', 'es-419': 'Globo simple', de: 'Einfache Sprechblase', th: 'บับเบิลอย่างง่าย', hi: 'साधारण बबल' }, group: 'Info Bubble' },
{ id: 'info-bubble-styled', label: { en: 'Styled Bubble', ja: 'スタイル付き吹き出し', 'es-419': 'Globo con estilo', de: 'Gestaltete Sprechblase', th: 'บับเบิลแบบมีสไตล์', hi: 'स्टाइल वाला बबल' }, group: 'Info Bubble' },
{ id: 'info-bubble-multiple', label: { en: 'Multiple Bubbles', ja: '複数の吹き出し', 'es-419': 'Varios globos', de: 'Mehrere Sprechblasen', th: 'บับเบิลหลายอัน', hi: 'कई बबल' }, group: 'Info Bubble' },
@@ -90,6 +93,7 @@ export function getProviderLabel(provider: string | undefined): string {
case 'maptiler': return 'MapTiler';
case 'longdo': return 'Longdo';
case 'mappls': return 'Mappls';
+ case 'deckgl': return 'deck.gl';
default: return 'MapLibre';
}
}
diff --git a/examples/basic/vite.config.ts b/examples/basic/vite.config.ts
index 75df7dd..5f76169 100644
--- a/examples/basic/vite.config.ts
+++ b/examples/basic/vite.config.ts
@@ -88,6 +88,10 @@ export default defineConfig({
define: {
CESIUM_BASE_URL: JSON.stringify(cesiumStaticPath),
},
+ // @mapconductor/vectortile renders in a module Worker, and Vite's default
+ // worker format (iife) cannot code-split. Only the production build trips
+ // on this — dev serves module workers natively.
+ worker: { format: 'es' },
plugins: [react(), cesiumStaticAssets(), mapconductorTileServiceWorker(), ...(useHttps ? [mkcert()] : [])],
resolve: {
dedupe: ['react', 'react-dom', '@mapconductor/js-sdk-core'],
diff --git a/examples/reactnative-basic/ios/Podfile b/examples/reactnative-basic/ios/Podfile
index 1bfcf00..90a551f 100644
--- a/examples/reactnative-basic/ios/Podfile
+++ b/examples/reactnative-basic/ios/Podfile
@@ -49,6 +49,12 @@ target 'MapConductorBasic' do
# consumed as CocoaPods source pods (not vendored prebuilt xcframeworks), so the real GoogleMaps
# pod gets installed fresh by CocoaPods instead of being statically embedded by us - autolinking
# only covers npm packages, so these path pods must be declared explicitly.
+ # CTilePng は MapConductorCore の依存だが、`:path` のローカル pod は
+ # 依存も `:path` で名指ししないと解決できない(CocoaPods は trunk を見る)。
+ # `:modular_headers` が要る: Swift から `import CTilePng` するには C の pod が
+ # モジュールマップを持っていないといけない。CocoaPods は static library の
+ # ときだけこれを強制する(まさに RN の構成)。
+ pod 'CTilePng', :path => '../../../../ios-sdk/ios-sdk-core', :modular_headers => true
pod 'MapConductorCore', :path => '../../../../ios-sdk/ios-sdk-core'
pod 'MapConductorForGoogleMaps', :path => '../../../../ios-sdk/ios-for-googlemaps'
# MapConductorForArcGIS is also a path pod for the same reason. Esri publishes no podspec of
@@ -61,6 +67,9 @@ target 'MapConductorBasic' do
pod 'ArcGIS', :podspec => '../../../../ios-sdk/ios-for-arcgis/ArcGIS.podspec'
pod 'MapConductorForArcGIS', :path => '../../../../ios-sdk/ios-for-arcgis'
pod 'MapConductorMarkerClustering', :path => '../../../../ios-sdk/ios-marker-clustering'
+ # CTilePng と同じ理由(Swift から import する ObjC は別 pod +
+ # modular_headers が要る)。
+ pod 'CMapLibreStyleTry', :path => '../../../../ios-sdk/ios-for-maplibre', :modular_headers => true
pod 'MapConductorForMapLibre', :path => '../../../../ios-sdk/ios-for-maplibre'
# 雛形。実 SDK を持たないので**プロバイダの選択肢には出さない**が、pod は残す。
# `@mapconductor/reactnative-for-template` の autolinking と合わせて、雛形の
diff --git a/examples/reactnative-basic/ios/Podfile.lock b/examples/reactnative-basic/ios/Podfile.lock
index 43d5296..2cdbae1 100644
--- a/examples/reactnative-basic/ios/Podfile.lock
+++ b/examples/reactnative-basic/ios/Podfile.lock
@@ -1,5 +1,7 @@
PODS:
- ArcGIS (300.1.0)
+ - CMapLibreStyleTry (1.3.1)
+ - CTilePng (1.3.1)
- EXConstants (57.0.11):
- ExpoModulesCore
- Expo (57.0.13):
@@ -87,7 +89,8 @@ PODS:
- MapboxCommon (= 24.28.2)
- MapboxCoreMaps (= 11.28.2)
- Turf (= 4.0.0)
- - MapConductorCore (1.3.1)
+ - MapConductorCore (1.3.1):
+ - CTilePng
- MapConductorForArcGIS (1.3.1):
- ArcGIS (= 300.1.0)
- MapConductorCore
@@ -101,6 +104,7 @@ PODS:
- MapboxMaps (~> 11.26)
- MapConductorCore
- MapConductorForMapLibre (1.3.1):
+ - CMapLibreStyleTry
- MapConductorCore
- MapLibre (~> 6.20)
- MapConductorForMapTiler (1.3.1):
@@ -117,12 +121,12 @@ PODS:
- MapConductorCore
- MapConductorMarkerClustering (1.3.1):
- MapConductorCore
- - MapConductorReactForArcGIS (0.2.0):
+ - MapConductorReactForArcGIS (0.2.1):
- MapConductorForArcGIS (~> 1.3.0)
- MapConductorReactMarkerClustering
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactForGoogleMaps (0.2.0):
+ - MapConductorReactForGoogleMaps (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorForGoogleMaps (~> 1.3.0)
- MapConductorReactMarkerClustering
@@ -134,21 +138,21 @@ PODS:
- MapConductorReactMarkerClustering
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactForMapbox (0.2.0):
+ - MapConductorReactForMapbox (0.2.1):
- MapboxMaps (~> 11.26)
- MapConductorCore (~> 1.3.0)
- MapConductorForMapbox (~> 1.3.0)
- MapConductorReactMarkerClustering
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactForMapLibre (0.2.0):
- - MapConductorCore (~> 1.3.0)
- - MapConductorForMapLibre (~> 1.3.0)
+ - MapConductorReactForMapLibre (0.2.1):
+ - MapConductorCore
+ - MapConductorForMapLibre
- MapConductorReactMarkerClustering
- MapConductorReactNativeCore
- MapLibre (~> 6.20)
- React-Core
- - MapConductorReactForMapTiler (0.2.0):
+ - MapConductorReactForMapTiler (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorForMapTiler (~> 1.3.0)
- MapConductorReactMarkerClustering
@@ -160,28 +164,28 @@ PODS:
- MapConductorForTemplate (~> 1.3.0)
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactForTomTom (0.2.0):
+ - MapConductorReactForTomTom (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorForTomTom (~> 1.3.0)
- MapConductorReactMarkerClustering
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactGeoJSONLayer (0.2.0):
+ - MapConductorReactGeoJSONLayer (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorGeoJSON (~> 1.3.0)
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactHeatmap (0.2.0):
+ - MapConductorReactHeatmap (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorHeatmap (~> 1.3.0)
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactMarkerClustering (0.2.0):
+ - MapConductorReactMarkerClustering (0.2.1):
- MapConductorCore (~> 1.3.0)
- MapConductorMarkerClustering (~> 1.3.0)
- MapConductorReactNativeCore
- React-Core
- - MapConductorReactNativeCore (0.2.0):
+ - MapConductorReactNativeCore (0.2.1):
- MapConductorCore (~> 1.3.0)
- React-callinvoker
- React-Core
@@ -2183,6 +2187,8 @@ PODS:
DEPENDENCIES:
- ArcGIS (from `../../../../ios-sdk/ios-for-arcgis/ArcGIS.podspec`)
+ - CMapLibreStyleTry (from `../../../../ios-sdk/ios-for-maplibre`)
+ - CTilePng (from `../../../../ios-sdk/ios-sdk-core`)
- EXConstants (from `../../../node_modules/expo-constants/ios`)
- Expo (from `../../../node_modules/expo`)
- ExpoAsset (from `../../../node_modules/expo-asset/ios`)
@@ -2323,6 +2329,10 @@ SPEC REPOS:
EXTERNAL SOURCES:
ArcGIS:
:podspec: "../../../../ios-sdk/ios-for-arcgis/ArcGIS.podspec"
+ CMapLibreStyleTry:
+ :path: "../../../../ios-sdk/ios-for-maplibre"
+ CTilePng:
+ :path: "../../../../ios-sdk/ios-sdk-core"
EXConstants:
:path: "../../../node_modules/expo-constants/ios"
Expo:
@@ -2575,6 +2585,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
ArcGIS: 7f9653b961b16c7658bc83d429e4cf943be495af
+ CMapLibreStyleTry: 814b15f1cdab0fb98603a80d9c099d11119cde70
+ CTilePng: 489523ec525ff5e6862929b9f4675caf58087408
EXConstants: 13cc6ad9324d81223386074a523d4e16aed32cd2
Expo: 092ab1f66de3246b5ffd87d85da9a78648013170
ExpoAsset: e046c820a585f46969182c2aa03c3a822dd55b6b
@@ -2593,30 +2605,30 @@ SPEC CHECKSUMS:
MapboxCommon: 69219036896e94b356757391629e586944ad2b97
MapboxCoreMaps: 77311833fc3d61407777a6d9b1d49422b6962d9a
MapboxMaps: 70192a3581956efae80a0ce4dedd09cc25b02d22
- MapConductorCore: f4a8fe706da64fc05e72c0d387ec60a48dcf1eeb
+ MapConductorCore: 1103b5a507231aebe4ab08fb593b32aca6712bef
MapConductorForArcGIS: 31dab782a4fbb6046f510dbe7d7ea19323092094
MapConductorForGoogleMaps: 483f312109c462dc1fc309cfd693bfff4dee034b
MapConductorForLongdo: 1d203bf49f1e99fd6695b33acc376c5ff239e0bc
MapConductorForMapbox: e45bed934a7e307efc08d9aa51aa6c8a48f042d5
- MapConductorForMapLibre: 9ac83b0358ba70f1b901e44e9d2f98ae4fbea9be
+ MapConductorForMapLibre: e2dd7d8a5f66d51b9d73af231a33d59b5920bfbd
MapConductorForMapTiler: 882ab9b984a63fa8b244ac3d38917d1071163ad9
MapConductorForTemplate: 722f6c4ad3df55aa9dc295301e549142f2bacded
MapConductorForTomTom: 768935180c85c0cc420647730e8795ba17d79987
MapConductorGeoJSON: 188c5fab5dc8d5db24e7fe77f9ee3eac707d1a55
MapConductorHeatmap: cc0c6348088b76b4e1bc74eea8e19bd5ca491f86
MapConductorMarkerClustering: 62baa375da0aafc1ff0a67f516ab3cddf10e4a39
- MapConductorReactForArcGIS: 82a0eeb55de9ed386f0d6117441e1b25a06d4a99
- MapConductorReactForGoogleMaps: bbf691aedad5c8f867ea691e8c9bb3beea70572e
+ MapConductorReactForArcGIS: 60976105f4b18c1443c41929f5f69635ccd33164
+ MapConductorReactForGoogleMaps: 197f61abc12cb55a27a9e88e07906c84aff6ad25
MapConductorReactForLongdo: 8d91c04314a4c105db839071cfb930558e615223
- MapConductorReactForMapbox: 1b423d99eb829c87b04e3edc57103e4e8b1d3659
- MapConductorReactForMapLibre: 2f073b6a4c6918e5e225be9e1b2ce252452aeeda
- MapConductorReactForMapTiler: dde283e47128af5a7a859b09badd867305aa5ce8
+ MapConductorReactForMapbox: 1c76065e17186f42ee25c16abfdeee7f2107ec4a
+ MapConductorReactForMapLibre: 03fe96bb4b75c00b39beed9a31993ba911d3bbaf
+ MapConductorReactForMapTiler: 915a2db2207a4244b1f57d58f0568e1f6ce30128
MapConductorReactForTemplate: 58c9908fe31eb43653eab0604749fdcca7a3a3de
- MapConductorReactForTomTom: e9ad7bbe3000c1e153338589db9cf14a0723e854
- MapConductorReactGeoJSONLayer: b81b6c631b08d6c3497b8d74cec04c9f90a1a6b9
- MapConductorReactHeatmap: baffc663d7492848f323739ea09acec8dbf5507a
- MapConductorReactMarkerClustering: 45aa7843f5118c1ec3d32bba3eeb2ba354c06a1e
- MapConductorReactNativeCore: fe69325883c4bcf93d6dce6382c15bcfb8c4998e
+ MapConductorReactForTomTom: 4116ab2dd76b583fb9caadb1e9c61bd25bc6bbdd
+ MapConductorReactGeoJSONLayer: 6d1b22cc5e42daf792fe9740d3c7be5d5bcb953b
+ MapConductorReactHeatmap: ddf19e30d12dc14083965c43fabdb1a6593c962a
+ MapConductorReactMarkerClustering: 9fd6c18d626b26098891b44d9821eef372752f5e
+ MapConductorReactNativeCore: af6a83a39feb5c8e093f97e7c42e0a012b106556
MapLibre: 96726270455ffd183688cf0bd2a3881b0212a57e
RCTDeprecation: 2a74a2c57675e64419bd89078efde81f7c1de90b
RCTRequired: 30451112e6fef4e6f31b4e7eee0845156e35e4b0
@@ -2708,6 +2720,6 @@ SPEC CHECKSUMS:
Turf: c9eb11a65d96af58cac523460fd40fec5061b081
Yoga: fe50ab299e578f397fef753cf309c6703a4db29b
-PODFILE CHECKSUM: 1917e9c6b4085ff2a37b9ee48ae78f61895e2ad9
+PODFILE CHECKSUM: e34c1eec31b26fee25c162fd0991dcd413e25e19
COCOAPODS: 1.17.0
diff --git a/js-sdk-core b/js-sdk-core
index 2aab7c2..553fca4 160000
--- a/js-sdk-core
+++ b/js-sdk-core
@@ -1 +1 @@
-Subproject commit 2aab7c2ffefa8fb2a12d9278c2391a894f44bb71
+Subproject commit 553fca4a627c25bda221d8cf70fa27be8734bbd2
diff --git a/js-sdk-react b/js-sdk-react
index e7d3c7c..4fa1db2 160000
--- a/js-sdk-react
+++ b/js-sdk-react
@@ -1 +1 @@
-Subproject commit e7d3c7c39bdf36992c1f2092730eb315df41e37c
+Subproject commit 4fa1db274e8fa81bce8586f10eff212c3d4246b2
diff --git a/package-lock.json b/package-lock.json
index bc1ff08..08bea96 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"react-for-maptiler/",
"react-for-longdo/",
"react-for-mappls/",
+ "react-for-deckgl/",
"reactnative-for-googlemaps/",
"reactnative-for-maplibre/",
"reactnative-for-arcgis/",
@@ -38,6 +39,8 @@
"react-geojson/",
"react-kml/",
"react-heatmap/",
+ "vectortile/",
+ "react-vectortile/",
"react-marker-clustering/",
"examples/*"
],
@@ -69,6 +72,7 @@
"@mapconductor/react-for-arcgis": "*",
"@mapconductor/react-for-azuremaps": "*",
"@mapconductor/react-for-cesium": "*",
+ "@mapconductor/react-for-deckgl": "*",
"@mapconductor/react-for-googlemaps": "*",
"@mapconductor/react-for-here": "*",
"@mapconductor/react-for-leaflet": "*",
@@ -85,6 +89,7 @@
"@mapconductor/react-icons": "*",
"@mapconductor/react-kml": "*",
"@mapconductor/react-marker-clustering": "*",
+ "@mapconductor/react-vectortile": "*",
"@zip.js/zip.js": "^2.8.26",
"maplibre-gl": "^6.0.0",
"prism-react-renderer": "^2.4.1",
@@ -1503,6 +1508,133 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
+ "node_modules/@deck.gl/core": {
+ "version": "9.3.11",
+ "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-9.3.11.tgz",
+ "integrity": "sha512-/rv2RvWWNpWzvjWCMNOTk9nuGzkiT6+JrmOqflCp7Df6vxxUE6uK6bdR7z8y9onMlCF7saxKIANYUf/Dw8sQYw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/core": "^4.4.3",
+ "@loaders.gl/images": "^4.4.3",
+ "@luma.gl/core": "~9.3.5",
+ "@luma.gl/engine": "~9.3.5",
+ "@luma.gl/shadertools": "~9.3.5",
+ "@luma.gl/webgl": "~9.3.5",
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/sun": "^4.1.0",
+ "@math.gl/types": "^4.1.0",
+ "@math.gl/web-mercator": "^4.1.0",
+ "@probe.gl/env": "^4.1.1",
+ "@probe.gl/log": "^4.1.1",
+ "@probe.gl/stats": "^4.1.1",
+ "@types/offscreencanvas": "^2019.6.4",
+ "gl-matrix": "^3.0.0",
+ "mjolnir.js": "^3.0.0"
+ }
+ },
+ "node_modules/@deck.gl/extensions": {
+ "version": "9.3.11",
+ "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-9.3.11.tgz",
+ "integrity": "sha512-HOWSgGrNX3ViIg6Y2rvvgDCpGTUPyYezTuwbyKHt/r4ah+oGSu6P9d3aAsWIwEuu2Z1sjeDjAUCppd89OLm1TA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@luma.gl/shadertools": "~9.3.5",
+ "@luma.gl/webgl": "~9.3.5",
+ "@math.gl/core": "^4.1.0"
+ },
+ "peerDependencies": {
+ "@deck.gl/core": "~9.3.0",
+ "@luma.gl/core": "~9.3.5",
+ "@luma.gl/engine": "~9.3.5"
+ }
+ },
+ "node_modules/@deck.gl/geo-layers": {
+ "version": "9.3.11",
+ "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-9.3.11.tgz",
+ "integrity": "sha512-sLrEX2fHPhoFWdaKljv7Fu2mputUDWyiQvB675TYTPyOzw5wZ9APk4G3XmdNfGfBg0Xl6NyKd6fgGz4LSoi/1w==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/3d-tiles": "^4.4.3",
+ "@loaders.gl/gis": "^4.4.3",
+ "@loaders.gl/loader-utils": "^4.4.3",
+ "@loaders.gl/mvt": "^4.4.3",
+ "@loaders.gl/schema": "^4.4.3",
+ "@loaders.gl/terrain": "^4.4.3",
+ "@loaders.gl/tiles": "^4.4.3",
+ "@loaders.gl/wms": "^4.4.3",
+ "@luma.gl/gltf": "~9.3.5",
+ "@luma.gl/shadertools": "~9.3.5",
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/culling": "^4.1.0",
+ "@math.gl/web-mercator": "^4.1.0",
+ "@types/geojson": "^7946.0.8",
+ "a5-js": "^0.7.2",
+ "h3-js": "^4.4.0",
+ "long": "^3.2.0"
+ },
+ "peerDependencies": {
+ "@deck.gl/core": "~9.3.0",
+ "@deck.gl/extensions": "~9.3.0",
+ "@deck.gl/layers": "~9.3.0",
+ "@deck.gl/mesh-layers": "~9.3.0",
+ "@loaders.gl/core": "^4.4.3",
+ "@luma.gl/core": "~9.3.5",
+ "@luma.gl/engine": "~9.3.5"
+ }
+ },
+ "node_modules/@deck.gl/geo-layers/node_modules/long": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
+ "integrity": "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/@deck.gl/layers": {
+ "version": "9.3.11",
+ "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-9.3.11.tgz",
+ "integrity": "sha512-DdFdblGZA2MxqB7coCgbvumniV80F2TaOPUHkaahFP5Gvo8ZA0cGgo0A9FusiVw0ZXJVPBTdoueMwAZqXiz8dQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/images": "^4.4.3",
+ "@loaders.gl/schema": "^4.4.3",
+ "@luma.gl/shadertools": "~9.3.5",
+ "@mapbox/tiny-sdf": "^2.0.5",
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/polygon": "^4.1.0",
+ "@math.gl/web-mercator": "^4.1.0",
+ "@types/geojson": "^7946.0.16",
+ "earcut": "^2.2.4"
+ },
+ "peerDependencies": {
+ "@deck.gl/core": "~9.3.0",
+ "@loaders.gl/core": "^4.4.3",
+ "@luma.gl/core": "~9.3.5",
+ "@luma.gl/engine": "~9.3.5"
+ }
+ },
+ "node_modules/@deck.gl/mesh-layers": {
+ "version": "9.3.11",
+ "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-9.3.11.tgz",
+ "integrity": "sha512-lL7NLb7luBjo7RghSRsaa3bMNWp/APEtWBZWcrAaSTHTmvqlJlsAGUux92fDlva+6flzwsaeqSzGCruLu/Kziw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@loaders.gl/gltf": "^4.4.3",
+ "@loaders.gl/schema": "^4.4.3",
+ "@luma.gl/gltf": "~9.3.5",
+ "@luma.gl/shadertools": "~9.3.5"
+ },
+ "peerDependencies": {
+ "@deck.gl/core": "~9.3.0",
+ "@luma.gl/core": "~9.3.5",
+ "@luma.gl/engine": "~9.3.5",
+ "@luma.gl/gltf": "~9.3.5",
+ "@luma.gl/shadertools": "~9.3.5"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
@@ -2537,6 +2669,520 @@
"@lit-labs/ssr-dom-shim": "^1.5.0"
}
},
+ "node_modules/@loaders.gl/3d-tiles": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-4.4.5.tgz",
+ "integrity": "sha512-+W9ncpVw5+OX9pjhZFmpbK+pBqT1XNCAaUbUY/qItFlK1PcTSQdy34NVvAziRR7dFxJ0VmWPEu5Q75LcNCCX2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/compression": "4.4.5",
+ "@loaders.gl/crypto": "4.4.5",
+ "@loaders.gl/draco": "4.4.5",
+ "@loaders.gl/gltf": "4.4.5",
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/math": "4.4.5",
+ "@loaders.gl/tiles": "4.4.5",
+ "@loaders.gl/zip": "4.4.5",
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/culling": "^4.1.0",
+ "@math.gl/geospatial": "^4.1.0",
+ "@probe.gl/log": "^4.1.1",
+ "long": "^5.2.1"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/compression": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/compression/-/compression-4.4.5.tgz",
+ "integrity": "sha512-vsuvdIyn3xLqiJxXhK970ENO3T8bLPtmM0jka8/y0zVAEover6q3Vd8gVsaqgWGfc28cWx5RYI4zKhJzRcTHNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "@types/pako": "^1.0.1",
+ "fflate": "0.7.4",
+ "pako": "1.0.11",
+ "snappyjs": "^0.6.1"
+ },
+ "optionalDependencies": {
+ "@types/brotli": "^1.3.0",
+ "brotli": "^1.3.2",
+ "lz4js": "^0.2.0",
+ "zstd-codec": "^0.1"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/compression/node_modules/fflate": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
+ "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==",
+ "license": "MIT"
+ },
+ "node_modules/@loaders.gl/compression/node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/@loaders.gl/core": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-4.4.5.tgz",
+ "integrity": "sha512-hlpE200MinDAyU0kMjEM4yk+0TDxiB9nT+GcwOCrXc7buE0e0YwTn+Ynz2Q85dwDKvJZw3kNHTTBGvQwq9533A==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/schema-utils": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "@probe.gl/log": "^4.1.1"
+ }
+ },
+ "node_modules/@loaders.gl/crypto": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/crypto/-/crypto-4.4.5.tgz",
+ "integrity": "sha512-P0n43KWN7GGsWF7+E094Nj1mwngN6ypfgts5tu2hSEroUS5dB01TgDa0Pr3sVeZ672jFSKKRgRuFDazRcITOFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "@types/crypto-js": "^4.0.2"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/draco": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-4.4.5.tgz",
+ "integrity": "sha512-J4DuzoUQNJhjxmErCArF5J1PC0LCMbhPkY/YdkTaDmUwxSQdh1M/VWg85AXKLAxUiwGkhmC8AUUaSyPxTpCUrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/schema-utils": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "draco3d": "1.5.7"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/geoarrow": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/geoarrow/-/geoarrow-4.4.5.tgz",
+ "integrity": "sha512-uUWp+5nZxQe6Sv/o36R6jcmCCNhguY0VhjougyMoH6FWqF6iJHrOnwx5UdEtvkw/zV9mHabs05Hv91dBvhfljQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/polygon": "^4.1.0",
+ "apache-arrow": ">= 17.0.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/gis": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-4.4.5.tgz",
+ "integrity": "sha512-r3klnZ6jjzaEZlUSCmGufPbH1pQpM5PCcGS70zLlGIFbpJPo80gaXDtZDVOSQvpWmqY8u8d7/6moAsogVoymzA==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/geoarrow": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/schema-utils": "4.4.5",
+ "@mapbox/vector-tile": "^1.3.1",
+ "@math.gl/polygon": "^4.1.0",
+ "pbf": "^3.2.1"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/gis/node_modules/@mapbox/point-geometry": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
+ "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==",
+ "license": "ISC"
+ },
+ "node_modules/@loaders.gl/gis/node_modules/@mapbox/vector-tile": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
+ "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@mapbox/point-geometry": "~0.1.0"
+ }
+ },
+ "node_modules/@loaders.gl/gis/node_modules/pbf": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz",
+ "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "ieee754": "^1.1.12",
+ "resolve-protobuf-schema": "^2.1.0"
+ },
+ "bin": {
+ "pbf": "bin/pbf"
+ }
+ },
+ "node_modules/@loaders.gl/gltf": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-4.4.5.tgz",
+ "integrity": "sha512-YIhgeoDYdRbfXQS+cpRWYbiRiiaajF5UCqpEoFpDEpOpcW6pKC2sfp5vZ1LiUIXu2CVv/HFJaDeLuQjeX5uVlQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/draco": "4.4.5",
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/textures": "4.4.5",
+ "@math.gl/core": "^4.1.0",
+ "meshoptimizer": "^1.2.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/images": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-4.4.5.tgz",
+ "integrity": "sha512-7/odHt5n67OVLHelTm1euNNw5gCwycezQI7Wg3NBUg7q3bHWmTPY++Z4uz2egiuzJNY3GLegfg8AI1c3fD64Jw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/loader-utils": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-4.4.5.tgz",
+ "integrity": "sha512-c4h2RUMEru+hbfvgZEIy5cLQKyQka2TPQZW/2Wy+yIPr3FU7RKwfp+vLwIfir6Xkdn2zniWyWretZwE02aY/Ug==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "@probe.gl/log": "^4.1.1",
+ "@probe.gl/stats": "^4.1.1"
+ }
+ },
+ "node_modules/@loaders.gl/math": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-4.4.5.tgz",
+ "integrity": "sha512-Az7rMw7oMNMzi1bXgPaabdkpPtk0safkWBr+I+dHjZHzny1RK5mFF4VjRkalw++DZBKbL0TskMw/OcdiRaL/Bw==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "^4.1.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/mvt": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-4.4.5.tgz",
+ "integrity": "sha512-3c4ojvF6+Fb0XjX2xGeRKIUAshaNgBfi0VkszooFNCNvrVv7faGcn69jI9wh1Pjf2ge1PtsZnAoOuLQXLLzWSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/gis": "4.4.5",
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/schema-utils": "4.4.5",
+ "@math.gl/polygon": "^4.1.0",
+ "@probe.gl/stats": "^4.1.1",
+ "pbf": "^3.2.1"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/mvt/node_modules/pbf": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.3.0.tgz",
+ "integrity": "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "ieee754": "^1.1.12",
+ "resolve-protobuf-schema": "^2.1.0"
+ },
+ "bin": {
+ "pbf": "bin/pbf"
+ }
+ },
+ "node_modules/@loaders.gl/schema": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-4.4.5.tgz",
+ "integrity": "sha512-q2XNquegw+hX+ZEshacKYL/+FKBUIS5FHA+2Ft3JWmcNiR6umGnYCdXQhDcFCqAm8Ks87fMCV+z/zTloxaIZgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "^7946.0.7",
+ "apache-arrow": ">= 17.0.0"
+ }
+ },
+ "node_modules/@loaders.gl/schema-utils": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/schema-utils/-/schema-utils-4.4.5.tgz",
+ "integrity": "sha512-vi6AROLWvoLIN609tVmchwotTaHK5rHv8SWjoVUWLhPCXmIc9npz0rCl7NJScCgr7UjYifZG1rWOnrAxaYTlyA==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/schema": "4.4.5",
+ "@math.gl/types": "^4.1.0",
+ "@types/geojson": "^7946.0.7",
+ "apache-arrow": ">= 17.0.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/terrain": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-4.4.5.tgz",
+ "integrity": "sha512-H8BED2/0I1wrviE8mBr1ny/01nK1vqctMHBYSoAHS36JJm5m+Tt2JfKXIgnNY2TU3Ulfr9L9x1VfH9a/z9V1jw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@mapbox/martini": "^0.2.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/textures": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/textures/-/textures-4.4.5.tgz",
+ "integrity": "sha512-zB9xMIKiU3tQN6q5/A6yaXw/DbodA+bqMDTVu7pzk4lw4zcBwWiGtD5LV0QjgtlTj2ZnwV8cCd1rYk9bwiX2Bw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/worker-utils": "4.4.5",
+ "@math.gl/types": "^4.1.0",
+ "ktx-parse": "^0.7.0",
+ "texture-compressor": "^1.0.2"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/textures/node_modules/ktx-parse": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.7.1.tgz",
+ "integrity": "sha512-FeA3g56ksdFNwjXJJsc1CCc7co+AJYDp6ipIp878zZ2bU8kWROatLYf39TQEd4/XRSUvBXovQ8gaVKWPXsCLEQ==",
+ "license": "MIT"
+ },
+ "node_modules/@loaders.gl/tiles": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-4.4.5.tgz",
+ "integrity": "sha512-XO9NeUsukjj+90YN1GEJWOgt7rI5GIv20dCpPIYdgj299aa8iYB5DWcm1YGcOuNjGqdQNZXIgPSv6ocdN/X7Mw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/math": "4.4.5",
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/culling": "^4.1.0",
+ "@math.gl/geospatial": "^4.1.0",
+ "@math.gl/web-mercator": "^4.1.0",
+ "@probe.gl/stats": "^4.1.1"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/wms": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/wms/-/wms-4.4.5.tgz",
+ "integrity": "sha512-0+nXHY017bAl3tELIefUa0FB3ptUpEVxtQD1imNqyUtRr1vrzhyc+kbBcc3uRIcDj/F6iW9pq2V6lBwcIGZXFw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/images": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "@loaders.gl/xml": "4.4.5",
+ "@turf/rewind": "^5.1.5",
+ "deep-strict-equal": "^0.2.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/boolean-clockwise": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-5.1.5.tgz",
+ "integrity": "sha512-FqbmEEOJ4rU4/2t7FKx0HUWmjFEVqR+NJrFP7ymGSjja2SQ7Q91nnBihGuT+yuHHl6ElMjQ3ttsB/eTmyCycxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/clone": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz",
+ "integrity": "sha512-//pITsQ8xUdcQ9pVb4JqXiSqG4dos5Q9N4sYFoWghX21tfOV2dhc5TGqYOhnHrQS7RiKQL1vQ48kIK34gQ5oRg==",
+ "license": "MIT",
+ "dependencies": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/helpers": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz",
+ "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw==",
+ "license": "MIT"
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/invariant": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz",
+ "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/meta": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.2.0.tgz",
+ "integrity": "sha512-ZjQ3Ii62X9FjnK4hhdsbT+64AYRpaI8XMBMcyftEOGSmPMUVnkbvuv3C9geuElAXfQU7Zk1oWGOcrGOD9zr78Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "node_modules/@loaders.gl/wms/node_modules/@turf/rewind": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-5.1.5.tgz",
+ "integrity": "sha512-Gdem7JXNu+G4hMllQHXRFRihJl3+pNl7qY+l4qhQFxq+hiU1cQoVFnyoleIqWKIrdK/i2YubaSwc3SCM7N5mMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@turf/boolean-clockwise": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "node_modules/@loaders.gl/worker-utils": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-4.4.5.tgz",
+ "integrity": "sha512-ZQDoM6f/HpZ3Lzj6vjtPHXSvi+cUK0QG7yJz+MKWAokmeWa98WMZwswS8zkn/qNkY95rLcxh66N4Sl96+7hqAQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/xml": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/xml/-/xml-4.4.5.tgz",
+ "integrity": "sha512-UsN7T9e67Sa1Q6Ra/u+j2mtaT9GTcFhH8iz8ba5QFU90YrRn3dwBEwq9SVxQiJrfC6dE4jFdMannW5mzeV5owg==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/loader-utils": "4.4.5",
+ "@loaders.gl/schema": "4.4.5",
+ "fast-xml-parser": "^5.3.6"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@loaders.gl/zip": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@loaders.gl/zip/-/zip-4.4.5.tgz",
+ "integrity": "sha512-vXlwnJ2QCCtXc8Pf55YJUNTJ0sjtjbUr34StDY91GPmoutdAXovqikuwzehrAlMDE69ldbnMtVATmNe4XeWGXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/compression": "4.4.5",
+ "@loaders.gl/crypto": "4.4.5",
+ "@loaders.gl/loader-utils": "4.4.5",
+ "jszip": "^3.1.5",
+ "md5": "^2.3.0"
+ },
+ "peerDependencies": {
+ "@loaders.gl/core": "~4.4.0"
+ }
+ },
+ "node_modules/@luma.gl/core": {
+ "version": "9.3.6",
+ "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-9.3.6.tgz",
+ "integrity": "sha512-eqHnCPh2xHYkdd9rEkiIIkGMixNiJkq1ROrnTob6npvmZNVHXL0ubIw5KueL7rqW0+J1tm+p2+TXZaCmn0sP7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/types": "^4.1.0",
+ "@probe.gl/env": "^4.1.1",
+ "@probe.gl/log": "^4.1.1",
+ "@probe.gl/stats": "^4.1.1",
+ "@types/offscreencanvas": "^2019.7.3"
+ }
+ },
+ "node_modules/@luma.gl/engine": {
+ "version": "9.3.6",
+ "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-9.3.6.tgz",
+ "integrity": "sha512-NYTdhn2NaH/MjN8qXCl2ukrT1Ac9iTKu1mgN0wz11XRd1QYnlMNBXswRROD7IZ2PUsBWdmYHc9qE8wKBQqMuIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/types": "^4.1.0",
+ "@probe.gl/log": "^4.1.1",
+ "@probe.gl/stats": "^4.1.1"
+ },
+ "peerDependencies": {
+ "@luma.gl/core": "~9.3.0",
+ "@luma.gl/shadertools": "~9.3.0"
+ }
+ },
+ "node_modules/@luma.gl/gltf": {
+ "version": "9.3.6",
+ "resolved": "https://registry.npmjs.org/@luma.gl/gltf/-/gltf-9.3.6.tgz",
+ "integrity": "sha512-9R27aYwvu6KBJzd9Kxs4cqIJpgJsI1AyL6Pn6+5CrmGbaCqMtgWi7Sf9Wo+bqv0PRxwzH0j1oAv7qRk0hGbstw==",
+ "license": "MIT",
+ "dependencies": {
+ "@loaders.gl/core": "~4.4.0",
+ "@loaders.gl/gltf": "~4.4.0",
+ "@loaders.gl/textures": "~4.4.0",
+ "@math.gl/core": "^4.1.0"
+ },
+ "peerDependencies": {
+ "@luma.gl/core": "~9.3.0",
+ "@luma.gl/engine": "~9.3.0",
+ "@luma.gl/shadertools": "~9.3.0"
+ }
+ },
+ "node_modules/@luma.gl/shadertools": {
+ "version": "9.3.6",
+ "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-9.3.6.tgz",
+ "integrity": "sha512-dDuD8lCOkAE1L7hJGZEyZAi7upR1HG3wEEIQ1gCLaTTbJWC7tNtnVz853lqUA+VXgjgS9NiQFFRcosiIZmW4Vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "^4.1.0",
+ "@math.gl/types": "^4.1.0"
+ },
+ "peerDependencies": {
+ "@luma.gl/core": "~9.3.0"
+ }
+ },
+ "node_modules/@luma.gl/webgl": {
+ "version": "9.3.6",
+ "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-9.3.6.tgz",
+ "integrity": "sha512-tGm7FGWPmJKxGZMvkRPRi219x3tKmBxR7Uke09nTp2ujNak/O5V9xPIQ9lUBGTxqAb8U2yjKkXG8j+f/4b2+sw==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/types": "^4.1.0",
+ "@probe.gl/env": "^4.1.1"
+ },
+ "peerDependencies": {
+ "@luma.gl/core": "~9.3.0"
+ }
+ },
"node_modules/@mapbox/jsonlint-lines-primitives": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.3.tgz",
@@ -2552,6 +3198,12 @@
"integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ==",
"license": "BSD-3-Clause"
},
+ "node_modules/@mapbox/martini": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/martini/-/martini-0.2.0.tgz",
+ "integrity": "sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ==",
+ "license": "ISC"
+ },
"node_modules/@mapbox/point-geometry": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz",
@@ -2609,6 +3261,10 @@
"resolved": "react-for-cesium",
"link": true
},
+ "node_modules/@mapconductor/react-for-deckgl": {
+ "resolved": "react-for-deckgl",
+ "link": true
+ },
"node_modules/@mapconductor/react-for-googlemaps": {
"resolved": "react-for-googlemaps",
"link": true
@@ -2677,6 +3333,10 @@
"resolved": "react-marker-clustering",
"link": true
},
+ "node_modules/@mapconductor/react-vectortile": {
+ "resolved": "react-vectortile",
+ "link": true
+ },
"node_modules/@mapconductor/reactnative-for-arcgis": {
"resolved": "reactnative-for-arcgis",
"link": true
@@ -2709,6 +3369,10 @@
"resolved": "reactnative-for-tomtom",
"link": true
},
+ "node_modules/@mapconductor/vectortile": {
+ "resolved": "vectortile",
+ "link": true
+ },
"node_modules/@maplibre/geojson-vt": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@maplibre/geojson-vt/-/geojson-vt-6.1.1.tgz",
@@ -2764,6 +3428,65 @@
"pbf": "^5.1.0"
}
},
+ "node_modules/@math.gl/core": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-4.1.0.tgz",
+ "integrity": "sha512-FrdHBCVG3QdrworwrUSzXIaK+/9OCRLscxI2OUy6sLOHyHgBMyfnEGs99/m3KNvs+95BsnQLWklVfpKfQzfwKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/types": "4.1.0"
+ }
+ },
+ "node_modules/@math.gl/culling": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-4.1.0.tgz",
+ "integrity": "sha512-jFmjFEACnP9kVl8qhZxFNhCyd47qPfSVmSvvjR0/dIL6R9oD5zhR1ub2gN16eKDO/UM7JF9OHKU3EBIfeR7gtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "4.1.0",
+ "@math.gl/types": "4.1.0"
+ }
+ },
+ "node_modules/@math.gl/geospatial": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/geospatial/-/geospatial-4.1.0.tgz",
+ "integrity": "sha512-BzsUhpVvnmleyYF6qdqJIip6FtIzJmnWuPTGhlBuPzh7VBHLonCFSPtQpbkRuoyAlbSyaGXcVt6p6lm9eK2vtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "4.1.0",
+ "@math.gl/types": "4.1.0"
+ }
+ },
+ "node_modules/@math.gl/polygon": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-4.1.0.tgz",
+ "integrity": "sha512-YA/9PzaCRHbIP5/0E9uTYrqe+jsYTQoqoDWhf6/b0Ixz8bPZBaGDEafLg3z7ffBomZLacUty9U3TlPjqMtzPjA==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "4.1.0"
+ }
+ },
+ "node_modules/@math.gl/sun": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/sun/-/sun-4.1.0.tgz",
+ "integrity": "sha512-i3q6OCBLSZ5wgZVhXg+X7gsjY/TUtuFW/2KBiq/U1ypLso3S4sEykoU/MGjxUv1xiiGtr+v8TeMbO1OBIh/HmA==",
+ "license": "MIT"
+ },
+ "node_modules/@math.gl/types": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/types/-/types-4.1.0.tgz",
+ "integrity": "sha512-clYZdHcmRvMzVK5fjeDkQlHUzXQSNdZ7s4xOqC3nJPgz4C/TZkUecTo9YS4PruZqtDda/ag4erndP0MIn40dGA==",
+ "license": "MIT"
+ },
+ "node_modules/@math.gl/web-mercator": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-4.1.0.tgz",
+ "integrity": "sha512-HZo3vO5GCMkXJThxRJ5/QYUYRr3XumfT8CzNNCwoJfinxy5NtKUd7dusNTXn7yJ40UoB8FMIwkVwNlqaiRZZAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@math.gl/core": "4.1.0"
+ }
+ },
"node_modules/@napi-rs/lzma-linux-x64-gnu": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
@@ -2808,6 +3531,18 @@
"url": "https://paulmillr.com/funding/"
}
},
+ "node_modules/@nodable/entities": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz",
+ "integrity": "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodable"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/@open-wc/dedupe-mixin": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz",
@@ -3183,6 +3918,27 @@
"node": ">=20"
}
},
+ "node_modules/@probe.gl/env": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-4.1.2.tgz",
+ "integrity": "sha512-KIcdjrEiEZVIGX9nh7pZSmTMIKrd+wCb09gyXqpYYI4hs9WMqrQHvKZ7KD8ASutf6kwARwgd4WNQn8aucLSz3g==",
+ "license": "MIT"
+ },
+ "node_modules/@probe.gl/log": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-4.1.2.tgz",
+ "integrity": "sha512-2LqSq4CHhc/HJQasHMPOzA6c7rprlGz8CCREGebo19jxcuKdvXQo0DEmlfId076U6UldMp6jGhWvDHEFLX111Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@probe.gl/env": "4.1.2"
+ }
+ },
+ "node_modules/@probe.gl/stats": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.1.2.tgz",
+ "integrity": "sha512-Hqc0UIHd0IZ2+JbovzTz7lYG7CY9D8yCB81zyP92Zl9UDSPcw2cLbTySW14keAQeAo1sjGjUw0+KHxr0Y2h/hA==",
+ "license": "MIT"
+ },
"node_modules/@react-native-community/slider": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-5.2.0.tgz",
@@ -6037,6 +6793,22 @@
"@babel/types": "^7.28.2"
}
},
+ "node_modules/@types/brotli": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/brotli/-/brotli-1.3.5.tgz",
+ "integrity": "sha512-9xoNr+bcxT236/7ZgcWw/6Pb2RRetE13p4bFy1xYSckKwyOiRfmInay8baUWZgH7/284Wl6IPe7+nOI9+OQg/A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/crypto-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
+ "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
+ "license": "MIT"
+ },
"node_modules/@types/d3": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
@@ -6394,6 +7166,18 @@
"undici-types": "~6.21.0"
}
},
+ "node_modules/@types/offscreencanvas": {
+ "version": "2019.7.3",
+ "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
+ "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==",
+ "license": "MIT"
+ },
+ "node_modules/@types/pako": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.7.tgz",
+ "integrity": "sha512-YBtzT2ztNF6R/9+UXj2wTGFnC9NklAnASt3sC0h2m1bbH7G6FyBIkt4AN8ThZpNfxUo1b2iMVO0UawiJymEt8A==",
+ "license": "MIT"
+ },
"node_modules/@types/polylabel": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@types/polylabel/-/polylabel-1.1.3.tgz",
@@ -6992,6 +7776,15 @@
"node": ">=18.0.0"
}
},
+ "node_modules/a5-js": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/a5-js/-/a5-js-0.7.3.tgz",
+ "integrity": "sha512-3aoMwHmNkyuMDHS4q6GRRInpOawamen2pokIbc0MQmR9cqG0Y9+B0bZpzswwetjrSG2ckbYtShH+nKru6+3O5Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "gl-matrix": "^3.4.3"
+ }
+ },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -7120,11 +7913,53 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "dev": true,
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/anynum": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz",
+ "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/apache-arrow": {
+ "version": "21.2.0",
+ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.2.0.tgz",
+ "integrity": "sha512-Hxe6Agq26gQOM954qpzYSllJBPJl+e16U5CkfuMUhLrNba+5nKkttIVlflaovN6oaTratqMGAO8H5u/aNhmHWQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/node": "^25.2.0",
+ "flatbuffers": "^25.1.24",
+ "json-with-bigint": "^3.5.3",
+ "tslib": "^2.6.2"
+ },
+ "bin": {
+ "arrow2csv": "bin/arrow2csv.js"
+ }
+ },
+ "node_modules/apache-arrow/node_modules/@types/node": {
+ "version": "25.9.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.5.tgz",
+ "integrity": "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": ">=7.24.0 <7.24.7"
+ }
+ },
+ "node_modules/apache-arrow/node_modules/undici-types": {
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
"license": "MIT"
},
"node_modules/arc": {
@@ -7516,6 +8351,15 @@
"node-int64": "^0.4.0"
}
},
+ "node_modules/buf-compare": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+ "integrity": "sha512-Bvx4xH00qweepGc43xFvMs5BKASXTbHaHm6+kDYIK9p/4iFwjATQkmPKHQSgJZzKbAymhztRbXUf1Nqhzl73/Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -7626,6 +8470,15 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/charenc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+ "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
@@ -7963,6 +8816,19 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/core-assert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+ "integrity": "sha512-IG97qShIP+nrJCXMCgkNZgH7jZQ4n8RpPyPeXX++T6avR/KhLhgLiHKoEn5Rc1KjfycSfA9DMa6m+4C4eguHhw==",
+ "license": "MIT",
+ "dependencies": {
+ "buf-compare": "^1.0.0",
+ "is-error": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/core-js-compat": {
"version": "3.50.0",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz",
@@ -7979,6 +8845,12 @@
"url": "https://opencollective.com/core-js"
}
},
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -8000,6 +8872,15 @@
"node": ">= 8"
}
},
+ "node_modules/crypt": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+ "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/cssfilter": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz",
@@ -8556,6 +9437,18 @@
}
}
},
+ "node_modules/deep-strict-equal": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+ "integrity": "sha512-3daSWyvZ/zwJvuMGlzG1O+Ow0YSadGfb3jsh9xoCutv2tWyB9dA4YvR9L9/fSdDZa2dByYQe+TqapSGUrjnkoA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-assert": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
@@ -9412,6 +10305,45 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
+ "node_modules/fast-xml-builder": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.3.1.tgz",
+ "integrity": "sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "path-expression-matcher": "^1.6.2",
+ "xml-naming": "^0.3.0"
+ }
+ },
+ "node_modules/fast-xml-parser": {
+ "version": "5.11.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.11.1.tgz",
+ "integrity": "sha512-TBw6K/fxoQGGjCmZDw9w/ZwP3uDcnTM4YH/g+PFRWr8sbe5idXtxNN6vITh4+1ruCZaho6uBFurElsA7F0zzgw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@nodable/entities": "^3.0.0",
+ "fast-xml-builder": "^1.2.0",
+ "is-unsafe": "^2.0.0",
+ "path-expression-matcher": "^1.6.2",
+ "strnum": "^2.4.2",
+ "xml-naming": "^0.3.0"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
"node_modules/fb-dotslash": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/fb-dotslash/-/fb-dotslash-0.5.8.tgz",
@@ -9502,6 +10434,12 @@
"rollup": "^4.34.8"
}
},
+ "node_modules/flatbuffers": {
+ "version": "25.9.23",
+ "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz",
+ "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
+ "license": "Apache-2.0"
+ },
"node_modules/flatpickr": {
"version": "4.6.13",
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz",
@@ -9715,6 +10653,17 @@
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
"license": "MIT"
},
+ "node_modules/h3-js": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-4.5.0.tgz",
+ "integrity": "sha512-uKmdPc+DuarnR+XqZxEuWOMw7KzzKROrx3MLeJpFnMOs78S9M5eZ+X5RieS9UcSFQqbeXzbfWuX/W9Pyajinqw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=4",
+ "npm": ">=3",
+ "yarn": ">=1.3.0"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -9829,6 +10778,26 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -9853,6 +10822,12 @@
"node": ">=16.x"
}
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -9886,6 +10861,12 @@
"loose-envify": "^1.0.0"
}
},
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "license": "MIT"
+ },
"node_modules/is-core-module": {
"version": "2.16.2",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
@@ -9916,6 +10897,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-error": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+ "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==",
+ "license": "MIT"
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -9934,6 +10921,18 @@
"node": ">=0.12.0"
}
},
+ "node_modules/is-unsafe": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-2.0.2.tgz",
+ "integrity": "sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -9946,6 +10945,12 @@
"node": ">=8"
}
},
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -10123,6 +11128,12 @@
"integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==",
"license": "MIT"
},
+ "node_modules/json-with-bigint": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz",
+ "integrity": "sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==",
+ "license": "MIT"
+ },
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -10144,6 +11155,24 @@
"node": ">= 12"
}
},
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/jszip/node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
+ },
"node_modules/kdbush": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.1.0.tgz",
@@ -10195,6 +11224,15 @@
"node": ">=6"
}
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/lighthouse-logger": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
@@ -10698,6 +11736,13 @@
"node": ">=12"
}
},
+ "node_modules/lz4js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/lz4js/-/lz4js-0.2.0.tgz",
+ "integrity": "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg==",
+ "license": "ISC",
+ "optional": true
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -10842,6 +11887,17 @@
"integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
"license": "Apache-2.0"
},
+ "node_modules/md5": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+ "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "charenc": "0.0.2",
+ "crypt": "0.0.2",
+ "is-buffer": "~1.1.6"
+ }
+ },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -11226,6 +12282,12 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/mjolnir.js": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-3.1.0.tgz",
+ "integrity": "sha512-fWcei0lo+xauQK0CVb5vwC8FaS9xeEBiNPd5vMIM89DchQAi6ENMq9itOjq+G8zAvhKmJu5UPnuEnU8kVrHzdg==",
+ "license": "MIT"
+ },
"node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@@ -11691,6 +12753,21 @@
"node": ">= 0.8"
}
},
+ "node_modules/path-expression-matcher": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz",
+ "integrity": "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -12071,6 +13148,12 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
"node_modules/progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@@ -12298,6 +13381,27 @@
"node": ">=0.10.0"
}
},
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@@ -12693,6 +13797,12 @@
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT"
},
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
+ },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -12770,6 +13880,12 @@
"node": ">=8.0.0"
}
},
+ "node_modules/snappyjs": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/snappyjs/-/snappyjs-0.6.1.tgz",
+ "integrity": "sha512-YIK6I2lsH072UE0aOFxxY1dPDCS43I5ktqHpeAsuLNYWkE5pGxRGWfDM4/vSUfNzXjC1Ivzt3qx31PCLmc9yqg==",
+ "license": "MIT"
+ },
"node_modules/sortablejs": {
"version": "1.15.7",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.7.tgz",
@@ -12819,6 +13935,12 @@
"integrity": "sha512-0kGecIZNIReCSiznK3uheYB8sbstLjCZLiwcQwbmLhgHJj2gz6OnSPkVzJQCMnmEz1BQ4gPK59ylhBoEWOhGNA==",
"license": "BDS-3-Clause"
},
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/stackframe": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
@@ -12864,6 +13986,21 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -12890,6 +14027,21 @@
"node": ">=8"
}
},
+ "node_modules/strnum": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.2.tgz",
+ "integrity": "sha512-rDG3Ah4TV0k1hWvLSzkZtMmLN9+eS+h3knq4MP6A42Y3Yh5qGNnOUs1jJkoSr8FG5dsL28c7KgkIBzSEykqtuw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "anynum": "^1.0.1"
+ }
+ },
"node_modules/structured-headers": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
@@ -13018,6 +14170,40 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
+ "node_modules/texture-compressor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/texture-compressor/-/texture-compressor-1.0.2.tgz",
+ "integrity": "sha512-dStVgoaQ11mA5htJ+RzZ51ZxIZqNOgWKAIvtjLrW1AliQQLCmrDqNzQZ8Jh91YealQ95DXt4MEduLzJmbs6lig==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.10",
+ "image-size": "^0.7.4"
+ },
+ "bin": {
+ "texture-compressor": "bin/texture-compressor.js"
+ }
+ },
+ "node_modules/texture-compressor/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/texture-compressor/node_modules/image-size": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
+ "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==",
+ "license": "MIT",
+ "bin": {
+ "image-size": "bin/image-size.js"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
@@ -13539,6 +14725,12 @@
"integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==",
"license": "MIT"
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -13843,6 +15035,21 @@
"node": ">=10.0.0"
}
},
+ "node_modules/xml-naming": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.3.0.tgz",
+ "integrity": "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
"node_modules/xml-utils": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.10.2.tgz",
@@ -14001,6 +15208,13 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
+ "node_modules/zstd-codec": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/zstd-codec/-/zstd-codec-0.1.5.tgz",
+ "integrity": "sha512-v3fyjpK8S/dpY/X5WxqTK3IoCnp/ZOLxn144GZVlNUjtwAchzrVo03h+oMATFhCIiJ5KTr4V3vDQQYz4RU684g==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/zstddec": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.2.0.tgz",
@@ -14094,6 +15308,37 @@
"node": ">=0.10.0"
}
},
+ "react-for-deckgl": {
+ "name": "@mapconductor/react-for-deckgl",
+ "version": "0.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@deck.gl/core": "^9.3.0",
+ "@deck.gl/geo-layers": "^9.3.0",
+ "@deck.gl/layers": "^9.3.0",
+ "@mapconductor/js-sdk-core": "^0.2.0",
+ "@mapconductor/js-sdk-react": "^0.2.1"
+ },
+ "devDependencies": {
+ "react": "^19.2.8",
+ "tsup": "^8.5.1",
+ "typescript": "^5.9.3"
+ },
+ "peerDependencies": {
+ "@mapconductor/js-sdk-core": "^0.2.0",
+ "react": "^18.0.0 || ^19.0.0"
+ }
+ },
+ "react-for-deckgl/node_modules/react": {
+ "version": "19.2.8",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz",
+ "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"react-for-googlemaps": {
"name": "@mapconductor/react-for-googlemaps",
"version": "0.2.1",
@@ -14547,6 +15792,25 @@
}
}
},
+ "react-vectortile": {
+ "name": "@mapconductor/react-vectortile",
+ "version": "0.2.1",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@mapconductor/js-sdk-core": "^0.2.0",
+ "@mapconductor/js-sdk-react": "^0.2.1",
+ "@mapconductor/vectortile": "*"
+ },
+ "devDependencies": {
+ "@types/react": "^19.2.0",
+ "react": "^19.2.0",
+ "tsup": "^8.5.1",
+ "typescript": "^5.9.3"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0"
+ }
+ },
"reactnative-for-arcgis": {
"name": "@mapconductor/reactnative-for-arcgis",
"version": "0.2.1",
@@ -14787,6 +16051,11 @@
"engines": {
"node": ">=0.10.0"
}
+ },
+ "vectortile": {
+ "name": "@mapconductor/vectortile",
+ "version": "0.1.0",
+ "license": "Apache-2.0"
}
}
}
diff --git a/package.json b/package.json
index 535e5b0..2601f5f 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"react-for-maptiler/",
"react-for-longdo/",
"react-for-mappls/",
+ "react-for-deckgl/",
"reactnative-for-googlemaps/",
"reactnative-for-maplibre/",
"reactnative-for-arcgis/",
@@ -33,17 +34,21 @@
"react-geojson/",
"react-kml/",
"react-heatmap/",
+ "vectorstyle/",
+ "vectortile/",
+ "react-vectorstyle/",
+ "react-vectortile/",
"react-marker-clustering/",
"examples/*"
],
"scripts": {
"build": "npm run build --workspaces --if-present",
- "build:packages": "npm run build --if-present --workspace @mapconductor/js-sdk-core --workspace @mapconductor/js-sdk-react --workspace @mapconductor/react-icons --workspace @mapconductor/react-for-googlemaps --workspace @mapconductor/react-for-maplibre --workspace @mapconductor/react-for-mapbox --workspace @mapconductor/react-for-leaflet --workspace @mapconductor/react-for-openlayers --workspace @mapconductor/react-for-arcgis --workspace @mapconductor/react-for-mapkit --workspace @mapconductor/react-for-azuremaps --workspace @mapconductor/react-for-cesium --workspace @mapconductor/react-for-here --workspace @mapconductor/react-for-tomtom --workspace @mapconductor/react-for-maptiler --workspace @mapconductor/react-for-longdo --workspace @mapconductor/react-for-mappls --workspace @mapconductor/reactnative-for-googlemaps --workspace @mapconductor/reactnative-for-maplibre --workspace @mapconductor/reactnative-for-arcgis --workspace @mapconductor/reactnative-for-longdo --workspace @mapconductor/reactnative-for-maptiler --workspace @mapconductor/reactnative-for-tomtom --workspace @mapconductor/reactnative-for-mapbox --workspace @mapconductor/react-geojson --workspace @mapconductor/react-kml --workspace @mapconductor/react-heatmap --workspace @mapconductor/react-marker-clustering",
+ "build:packages": "npm run build --if-present --workspace @mapconductor/js-sdk-core --workspace @mapconductor/js-sdk-react --workspace @mapconductor/react-icons --workspace @mapconductor/react-for-googlemaps --workspace @mapconductor/react-for-maplibre --workspace @mapconductor/react-for-mapbox --workspace @mapconductor/react-for-leaflet --workspace @mapconductor/react-for-openlayers --workspace @mapconductor/react-for-arcgis --workspace @mapconductor/react-for-mapkit --workspace @mapconductor/react-for-azuremaps --workspace @mapconductor/react-for-cesium --workspace @mapconductor/react-for-here --workspace @mapconductor/react-for-tomtom --workspace @mapconductor/react-for-maptiler --workspace @mapconductor/react-for-longdo --workspace @mapconductor/react-for-mappls --workspace @mapconductor/react-for-deckgl --workspace @mapconductor/reactnative-for-googlemaps --workspace @mapconductor/reactnative-for-maplibre --workspace @mapconductor/reactnative-for-arcgis --workspace @mapconductor/reactnative-for-longdo --workspace @mapconductor/reactnative-for-maptiler --workspace @mapconductor/reactnative-for-tomtom --workspace @mapconductor/reactnative-for-mapbox --workspace @mapconductor/react-geojson --workspace @mapconductor/react-kml --workspace @mapconductor/react-heatmap --workspace @mapconductor/react-vectorstyle --workspace @mapconductor/react-vectortile --workspace @mapconductor/react-marker-clustering",
"dev": "npm run build:packages && (npm run dev:packages & npm run dev:examples & wait)",
"dev:rn": "npm run build:packages && (npm run dev:packages & npm run dev:rn:examples & wait)",
"dev:rn:android": "npm run build && npm run expo:android --workspace @mapconductor/example-rn-basic",
"dev:rn:ios": "npm run build && npm run expo:prebuild:ios --workspace @mapconductor/example-rn-basic && npm run expo:ios --workspace @mapconductor/example-rn-basic",
- "dev:packages": "(npm run dev --workspace @mapconductor/js-sdk-core -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/js-sdk-react -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-icons -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-googlemaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-maplibre -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mapbox -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-leaflet -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-openlayers -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mapkit -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-azuremaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-cesium -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-maptiler -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-longdo -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mappls -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-googlemaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-maplibre -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-arcgis -- --tsconfig ../tsconfig.dev.json & npm run dev -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-longdo -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-maptiler --workspace @mapconductor/reactnative-for-tomtom -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-mapbox -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-geojson -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-kml -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-heatmap -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-marker-clustering -- --tsconfig ../tsconfig.dev.json & wait)",
+ "dev:packages": "(npm run dev --workspace @mapconductor/js-sdk-core -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/js-sdk-react -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-icons -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-googlemaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-maplibre -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mapbox -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-leaflet -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-openlayers -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mapkit -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-azuremaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-cesium -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-maptiler -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-longdo -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-mappls -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-for-deckgl -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-googlemaps -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-maplibre -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-arcgis -- --tsconfig ../tsconfig.dev.json & npm run dev -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-longdo -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-maptiler --workspace @mapconductor/reactnative-for-tomtom -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/reactnative-for-mapbox -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-geojson -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-kml -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-heatmap -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-marker-clustering -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-vectorstyle -- --tsconfig ../tsconfig.dev.json & npm run dev --workspace @mapconductor/react-vectortile -- --tsconfig ../tsconfig.dev.json & wait)",
"dev:examples": "npm run dev --workspace @mapconductor/example-basic",
"dev:rn:examples": "npm run expo:start --workspace @mapconductor/example-rn-basic -- --clear",
"link:local": "node scripts/link-local-workspaces.mjs",
diff --git a/react-for-arcgis b/react-for-arcgis
index 68494ec..420108f 160000
--- a/react-for-arcgis
+++ b/react-for-arcgis
@@ -1 +1 @@
-Subproject commit 68494ec41982e2a44686226b21ddd6d10569cd9b
+Subproject commit 420108f1aa9d9c97b6c88417bbae5cbbd78ce7f0
diff --git a/react-for-azuremaps b/react-for-azuremaps
index 7f4c6bc..915b19a 160000
--- a/react-for-azuremaps
+++ b/react-for-azuremaps
@@ -1 +1 @@
-Subproject commit 7f4c6bcf1021c5817d4682b19ba87cd1fb10bae7
+Subproject commit 915b19ae131fddc017b580fa55fab997ca657d09
diff --git a/react-for-cesium b/react-for-cesium
index 06df488..7aac9f0 160000
--- a/react-for-cesium
+++ b/react-for-cesium
@@ -1 +1 @@
-Subproject commit 06df4884b659bd2913f1683fa181af82f6a329aa
+Subproject commit 7aac9f0bd5ed82b9aaf841ad305d37e3d26e6e73
diff --git a/react-for-deckgl b/react-for-deckgl
new file mode 160000
index 0000000..d339617
--- /dev/null
+++ b/react-for-deckgl
@@ -0,0 +1 @@
+Subproject commit d33961786918f94390a1d27949d5c7dc89923b32
diff --git a/react-for-googlemaps b/react-for-googlemaps
index 1210c48..8786dbb 160000
--- a/react-for-googlemaps
+++ b/react-for-googlemaps
@@ -1 +1 @@
-Subproject commit 1210c4884797ecb5b472a0c634fdc7b15c3cd8ba
+Subproject commit 8786dbbe08fa2fd9ccee661f18d7c2de7d71e749
diff --git a/react-for-here b/react-for-here
index edb28a6..156cd9f 160000
--- a/react-for-here
+++ b/react-for-here
@@ -1 +1 @@
-Subproject commit edb28a60f6f963fa96a317ad24d24348936ff2a2
+Subproject commit 156cd9f6c8e3524df596e4e616a74dfdd29e11a6
diff --git a/react-for-leaflet b/react-for-leaflet
index fe8994a..c508eec 160000
--- a/react-for-leaflet
+++ b/react-for-leaflet
@@ -1 +1 @@
-Subproject commit fe8994aaf19dab7635542a6d40be220579bdd786
+Subproject commit c508eece65b6fde4b3c81c9d5ea18f4c08a0989a
diff --git a/react-for-longdo b/react-for-longdo
index 58860ee..6223249 160000
--- a/react-for-longdo
+++ b/react-for-longdo
@@ -1 +1 @@
-Subproject commit 58860eee2cdf8d31d4197ae3fabb840802771cfa
+Subproject commit 622324936246bb04a17e5fd43b600dcb7df958d3
diff --git a/react-for-mapbox b/react-for-mapbox
index 148a371..4c70f45 160000
--- a/react-for-mapbox
+++ b/react-for-mapbox
@@ -1 +1 @@
-Subproject commit 148a3712b08a5314494e371c0163e09e0dcbd0cb
+Subproject commit 4c70f452ad332a8776552c77047eca4c6ede5f40
diff --git a/react-for-mapkit b/react-for-mapkit
index 0665b6a..3e0044f 160000
--- a/react-for-mapkit
+++ b/react-for-mapkit
@@ -1 +1 @@
-Subproject commit 0665b6a9438ac1b354f16dc6a11ab9fda89f8a50
+Subproject commit 3e0044f8c88ee44737e5fa40b3a269c7b679139e
diff --git a/react-for-maplibre b/react-for-maplibre
index 38cdf43..c3e312e 160000
--- a/react-for-maplibre
+++ b/react-for-maplibre
@@ -1 +1 @@
-Subproject commit 38cdf43e1ff882565eae677ce114b2dc09d58dae
+Subproject commit c3e312efdf2c8e6768ef0f8634a5369285089abc
diff --git a/react-for-mappls b/react-for-mappls
index f0d5187..8f36324 160000
--- a/react-for-mappls
+++ b/react-for-mappls
@@ -1 +1 @@
-Subproject commit f0d5187748b2802a9b49b244045c4752d9b23f40
+Subproject commit 8f36324e50012bcc70d5b395d413dbae1e665a1f
diff --git a/react-for-maptiler b/react-for-maptiler
index 0311762..0abcdc3 160000
--- a/react-for-maptiler
+++ b/react-for-maptiler
@@ -1 +1 @@
-Subproject commit 03117625bfcb2baa0eebfdb68df03152ee96a70d
+Subproject commit 0abcdc38a91788692f8ac6fd85f5de712d904efc
diff --git a/react-for-openlayers b/react-for-openlayers
index 4efb45c..bbd2eb5 160000
--- a/react-for-openlayers
+++ b/react-for-openlayers
@@ -1 +1 @@
-Subproject commit 4efb45cd7559e1ff7e09c373f92f4d8c82a0e191
+Subproject commit bbd2eb5cf56005a312e7f22f3ddbc433e46a1bc1
diff --git a/react-for-template/api/react-for-template.api.d.ts b/react-for-template/api/react-for-template.api.d.ts
new file mode 100644
index 0000000..93950e6
--- /dev/null
+++ b/react-for-template/api/react-for-template.api.d.ts
@@ -0,0 +1,302 @@
+import { OverlayKind, GeoPoint, MapViewHolderBase, Offset, GeoPointInterface, MapDesignTypeInterface, CircleController, AbstractCircleOverlayRenderer, CircleState, CircleEntity, GroundImageController, AbstractGroundImageOverlayRenderer, GroundImageState, GroundImageEntity, AbstractMarkerController, AbstractMarkerOverlayRenderer, MarkerEntity, AddParams, ChangeParams, PolygonController, AbstractPolygonOverlayRenderer, PolygonState, PolygonEntity, PolylineController, AbstractPolylineOverlayRenderer, PolylineState, PolylineEntity, RasterLayerController, RasterLayerOverlayRenderer, RasterLayerState, RasterLayerEntity, BaseMapViewController, MapViewControllerInterface, WebMercatorZoomAltitudeConverter, MapCameraPosition, GeoRectBounds, MutableMapServiceRegistry, MapUISettings, MapViewStateInterface, MapViewStyle, MapViewState } from '@mapconductor/js-sdk-core';
+import * as react from 'react';
+import { ReactNode } from 'react';
+
+/** 地図に置かれた図形 1 つ。実際の SDK では `maplibregl.Marker` などにあたる。 */
+interface TemplateShape {
+ readonly id: string;
+ readonly kind: OverlayKind;
+ points: GeoPoint[];
+}
+/** 地図 SDK の代役。 */
+declare class TemplateMap {
+ /** カメラ。実際の SDK では `map.getCenter()` / `getZoom()` にあたる。 */
+ center: GeoPoint;
+ zoom: number;
+ bearingDegrees: number;
+ tiltDegrees: number;
+ /** ビューポート。実際の SDK では `map.getCanvas()` の大きさ。 */
+ sizePx: {
+ width: number;
+ height: number;
+ };
+ /** パンできるか。ドラッグ中だけ切る。 */
+ dragPanEnabled: boolean;
+ readonly shapes: Map;
+ /** SDK 側のイベント。ドライバーはこれをコアの受け口へ転送する(実装点 E)。 */
+ onCameraChanged: (() => void) | null;
+ onClick: ((offset: Offset) => void) | null;
+ add(id: string, kind: OverlayKind, points: GeoPoint[]): TemplateShape;
+ remove(id: string): void;
+ /**
+ * 地理座標 → 画面座標。
+ *
+ * 代役なので素の Web メルカトルで計算する。**bearing と tilt は無視している**ので、
+ * 回転・傾斜させた状態では位置がずれる。だから `declareCapabilities()` で
+ * `cameraRotate` / `cameraTilt` を `approximated` として宣言している
+ * (`unsupported` ではない)。
+ */
+ project(position: GeoPointInterface): Offset;
+ /** 画面座標 → 地理座標。`project` の逆。 */
+ unproject(offset: Offset): GeoPoint;
+}
+/**
+ * 実装点 A。**投影をここ以外に書かないこと。**
+ *
+ * コアの InfoBubble・タイル方式マーカーの当たり判定・マーカーアニメ・
+ * `buildVisibleRegion` は、すべてここを通して画面座標を得る。
+ *
+ * 同期変換が用意できない SDK(WebView ブリッジなど)は `fromScreenOffsetSync` を
+ * 実装せず、`fromScreenOffset` の async だけ実装する。コアは同期変換の有無を見て
+ * 経路を変える(`ScreenProjectionRequirement`)。**同期を必須にしない。**
+ */
+declare class TemplateMapViewHolder extends MapViewHolderBase {
+ readonly mapView: HTMLElement | null;
+ readonly map: TemplateMap;
+ constructor(mapView: HTMLElement | null, map: TemplateMap);
+ toScreenOffset(position: GeoPointInterface): Offset;
+ fromScreenOffsetSync(offset: Offset): GeoPoint;
+}
+/**
+ * 実装点 C。SDK のスタイル指定を表す型。
+ *
+ * `MapDesignTypeInterface` が要求するのは `id` と `getValue()` の 2 つだけ。
+ * `getValue()` は「同じ見た目か」の比較に使われるので、**見た目を決める要素を
+ * すべて含めた文字列**を返すこと(id だけだと、同じ id で URL 違いのデザインを
+ * 切り替えたときに再読み込みが走らない)。
+ */
+interface TemplateMapDesignType extends MapDesignTypeInterface {
+ readonly styleUrl: string;
+}
+declare class TemplateDesign implements TemplateMapDesignType {
+ readonly id: string;
+ readonly styleUrl: string;
+ constructor(id: string, styleUrl: string);
+ getValue(): string;
+ static readonly Standard: TemplateDesign;
+ static readonly Satellite: TemplateDesign;
+}
+
+declare class TemplateCircleRenderer extends AbstractCircleOverlayRenderer {
+ createCircle(state: CircleState): Promise;
+ updateCircleProperties({ circle, current, }: {
+ circle: TemplateShape;
+ current: CircleEntity;
+ prev: CircleEntity;
+ }): Promise;
+ removeCircle(entity: CircleEntity): Promise;
+}
+/**
+ * コントローラは差分も購読も持たない。
+ *
+ * **`kind` と `resolveTap` はコアの `CircleController` が持っている。**
+ * 自前で `OverlayControllerLike` を組む(複数レンダラを束ねる「コンダクタ」を
+ * 作る)ときだけ、`implements SlottedOverlayController` を明示して書くこと。
+ * TypeScript は構造的型付けなので、書き忘れても型は通ってしまう。
+ */
+declare class TemplateCircleController extends CircleController {
+ constructor(renderer: TemplateCircleRenderer);
+}
+declare class TemplatePolylineRenderer extends AbstractPolylineOverlayRenderer {
+ createPolyline(state: PolylineState): Promise;
+ updatePolylineProperties({ polyline, current, }: {
+ polyline: TemplateShape;
+ current: PolylineEntity;
+ prev: PolylineEntity;
+ }): Promise;
+ removePolyline(entity: PolylineEntity): Promise;
+}
+declare class TemplatePolylineController extends PolylineController {
+ constructor(renderer: TemplatePolylineRenderer);
+}
+declare class TemplatePolygonRenderer extends AbstractPolygonOverlayRenderer {
+ createPolygon(state: PolygonState): Promise;
+ updatePolygonProperties({ polygon, current, }: {
+ polygon: TemplateShape;
+ current: PolygonEntity;
+ prev: PolygonEntity;
+ }): Promise;
+ removePolygon(entity: PolygonEntity): Promise;
+}
+declare class TemplatePolygonController extends PolygonController {
+ constructor(renderer: TemplatePolygonRenderer);
+}
+declare class TemplateGroundImageRenderer extends AbstractGroundImageOverlayRenderer {
+ createGroundImage(state: GroundImageState): Promise;
+ updateGroundImageProperties({ groundImage, }: {
+ groundImage: TemplateShape;
+ current: GroundImageEntity;
+ prev: GroundImageEntity;
+ }): Promise;
+ removeGroundImage(entity: GroundImageEntity): Promise;
+}
+declare class TemplateGroundImageController extends GroundImageController {
+ constructor(renderer: TemplateGroundImageRenderer);
+}
+/**
+ * ラスターレイヤだけは抽象基底が無く、インタフェースを直に実装する
+ * (GL 系はソースとレイヤをまとめて差し替えるのが最速なので、
+ * per-object の既定を押しつけていない)。
+ */
+declare class TemplateRasterLayerRenderer implements RasterLayerOverlayRenderer {
+ readonly holder: TemplateMapViewHolder;
+ constructor(holder: TemplateMapViewHolder);
+ onAdd(data: {
+ state: RasterLayerState;
+ }[]): Promise<(TemplateShape | null)[]>;
+ onChange(data: {
+ current: RasterLayerEntity;
+ }[]): Promise<(TemplateShape | null)[]>;
+ onRemove(data: RasterLayerEntity[]): Promise;
+ /** カメラが動くたびに呼ばれる。タイルの貼り直しが要る SDK はここで行う。 */
+ onCameraChanged(): Promise;
+ onPostProcess(): Promise;
+}
+declare class TemplateRasterLayerController extends RasterLayerController {
+ constructor(renderer: TemplateRasterLayerRenderer);
+}
+declare class TemplateMarkerRenderer extends AbstractMarkerOverlayRenderer {
+ constructor(holder: TemplateMapViewHolder);
+ /**
+ * ドラッグ中や位置更新でネイティブのマーカーを動かす。
+ * 実際の SDK では `marker.setLngLat(...)` にあたる。
+ */
+ setMarkerPosition(markerEntity: MarkerEntity, position: GeoPoint): void;
+ /**
+ * `bitmapIcon` は**コアが用意した最終的なアイコン**。既定アイコンの合成も
+ * ラベル描画も済んでいる。SDK のマーカーに載せるだけでよい。
+ */
+ onAdd(data: AddParams[]): Promise<(TemplateShape | null)[]>;
+ onChange(data: ChangeParams[]): Promise<(TemplateShape | null)[]>;
+ onRemove(data: MarkerEntity[]): Promise;
+ /**
+ * アニメーションを持たない SDK は空のままでよい。ただし
+ * `animateStartListener` / `animateEndListener` を呼ばないなら、
+ * その capability を `unsupported` で宣言すること(黙って無反応にしない)。
+ */
+ onAnimate(_entity: MarkerEntity): Promise;
+ onPostProcess(): Promise;
+}
+declare class TemplateMarkerController extends AbstractMarkerController {
+ constructor(renderer: TemplateMarkerRenderer);
+}
+
+/**
+ * 実装点 B。
+ *
+ * ## 書くもの
+ * - `holder`(投影の注入点)
+ * - `readNativeCamera()`(SDK のカメラ → `MapCameraPosition`)
+ * - `moveCamera` / `animateCamera` / `fitBounds`
+ *
+ * ## 書かないもの
+ * - クリックのカスケード … `dispatchTap(position)` を呼ぶだけ
+ * - Capable ファサードの 22 メソッド … `registerOverlayController` するだけ
+ * - マーカーのドラッグの状態遷移 … `DefaultMarkerEventController`
+ */
+declare class TemplateMapViewController extends BaseMapViewController implements MapViewControllerInterface {
+ readonly map: TemplateMap;
+ readonly holder: TemplateMapViewHolder;
+ private readonly circleController;
+ private readonly polylineController;
+ private readonly polygonController;
+ private readonly groundImageController;
+ private readonly rasterLayerController;
+ private readonly markerController;
+ /**
+ * 統一ズーム(Google 準拠)と SDK の生ズームの相互変換。
+ *
+ * SDK のズームが Google と同じ体系なら `zoomOffset: 0`。
+ * タイル 512px 系(Mapbox など)は `zoomOffset: 1`。
+ * **較正値をコアに固定しないこと。**同じ SDK でもプラットフォームで違う値になる。
+ */
+ readonly zoomConverter: WebMercatorZoomAltitudeConverter;
+ constructor(map: TemplateMap);
+ private installListeners;
+ /**
+ * SDK のカメラ → `MapCameraPosition`。**生ズームを統一ズームへ直すのを忘れない。**
+ * ここがずれると、当たり判定の許容量が実際の縮尺と食い違い、
+ * 「線や円をタップしても反応しない」という形で表面化する。
+ */
+ readNativeCamera(): MapCameraPosition;
+ /** 4 隅を逆投影して可視範囲を組む。ホルダーの投影が唯一の入口。 */
+ private buildVisibleRegion;
+ moveCamera(position: MapCameraPosition): Promise;
+ animateCamera(position: MapCameraPosition, _durationMillis: number): Promise;
+ fitBounds(bounds: GeoRectBounds, _padding: number): Promise;
+ private apply;
+ /**
+ * 実装点 H。**`unknown` と `unsupported` を混同しないこと。**
+ *
+ * 宣言が無い(`unknown`)は「まだ宣言していない」であって「使えない」ではない。
+ * `unsupported` にすると**コアが動いている機能を止める**。
+ * 別経路で動いているなら `degraded` / `approximated` にすること。
+ */
+ declareCapabilities(registry: MutableMapServiceRegistry): void;
+ applyUISettings(settings: MapUISettings): void;
+ clearOverlays(): Promise;
+ /** 地図の破棄。登録済みコントローラの後始末はコアがやる。 */
+ destroy(): void;
+ /** 任意の地点をタップさせるテスト用の入口。 */
+ simulateClick(position: GeoPoint): boolean;
+}
+
+/**
+ * 実装点 G。**残るのは 3 つだけ。**
+ *
+ * - `mapDesignType`(プロバイダ固有の型)
+ * - プロバイダ型のホルダー
+ * - `getMapViewHolder()` の絞り込み
+ *
+ * カメラの保持・`moveCameraTo` の 2 種・`fitBounds`・`attachController`・
+ * `uiSettings`・`id` はコアの `MapViewState` が持つ。
+ *
+ * ## `optimisticCameraUpdate` は web だけ既定 true
+ *
+ * web の地図エンジンはカメライベントが非同期なので、`moveCamera` の直後に
+ * `state.cameraPosition` を読んでも古い値が返らないよう、要求値を先に反映する。
+ * android / iOS は push で同期的に返るので false。**ここだけ既定が違う。**
+ */
+declare class TemplateViewState extends MapViewState {
+ private _mapDesignType;
+ mapViewHolder: TemplateMapViewHolder | null;
+ constructor({ id, mapDesignType, cameraPosition, }?: {
+ id?: string;
+ mapDesignType?: TemplateMapDesignType;
+ cameraPosition?: MapCameraPosition;
+ });
+ get mapDesignType(): TemplateMapDesignType;
+ set mapDesignType(value: TemplateMapDesignType);
+}
+declare function useTemplateViewState(params?: {
+ id?: string;
+ mapDesignType?: TemplateMapDesignType;
+ cameraPosition?: MapCameraPosition;
+}): MapViewStateInterface;
+/**
+ * アプリ開発者が書くのはこれ。実際のドライバーでは `useEffect` の中で
+ * SDK の地図を `container` にマウントする。
+ *
+ * ```tsx
+ *
+ *
+ *
+ *
+ * ```
+ */
+declare function TemplateMapView({ state, mapStyle, onStyleDiagnostics, children, }: {
+ state: MapViewStateInterface;
+ /**
+ * 実装点。**全プロバイダが同じ名前で受けること。** 何が起きるかはこの
+ * バックエンドが宣言した能力で決まる: `VectorStyleSupportKey` も
+ * `VectorStyleMutationSupportKey` も宣言していなければ、スタイルは
+ * ラスタータイルとして届く。
+ *
+ * android / iOS では `style`。JS だけ違う理由は `MapViewBaseProps` に。
+ */
+ mapStyle?: MapViewStyle | null;
+ onStyleDiagnostics?: (diagnostics: readonly string[]) => void;
+ children?: ReactNode;
+}): react.JSX.Element;
+
+export { TemplateCircleController, TemplateCircleRenderer, TemplateDesign, TemplateGroundImageController, TemplateGroundImageRenderer, TemplateMap, type TemplateMapDesignType, TemplateMapView, TemplateMapViewController, TemplateMapViewHolder, TemplateMarkerController, TemplateMarkerRenderer, TemplatePolygonController, TemplatePolygonRenderer, TemplatePolylineController, TemplatePolylineRenderer, TemplateRasterLayerController, TemplateRasterLayerRenderer, type TemplateShape, TemplateViewState, useTemplateViewState };
diff --git a/react-for-template/src/TemplateMapView.tsx b/react-for-template/src/TemplateMapView.tsx
index 23e0606..7224c23 100644
--- a/react-for-template/src/TemplateMapView.tsx
+++ b/react-for-template/src/TemplateMapView.tsx
@@ -5,7 +5,9 @@ import {
MapViewState,
type MapCameraPosition,
type MapViewStateInterface,
+ type MapViewStyle,
} from '@mapconductor/js-sdk-core';
+import { useMapViewStyle } from '@mapconductor/js-sdk-react/internal';
import { TemplateDesign, TemplateMap, TemplateMapViewHolder, type TemplateMapDesignType } from './TemplateMap';
import { TemplateMapViewController } from './TemplateMapViewController';
@@ -82,19 +84,38 @@ export function useTemplateViewState(params: {
*/
export function TemplateMapView({
state,
+ mapStyle,
+ onStyleDiagnostics,
children,
}: {
state: MapViewStateInterface;
+ /**
+ * 実装点。**全プロバイダが同じ名前で受けること。** 何が起きるかはこの
+ * バックエンドが宣言した能力で決まる: `VectorStyleSupportKey` も
+ * `VectorStyleMutationSupportKey` も宣言していなければ、スタイルは
+ * ラスタータイルとして届く。
+ *
+ * android / iOS では `style`。JS だけ違う理由は `MapViewBaseProps` に。
+ */
+ mapStyle?: MapViewStyle | null;
+ onStyleDiagnostics?: (diagnostics: readonly string[]) => void;
children?: ReactNode;
}) {
const containerRef = useRef(null);
const controllerRef = useRef(null);
+ // コントローラができたら再レンダーさせる。スタイルの設置はコントローラが
+ // 要るので、ref に入れるだけでは設置の機会が来ない。
+ const [controller, setController] = useState(null);
+
+ // 実装点。1 行で、プロバイダ固有の分岐は無い。
+ useMapViewStyle(state, controller, mapStyle, onStyleDiagnostics);
useEffect(() => {
// 実際のドライバーはここで `new maplibregl.Map({ container })` する。
const map = new TemplateMap();
const controller = new TemplateMapViewController(map);
controllerRef.current = controller;
+ setController(controller);
const internal = state as unknown as {
attachController?: (c: TemplateMapViewController) => void;
@@ -108,6 +129,7 @@ export function TemplateMapView({
return () => {
controller.destroy();
controllerRef.current = null;
+ setController(null);
};
}, [state]);
diff --git a/react-for-tomtom b/react-for-tomtom
index 42a14b3..325ed80 160000
--- a/react-for-tomtom
+++ b/react-for-tomtom
@@ -1 +1 @@
-Subproject commit 42a14b39ad3d535e1561eb563c595aeb4feb84da
+Subproject commit 325ed80186119e7c67d165e599d23de10fea50ef
diff --git a/react-icons-jp b/react-icons-jp
index 56f2485..6f01918 160000
--- a/react-icons-jp
+++ b/react-icons-jp
@@ -1 +1 @@
-Subproject commit 56f24854d51e8e676dcfeb46a00e43b88450fa84
+Subproject commit 6f019189b9d3e2d3fb66cd887e311b0ca3dfafbf
diff --git a/react-icons-us b/react-icons-us
index 7f79aaa..cd0f3af 160000
--- a/react-icons-us
+++ b/react-icons-us
@@ -1 +1 @@
-Subproject commit 7f79aaa7ce33a858a0249ae2fcd83ba07a6ea5c2
+Subproject commit cd0f3af0899f45b6e16b8e85504735f2101a3376
diff --git a/react-icons-weather b/react-icons-weather
index 518e1a2..898c023 160000
--- a/react-icons-weather
+++ b/react-icons-weather
@@ -1 +1 @@
-Subproject commit 518e1a2882e411a960ab9e5c9f789137e5560a86
+Subproject commit 898c0234dbc54c010232e66f5d43929f9647575c
diff --git a/react-kml b/react-kml
new file mode 160000
index 0000000..2e4e9a3
--- /dev/null
+++ b/react-kml
@@ -0,0 +1 @@
+Subproject commit 2e4e9a36d7be83ce12528b0ff2da3305970e1cdd
diff --git a/react-kml/README.es-419.md b/react-kml/README.es-419.md
deleted file mode 100644
index 797ab12..0000000
--- a/react-kml/README.es-419.md
+++ /dev/null
@@ -1,42 +0,0 @@
-[English](./README.md) | [日本語](./README.ja.md) | Español (Latinoamérica)
-
-# @mapconductor/react-kml
-
-Extensión de capa KML para el MapConductor React SDK. Analiza documentos OGC
-KML 2.2 (y archivos KMZ) en modelos de elementos y los renderiza como una
-superposición de mosaicos dentro de cualquier vista de mapa de proveedor
-(`react-for-googlemaps`, `react-for-maplibre`, `react-for-here`, …), con
-estilos KML y detección de clics. Comparte la arquitectura de renderizado por
-mosaicos de `@mapconductor/react-geojson`, por lo que escala a conjuntos
-de datos KML grandes.
-
-El soporte para React Native aún no está disponible — por ahora este paquete es
-solo para web.
-
-## Características
-
-- Analiza `Point`, `LineString`, `LinearRing`, `Polygon` (con agujeros de
- `innerBoundaryIs`) y `MultiGeometry`.
-- Lee archivos KMZ de forma transparente: la entrada ZIP se detecta por firma y
- se usa la primera entrada `.kml` (convencionalmente `doc.kml`).
-- Recorre contenedores `` y `` anidados con un bucle y un
- contador de profundidad — nunca con recursión.
-- Sigue referencias `` mediante `KMLLoader`, con resolución de
- href relativos, detección de ciclos y un límite de documentos.
-- Resuelve estilos KML: `LineStyle`, `PolyStyle`, `IconStyle`, incluidas las
- referencias compartidas `