0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ArcGIS Onlineでベクトルタイルを読み込めるコードを作る

Last updated at Posted at 2025-01-28

はじめに

こちらの記事で、ArcGIS Onlineでベクトルタイルを表示しました。その際には、tilemapについて最低限必要なファイルを用意しましたが、実際にはズームレベルが大きくなると必要となるファイル数は膨大な数となり、そのファイルを一つ一つ用意することは現実的ではありません。そのため、Node.jsを利用してリクエストパスに応じて動的にレスポンスファイルを作成するコードを作成したいと思います。
ArcGIS Onlineのために必要なindex.json、スタイルファイルroot.jsonもルーティングします。
コードはこちらのGithubページにあります。

Map Viewer Classicでレイヤが保存できない問題

レンタルサーバにおいて、Map Viewer Classicでレイヤが保存できませんでした。そこで、レンタルサーバにおいても、index.json、スタイルファイルroot.jsonについて、リクエストパスに対してルーティングは行わず直接パスを用意することで、ArcGIS Onlineでのレイヤ保存時のエラーがなくなると考えました。しかし、Githubとレンタルサーバでは以下の挙動の違いがあるため、結局Node.jsのexpressでルーティングすることにしました。

Github

ファイルが指定されていない場合は、デフォルトでまずはindex.htmlを探し、index.htmlがない場合には、index.jsonを返します。しかし、root.jsonはデフォルトでは返りません。ただ、root.jsonはindex.jsonの中でパスを定義されているのでデフォルトで返らなくても問題なさそうです。

レンタルサーバ

レンタルサーバでは、index.jsonは自動で返りません。そのため、Node.jsのexpressでルーティングするのが良いと思います。というか、それしかないと思います。

結局、解決する方法は、Esriドキュメントにある通り、「rest/services」をURLに含めることでした。
そうすることで、Map Viewer Classicで保存が出来ました。さらに、ContentのNew itemから保存することも出来ました。その方法を以下、記載していきます。

環境

レンタルサーバ

OS: Rocky Linux 8
メモリ: 1GB
ストレージ: 25GB SSD
node version: v16.20.2 ※nvmで管理
npm version: 8.19.4

サーバーの準備

apps.jsを以下のとおり準備します。

apps.js
const config = require('config');
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
const winston = require('winston');
const DailyRotateFile = require('winston-daily-rotate-file');

// config constants
const morganFormat = config.get('morganFormat');
const htdocsPath = config.get('htdocsPath');
const port = config.get('port');
const logDirPath = config.get('logDirPath');

// logger configuration
const logger = winston.createLogger({
  transports: [
    new winston.transports.Console(),
    new DailyRotateFile({
      filename: `${logDirPath}/server-%DATE%.log`,
      datePattern: 'YYYY-MM-DD',
    }),
  ],
});

logger.stream = {
  write: message => {
    logger.info(message.trim());
  },
};

// app
const app = express();
var VTRouter = require('./routes/VT'); //tiling
var esriIFRouter = require('./routes/esriIF'); //esri interface (tilemap, etc..)
app.use(cors());
app.use(
  morgan(morganFormat, {
    stream: logger.stream,
  })
);
app.use(express.static(htdocsPath));
app.use('/rest/services/VT', VTRouter);
// app.use('/esriIF', esriIFRouter); //esri interface
app.use('/rest/services/esriIF', esriIFRouter); //esri interface

//for http
// app.listen(port, () => {
//   console.log(`Running at Port ${port} ...`);
// });

// for https
const fs = require('fs');
const spdy = require('spdy'); //for https
const privkeyPath = config.get('privkeyPath'); //for https
const fullchainPath = config.get('fullchainPath'); //for https
spdy
  .createServer(
    {
      key: fs.readFileSync(privkeyPath),
      cert: fs.readFileSync(fullchainPath),
    },
    app
  )
  .listen(port);

app.use('rest/services/esriIF', esriIFRouter);
としているのが、ポイントです。

コンフィグ設定は以下です。

