ArcGIS Onlineでベクトルタイルのオーバーズーミングを試す

# はじめに
ArcGIS Onlineで外部ベクトルタイルを表示することは[以前の記事](https://qiita.com/k96mz/items/44e40d4cd63c97ca3bd2)で行い、ArcGISベクトルタイルサーバの観察は[こちらの記事](https://qiita.com/k96mz/items/206cd0e30fe9b8707e3d)で行いました。本記事では、ArcGIS Onlineでベクトルタイルのオーバーズーミングをする過程を記載します。
本記事は[こちらの記事](https://qiita.com/T-ubu/items/d2454cd7b018820fa8b1)を参考にさせていただいています。
特に、ズームレベルを上げていく際に、maxLODやmaxZoom、スタイルファイルでのズームレベル設定など、様々な設定項目があり、それが地物の表示にどのような役割を果たしているのかを実験しながら確かめたいと思います。

# 1. ベクトルタイルの作成
参考記事と同様に[NaturalEarth](https://www.naturalearthdata.com/)のデータを使用します。ダウンロードページから、「1:110m Physical Vectors」の「Coastline」、「Land」、「Rivers,Lake Centerlines」、「Graticules 30」をダウンロードします。

以下のようなベクトルタイル構成とします。参考記事では、ズームレベル2で作成されていますが、ここではズームレベルに関して色々と実験したいので、2と3で作成しました。

| レイヤ名 | ソース | Min Zoom | Max Zoom |
|:-:|:-:|:-:|:-:|
| coastl | ne_110m_coastline.shp  | 0 | 3 |
| landmass  | ne_110m_land.shp  | 0 | 3 |
| riverl  | ne_110m_rivers_lake_centerlines.shp  | 0 | 2 |
| graticules30  | ne_110m_graticules_30.shp  | 0 | 2 |

ベクトルタイルの作成方法は[こちらの記事](https://qiita.com/k96mz/items/1f7e0f8e6e41e6a78cc6)に記載しています。記事にある通り、shp→GeoJSON→ベクトルタイルの順番でデータを変換します。
ズームレベル2,3をそれぞれ作成する必要があるため、以下の２つのコマンドを使用しました。

ズームレベル3を作成
```
tippecanoe -e VTcoastl_landmass_zl3 --no-tile-compression --no-feature-limit --no-tile-size-limit --drop-rate=1 -Z0 -z3 -L coastl:coastl.geojson -L landmass:landmass.geojson
```

ズームレベル2を作成
```
tippecanoe -e VTriverl_graticules30_zl2 --no-tile-compression --no-feature-limit --no-tile-size-limit --drop-rate=1 -Z0 -z2 -L riverl:riverl.geojson -L graticules30:graticules30.geojson
```

その後、[tile-join](https://github.com/felt/tippecanoe/tree/main?tab=readme-ov-file#tile-join)を使用して、２つのベクトルタイルを統合しました。

```
tile-join -e VT --no-tile-size-limit --no-tile-compression --minimum-zoom=0 --maximum-zoom=3 VTcoastl_landmass_zl3 VTriverl_graticules30_zl2
```

コマンドを実行すると、ベクトルタイルのズームレベルが合致していないという以下の警告が出ましたが、ベクトルタイル自体は作成出来ました。
Warning: mismatched maxzooms: 3 in VTcoastl_landmass_zl3 vs previous 2

ついでにmbtilesも作成しておきます。
```
tile-join -o VTtest.mbtiles --no-tile-size-limit --minimum-zoom=0 --maximum-zoom=3 VTcoastl_landmass_zl3 VTriverl_graticules30_zl2 
```
以下に格納されています。
https://github.com/k96mz/20250117tilemap/tree/main/VectorTileServer/data/mbtiles

# 2. GitHubページでのホスティング
Gethubページに[新しいレポジトリ](https://github.com/k96mz/20250117tilemap)を作成しました。
[Esriさんのページ](https://developers.arcgis.com/rest/services-reference/enterprise/vector-tile-service/)に記載されているようにフォルダを構成します。
具体的には、VectorTileServerフォルダの下にtileフォルダを作成し、そこにベクトルタイルを格納します。ベクトルタイルはz/x/y.pbfという構造にする必要があります。
ベクトルタイルを作成する際にVTという名前を使用していましたが、ここもtileという名前で作ると便利だったかもしれません。
Github > Settings > Pages からデータをホストする設定を行います。これで、以下のURLからベクトルタイルへのアクセスが可能となります。
https:\//k96mz.github.io/20250117tilemap/VectorTileServer/tile/{z}/{x}/{y}.pbf

# 3. スタイルファイル作成
アップロードしたベクトルタイルを見るためにMaputnikを使用してスタイルファイルを作成します。Maputnikの使用方法は[こちらの記事](https://qiita.com/k96mz/items/588a5241327f51cb5f9f)で解説しています。

Maputnikを使用して以下のようにスタイリングを行いました。

![スクリーンショット 2025-01-17 15.22.43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/0dd423b1-202b-f5a2-ed64-4ff7cb3a38cb.jpeg)

スタイルは参考記事同様に以下のように整理しています。

| レイヤID | Type | Min Zoom | Max Zoom |
|:-:|:-:|:-:|:-:|
| background | background  | na | na |
| coastl | line  | na | 6 |
| landmass  | fill  | na | 6 |
| riverl  | line  | na | 6 |
| graticules30  | line  | na | 2 |

Max Zoom以上に拡大すると該当レイヤは見られなくなります。

:::note info
注意
Maputnikが不安定なのか、作成したMaxズームレベル + 1まで（例えばlandmassなら4）しか見られないときもあります。つまりはズームレベルが４になった瞬間に見られない時がありました。（ズームレベル６まで継続して見られませんでした。）
これは、もしかしたら、tile-joinを使用した影響があるのかもしれません。
:::

Maputnikの使用方法を説明した記事でも言及していますが、sourcesの"maxzoom"はレイヤの表示に影響を与えないようです。

作成したスタイルファイルを利用した地図は、Maputnikを利用して[こちら](https://maputnik.github.io/editor/?style=https://k96mz.github.io/20250117tilemap/VectorTileServer/resources/styles/root_tileurl.json)から見られます。

作成したスタイルファイルは、tileのパスが指定されていますが、ArcGIS OnlineではサーバURLを記載する必要があるようですので、以下に変更する必要があります。
https://k96mz.github.io/20250117tilemap/VectorTileServer/

また、tilesをurlに変更する必要があること、タイルを指定する際にあった[]を削除することにも、注意が必要です。urlの最後のスラッシュは削除しています。

変更後のスタイルファイルは以下のとおりです。Esriさんのドキュメントに記載のある通り、VectorTileServerフォルダの下にresources/stylesフォルダを作成して、root.jsonとして保存します。

```json: root.json
{
  "version": 8,
  "name": "Empty Style",
  "metadata": { "maputnik:renderer": "mlgljs" },
  "sources": {
    "v": {
      "type": "vector",
      "url": "https://k96mz.github.io/20250117tilemap/VectorTileServer",
      "minzoom": 0,
      "maxzoom": 8,
      "scheme": "xyz"
    }
  },
  "sprite": "",
  "glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf",
  "layers": [
    {
      "id": "background",
      "type": "background",
      "paint": { "background-color": "rgba(35, 113, 123, 1)" }
    },
    {
      "id": "coastl",
      "type": "line",
      "source": "v",
      "source-layer": "coastl",
      "maxzoom": 6,
      "paint": { "line-color": "rgba(15, 16, 14, 1)" }
    },
    {
      "id": "landmass",
      "type": "fill",
      "source": "v",
      "source-layer": "landmass",
      "maxzoom": 6,
      "paint": { "fill-color": "rgba(191, 142, 92, 1)" }
    },
    {
      "id": "riverl",
      "type": "line",
      "source": "v",
      "source-layer": "riverl",
      "maxzoom": 6,
      "paint": { "line-color": "rgba(8, 45, 214, 1)" }
    },
    {
      "id": "graticules30",
      "type": "line",
      "source": "v",
      "source-layer": "graticules30",
      "maxzoom": 2,
      "paint": { "line-color": "rgba(222, 16, 16, 1)" }
    }
  ],
  "id": "9vv30hv"
}
```

[Esriドキュメント](https://developers.arcgis.com/rest/services-reference/enterprise/vector-tile-style/)にない、"metadata"や"_ssl"の記載があっても問題ないようです。

# 4. ベクトルタイルサーバ情報の作成
[Esriドキュメント](https://developers.arcgis.com/rest/services-reference/enterprise/vector-tile-service/)を参照して、VectorTileServerフォルダの下に、index.jsonを作成します。

```json: index.json
{
  "currentVersion": 10.9,
  "name": "20250117tilemap",
  "capabilities": "TilesOnly,Tilemap",
  "copyrightText": "NaturalEarth",
  "type": "indexedVector",
  "tileMap": "tilemap",
  "defaultStyles": "resources/styles",
  "tiles": [
    "https://k96mz.github.io/20250117tilemap/VectorTileServer/tile/{z}/{x}/{y}.pbf"
  ],
  "exportTilesAllowed": false,
  "initialExtent": {
    "xmin": -2.0037507842788246e7,
    "ymin": -2.0037508342787e7,
    "xmax": 2.0037507842788246e7,
    "ymax": 2.0037508342787e7,
    "spatialReference": {
      "wkid": 102100,
      "latestWkid": 3857
    }
  },
  "fullExtent": {
    "xmin": -2.0037507842788246e7,
    "ymin": -2.0037508342787e7,
    "xmax": 2.0037507842788246e7,
    "ymax": 2.0037508342787e7,
    "spatialReference": {
      "wkid": 102100,
      "latestWkid": 3857
    }
  },
  "minScale": 2.958287637957775e8,
  "maxScale": 1155581.1085775,
  "tileInfo": {
    "rows": 512,
    "cols": 512,
    "dpi": 96,
    "format": "pbf",
    "origin": {
      "x": -2.0037508342787e7,
      "y": 2.0037508342787e7
    },
    "spatialReference": {
      "wkid": 102100,
      "latestWkid": 3857
    },
    "lods": [
      {
        "level": 0,
        "resolution": 78271.516964,
        "scale": 2.958287637957775e8
      },
      {
        "level": 1,
        "resolution": 39135.75848199995,
        "scale": 1.479143818978885e8
      },
      {
        "level": 2,
        "resolution": 19567.87924100005,
        "scale": 7.39571909489445e7
      },
      {
        "level": 3,
        "resolution": 9783.93962049995,
        "scale": 3.6978595474472e7
      },
      {
        "level": 4,
        "resolution": 4891.96981024998,
        "scale": 1.8489297737236e7
      },
      {
        "level": 5,
        "resolution": 2445.98490512499,
        "scale": 9244648.868618
      },
      {
        "level": 6,
        "resolution": 1222.992452562495,
        "scale": 4622324.434309
      },
      {
        "level": 7,
        "resolution": 611.496226281245,
        "scale": 2311162.2171545
      },
      {
        "level": 8,
        "resolution": 305.74811314069,
        "scale": 1155581.1085775
      }
    ]
  },
  "maxzoom": 8,
  "resourceInfo": {
    "styleVersion": 8,
    "tileCompression": "gzip",
    "cacheInfo": {
      "storageInfo": {
        "packetSize": 128,
        "storageFormat": "compactV2"
      }
    }
  },
  "minLOD": 0,
  "maxLOD": 2,
  "maxExportTilesCount": 100000,
  "supportedExtensions": ""
}
```

:::note info
「"maxzoom": 8」と「"maxLOD": 2」の関係性

chatGPTによると、maxzoomがサーバが提供するタイルの最大ズームレベルを指定し、maxLODがクライアント側で表示する最大ズームレベル（LOD: Level of Detail, 詳細レベル）を制限します。つまり、ズームレベル3に達すると、クライアントは新しいタイルをリクエストせず、ズームレベル2のタイルをそのまま拡大して表示します。
:::

"capabilities"には、"Tilemap"も含めています。

このファイルは以下のどのURLでも同じファイルにアクセスできます。
https://k96mz.github.io/20250117tilemap/VectorTileServer/index.json
https://k96mz.github.io/20250117tilemap/VectorTileServer/
https://k96mz.github.io/20250117tilemap/VectorTileServer/?f=json

※試しにベクトルタイルサーバ情報のファイル名をindex2.jsonとしてみたところ、ファイルにアクセス出来ませんでした。index.jsonとする必要があるようです。


# 5. tilemapの作成
次にタイルの有無を返すtilemapファイルを作成します。[こちらの記事](https://qiita.com/k96mz/items/206cd0e30fe9b8707e3d)で見た通り、返すタイルが存在する場合は、ズームレベル5までは一つのファイルが必要で、ズームレベル6以上では４個以上のファイルが必要です。参考記事にもある通り、今回はズームレベル0~6のtilemapを用意します。
ベクトルタイルを作成した際のズームレベルによる挙動の違い（riverlはZL2、landmassはZL3）を確かめるために、ズームレベル3まではベクトルタイルが存在するという情報のtilemapを作成し、それ以降はベクトルタイルが存在しないという情報のtilemapを作成します。
tilemapのURL構成は以下の通りです。
VectorTileServer/tilemap/\<level>/\<row>/\<column>/\<width>/\<height>
日本語で書くと、
VectorTileServer/tilemap/ズームレベル/行（縦方向）/列（横方向）/横幅/縦幅
です。

先ほど記載したとおりズームレベル5までは一つのファイルです。それぞれのtilemapは、ズームレベル毎のタイル数だけ1を持ちます。そして、1を表示する位置は32×32のタイル該当部分となります。
ズームレベル毎のtilemapを以下に示します。

### ズームレベル0

```json: tilemap/0/0/0/32/32/index.json
{
  "adjusted": false,
  "location": {
    "left": 0,
    "top": 0,
    "width": 32,
    "height": 32
  },
  "data": [
    1, 0, 0, 0, 0, 0, 0...
  ]
}
```

タイルの数は１つなので、1は最初の一個だけです。



### ズームレベル1
```json: tilemap/1/0/0/32/32/index.json
{
  "adjusted": false,
  "location": {
    "left": 0,
    "top": 0,
    "width": 32,
    "height": 32
  },
  "data": [
    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,...
  ]
}
```

タイルの数は4つなので、1,1の組み合わせが２個出てきます。


### ズームレベル2

```json: tilemap/2/0/0/32/32/index.json
{
  "adjusted": false,
  "location": {
    "left": 0,
    "top": 0,
    "width": 32,
    "height": 32
  },
  "data": [
    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
    0, 0, 0, 0, 0,....
  ]
}
```

タイルの数は16個なので、1,1,1,1の組み合わせが4個出てきます。

### ズームレベル3

```json: tilemap/3/0/0/32/32/index.json
{
  "adjusted": false,
  "location": {
    "left": 0,
    "top": 0,
    "width": 32,
    "height": 32
  },
  "data": [
    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,...
  ]
}
```

タイルの数は64個なので、1,1,1,1,1,1,1,1の組み合わせが8個出てきます。

### ズームレベル4
リクエストされたバンドル（範囲）がない、もしくは対応するズームレベルでない場合は、以下のとおり422を返します。

```json: tilemap/4/0/0/32/32/index.json
{ "error": { "code": 422, "message": "Tiles not present", "details": [] } }
```

### ズームレベル5
```json: tilemap/5/0/0/32/32/index.json
{ "error": { "code": 422, "message": "Tiles not present", "details": [] } }
```

### ズームレベル6
ズームレベルが６になると、32×32のタイルが４つあるので、4つのtilemapファイルを用意します。

tilemap/6/0/0/32/32/index.json
tilemap/6/32/0/32/32/index.json
tilemap/6/0/32/32/32/index.json
tilemap/6/32/32/32/32/index.json

いずれもズームレベル４、５の時と同様の以下のファイルです。
```json:
{ "error": { "code": 422, "message": "Tiles not present", "details": [] } }
```

# 6. 確認
今まで準備したものをまとめます。
ベクトルタイル：
https:\//k96mz.github.io/20250117tilemap/VectorTileServer/tile/{z}/{x}/{y}.pbf

スタイルファイル：
https://k96mz.github.io/20250117tilemap/VectorTileServer/resources/styles/root.json

ベクトルタイルサーバ情報：
https://k96mz.github.io/20250117tilemap/VectorTileServer/index.json

tilemap：
https:\//k96mz.github.io/20250117tilemap/VectorTileServer/tilemap/z/32m/32n/32/32/index.json（m,nは整数）


# 7. ArcGIS Online(Map Viewr Classic)での読み込み

最後に[こちらの記事](https://qiita.com/k96mz/items/44e40d4cd63c97ca3bd2)で記載したとおりに、ArcGIS OnlineのMap Viewer Classicで読み込んでいきます。

読み込むURLはベクトルタイルサーバ情報の以下です。
https://k96mz.github.io/20250117tilemap/VectorTileServer/

以下のようにして読み込みます。今回は、ベースマップとして読み込んでいます。

![スクリーンショット 2025-01-20 12.15.37.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/365b152b-c078-9000-be5e-9eeeb1ab8fa4.jpeg)

読み込むと以下のように地図が表示されました。

![スクリーンショット 2025-01-20 12.16.01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/4f6056f7-68e6-11d6-9854-1be74a9f3611.jpeg)


ズームレベル0~2については作成したタイルが読み込まれていました。tilemapについては、以下のURLのファイルが読み込まれています。

Request URL:
https://k96mz.github.io/20250117tilemap/VectorTileServer/tilemap/1/0/0/32/32?f=json
については、
Status Code: 301 Moved Permanently
と表示されました。

Request URL:
https://k96mz.github.io/20250117tilemap/VectorTileServer/tilemap/1/0/0/32/32/?f=json
については、
Status Code:200 OK
と表示されました。


![スクリーンショット 2025-01-20 12.18.09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/6e10c484-114d-f8da-3c20-c8f5c01cb603.jpeg)

参考記事も同様のファイルが存在したので、たぶん問題ないのだと思います。

上の図はズームレベル２の状態ですが、graticules30である経緯度線が消えています。これは、スタイルファイルであるroot.jsonに記載された通りの想定された挙動です。

ズームレベル3についても、作成したタイルが読み込まれました。
河川であるriverlについては、tile-joinをする過程で他の地物と統合されたベクトルタイルファイルとなっていますが、データとしてはズームレベル2までしか作成していません。実際にズームレベル３で表示したところ、下図のように河川データは表示されませんでした。
つまりは、tile-joinを行う際に、地物データにズームレベルのばらつきがあると、ズームレベルが小さい地物はそのズームレベル以降ではオーバーズーミングできないことが分かりました。オーバーズーミングをさせたい場合は、全ての地物を同じズームレベルに揃えてデータを作成する必要があります。逆に言えば、オーバーズーミングする必要がない地物だと、異なるズームレベルを持った地物でもtile-joinしても良いことになります。

![スクリーンショット 2025-01-20 12.30.54.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/504bf65f-9dd1-5d76-eaba-0b933e823f28.jpeg)

index.jsonにおいて、"maxLOD": 2,としていますが、これはMap Viewer Classicだと関係ないのかもしれません。

ズームレベル４の時には、tilemapはズームレベル4のファイルが読み込まれますが、ベクトルタイルはズームレベル3のものが再度読み込まれました。例えば、以下のベクトルタイルファイルはズームレベル3で一度読み込まれ、ズームレベル4で再度読み込まれます。
https://k96mz.github.io/20250117tilemap/VectorTileServer/tile/3/6/2.pbf
そのため、キャッシュを使用できると良さそうです。

ズームレベル5はズームレベル4と同じ挙動です。

ズームレベル6は地物の表示がなくなり、backgroundだけになります。これは、スタイルファイルであるroot.jsonに記載された通りの想定された挙動です。

![スクリーンショット 2025-01-20 12.41.03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/e128c3cb-21da-5fac-999f-e50cd3b98491.jpeg)

上図の例では、ズームレベル6にあるtilemapファイル４つのうち、読み込まれたファイルは以下です。
https://k96mz.github.io/20250117tilemap/VectorTileServer/tilemap/6/0/32/32/32/?f=json

ズームレベル6以降はtilemapファイルは存在しない（作成していない）のでエラーが返ります。同様に、ベクトルタイルファイルについてもエラーが返ります。下図はズームレベル8の例です。

![スクリーンショット 2025-01-20 12.48.06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/3a1ef024-0d0b-6780-a1a9-e229a49cdfff.jpeg)


ズームレベル8以降は、ファイル自体が返ってきません。これは、index.jsonでmaxzoomを8としているからな気がします。つまり、index.jsonの設定により、サーバでズームレベル8までしかベクトルタイルやtilemapを返さない設定になっているということです。しかし、ArcGIS Onlineの仕様なのか、ずっと拡大をし続けることは出来ました。もちろん、何も表示されません。





※最後に、表示させたレイヤをArcGIS Onlineに保存しておきます。

# 8. ArcGIS Online(Map Viewer)での読み込み
次にMap Viewer Classicではなく、Map Viewerでの読み込みを実行します。
しかし、Add Layer from URLから読み込みを実行しても、以下のとおりずっと処理中になり読み込めません。

![スクリーンショット 2025-01-20 14.42.33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/5622b4f5-c4e0-dc51-5a58-57f0d84ce227.jpeg)

そこで、Add layerをクリックし、先程保存したレイヤ(20250117tilemap)を追加します。

![スクリーンショット 2025-01-20 14.43.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/2748b82e-c91f-e966-7e10-722233ed7ccb.jpeg)

Map Viewer Classicとの違いは、ズームレベル2のベクトルタイルまでしか読み込まないことです。原因としては、index.jsonの  "maxLOD": 2,によるものと思われます。試しにこれを3にして、再度Map Viewer Classicの読み込みと保存をし、Map Viewerで表示してみます。そうるすると、ズームレベル3のベクトルタイルまで読むことが出来ました。


:::note info
Map Viewer ClassicとMap Viewerの表示仕様の違い

Map Viewer Classicでは、index.jsonの "maxLOD"の影響は不明であるが、Map Viewerでは"maxLOD"で規定されたズームレベルまでしかクライアントに読み込まれない。
:::


:::note info
ズームレベル関係まとめ
A. ベクトルタイル作成時のMax Zoom：それぞれのレイヤが持つ素材の最大ズームレベル
B. スタイルファイルroot.jsonのそれぞれのレイヤのmaxzoom：オーバーズーミング時の最大ズームレベル（画面で表示される際の最大ズームレベル）
C. ベクトルタイルサーバ情報index.jsonのmaxzoom：サーバが提供するタイルの最大ズームレベル。このズームレベル以降はレスポンスを返しません。
D. ベクトルタイルサーバ情報index.jsonのmaxLOD：クライアント側で表示する最大ズームレベル

※Cが一番大きな値を取る。Bのレイヤの一番大きなmaxzoom値を、Dの値にすると整合が取れる
:::

## 読み込みURLを変更してみる
こちらの[Esriドキュメント](https://geoportal.un.org/arcgis/portalhelp/en/portal/11.4/use/add-item-from-url.htm)に記載の通り、以下のようなURLにしないといけないのかもしれません。
```
 https://<fully qualified web adaptor machine name>/<web adaptor name>/rest/services/<service name>/<service type>.
```

そのため、以下のURLで読み込まれるか実験してみました。また、フォルダなども新しく作成しました。
https://k96mz.github.io/20250117tilemap/rest/services/service/VectorTileServer

無事に読み込み出来ました！！！

![スクリーンショット 2025-01-27 16.21.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/560348a4-4af3-4f50-71bc-b0cfd026b736.jpeg)

Map Viewerで保存を選択することが出来ませんでした。

![スクリーンショット 2025-01-27 16.30.22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/94031fc5-6c32-1f50-0476-915310925a2d.jpeg)


しかし、ContentのNew itemから保存することが出来ました。

![スクリーンショット 2025-01-27 16.31.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/7e9a12c3-fe0d-e510-34ec-4613d81fa812.jpeg)



# まとめ
今回はArcGIS Onlineでベクトルタイルのオーバーズーミングを試しました。Map Viewer ClassicとMap Viewerの表示仕様の違いが分かったのが大きな成果です。

# Reference
https://qiita.com/T-ubu/items/d2454cd7b018820fa8b1

https://qiita.com/k96mz/items/44e40d4cd63c97ca3bd2

https://qiita.com/k96mz/items/206cd0e30fe9b8707e3d

https://github.com/k96mz/20250117tilemap

https://qiita.com/k96mz/items/588a5241327f51cb5f9f