config/default.hjson
{
 morganFormat: tiny
 htdocsPath: htdocs
 privkeyPath: ./key/privkey.pem 
 fullchainPath: ./key/cert.pem
 logDirPath: log
 port: 443
 mbtilesDir: mbtiles
 esriDir: esri
 esri-tilemap-min:{
  arcgis-readable: 0
 }
 esri-tilemap-max:{
  arcgis-readable: 8
 }
}

ポート番号は443にしました。Tilemapで使うために、ここで読み込むデータセット(arcgis-readable)とその最大ズームレベル、最小ズームレベルを指定します。
mbtilesDir: mbtiles
の記載も追記しています。

esri関係インターフェース

routes/esriIF.jsを準備しました。

JSONファイルの準備

次に、esri/arcgis-readableというフォルダを作って、その中にindex.jsonとstyle.jsonを準備します。

style.jsonのurl部分は以下の通りとしています。
"url": "https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer",

index.jsonのtiles部分は以下のとおりです。
"tiles": [
"https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tile/{z}/{x}/{y}.pbf"
],

レンタルサーバ

サーバに入り、その後cloneします。

git clone https://github.com/k96mz/20250123arcgis-readable.git

その他、以下を実行します。

・npm iでモジュールをインストール
・./key/privkey.pem と./key/cert.pemに該当ファイルを置く

sudo ~/.nvm/versions/node/v16.20.2/bin/node apps.js

とすると、以下のURLからindex.htmlファイルを見ることができます。
https://k96mz.net

確認

ベクトルタイル:
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tile/{z}/{x}/{y}.pbf

https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tile/1/1/1.pbf

スタイルファイル:
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/resources/styles
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/resources/styles/root.json
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/resources/styles/root.json?f=pjson

ベクトルタイルサーバ情報:
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/index.json
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer?f=json

tilemap:
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tilemap/3/0/0/32/32
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tilemap/4/0/0/32/32
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer/tilemap/6/32/64/32/32

ArcGIS Onlineでみる

Map Viewer Classicにおいて、以下のURLだと読み込み、及び保存が出来ました!
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer

index.jsonのtiles部分を、以下に変更して試したところ、問題なく読み込みと保存が出来ました。つまり、外部の静的サイトに置かれたタイルを使用したレイヤも保存できることが分かりました。
https://k96mz.net/tile/{z}/{x}/{y}.pbf

つまりは、ベクトルタイルの場所は、

VectorTileServer/tile/<level>/<row>/<column>.pbf

でなくても良いと思われます。

タイルURL例
https://k96mz.net/tile/1/1/1.pbf

以下が表示されたタイルURL例です。
スクリーンショット 2025-01-28 10.57.40.jpg

mbtilesも表示出来るか試してみる

index.jsonのtilesを以下のURLにして試してみました。
https://k96mz.net/rest/services/VT/zxy/VTtest/{z}/{x}/{y}.pbf

以下の通り、無事に読み込む、さらに保存することも出来ました。

スクリーンショット 2025-01-28 17.47.22.jpg

エラーが発生していた以下のURLでは、下図のように表示されていました。
https://k96mz.net/rest/arcgis-readable/VectorTileServer

スクリーンショット 2025-01-24 14.07.00.jpg

タイルへのリクエストが以下のようになっており、違和感を感じます。これが、レイヤを保存できなかった理由かもしれません。
Request URL:
https://geoportal.un.org/arcgis/sharing/proxy?https://k96mz.github.io/20250117tilemap/VectorTileServer/tile/3/4/4.pbf

ContentのNew itemから保存する

こちらの記事で見たように、ContentのNew itemから保存してみます。
VectorTileServerへのパスを以下にします。
https://k96mz.net/rest/services/esriIF/arcgis-readable/VectorTileServer

無事に保存出来ました。

スクリーンショット 2025-01-28 10.18.07.jpg

まとめ

Node.jsを利用してリクエストパスに応じて動的にレスポンスファイルを作成するコードを作成しました。そして、そのコードを用いてレンタルサーバでホストし、そのサイトをArcGIS Onlineに保存しました。
ArcGIS Onlineに保存することが出来ないエラーが発生し、解決に手間取りましたが、ドキュメントをきちんと読む事で対応できました。闇雲に色々と試すのではなく、何がエラー原因かを考えながら、ドキュメントを読むことが大切だと感じました。

Reference

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?