不動産情報ライブラリAPIのベクトルタイルをMapLibreで表示してみる

https://qiita.com/4gou/items/bcdfe8c58c64bbc83221

↑の記事で不動産情報ライブラリのベクトルタイルをQGISで表示する方法を紹介しました。
今回は不動産情報ライブラリのベクトルタイルをMapLibreを使って表示してみます。

結論を先に書きますと、直接MapLibreのTileのURLに不動産情報ライブラリAPIのURLを指定してベクトルタイルを表示させることはできません。不動産情報ライブラリAPIにアクセスするためのサーバーサイドのプログラムかプロキシサービスなどが必要になります。

## 初めにやったこと　transformRequestでAPIキーをセットしてみる（NGな方法）
ローカルでさくっと見たかっただけなので、MapLibreのMapOptionsのtransformRequestを使って、不動産情報ライブラリAPIへのリクエスト時にAPIキーをセットしてみました。
もちろんこの方法は、外部にAPIキーが漏洩して第三者が利用可能な状態になるため、実施しない方が良いです。
あくまでローカルで自分だけが見られるような状態で取得結果を確認したかったので試しました。

タイルのソース情報として ```'https://www.reinfolib.mlit.go.jp/ex-api/external/XKT004?response_format=pbf&z={z}&x={x}&y={y}'``` を指定して、transformRequestの内部で ```headers: {'Ocp-Apim-Subscription-Key': 'YOUR-API-KEY'}``` をセットする感じです。

### transformRequestをセットして取得した結果
タイルは表示されませんでした。Chromeの開発者ツールで見てみると。CORSのエラーメッセージが出ていました。
![CORSエラーメッセージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325378/ae772c52-9a4a-6c73-7d59-0fc96c3df22c.png)

はい、おとなしくサーバーサイドからリクエストする必要がありそうです。

## サーバーサイドから不動産情報ライブラリにリクエストする
不動産情報ライブラリAPIにリクエストするプロキシ的なサーバーサイドプログラムを用意します。
リクエストの流れは以下のようになります。
地図アプリ　⇔　サーバーサイドアプリ　⇔　不動産情報ライブラリAPI

サーバーサイドのプログラムが地図アプリと別オリジンならレスポンスヘッダーに適切な[Access-Control-Allow-Origin](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)をセットします。Access-Control-Allow-Originの設定値はよく考えて決定してください。

サーバーサイドのプログラムは不動産情報ライブラリAPIへのプロキシの役割を持っているだけなので、プログラム言語は何でもよいです。x、y、z、administrativeAreaCodeなどのリクエストパラメータを受け取り、APIキーをヘッダーにセットして不動産情報ライブラリAPIに流すだけです。
サーバーサイドのプログラム例は割愛します。


## MapLibreの設定
用意したサーバーサイドプログラムのURLをtileに指定します。その他注意するのはsource-layerの設定くらいです。
``` js
import './style.css'
// MapLibreの読み込み
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

const map = new maplibregl.Map({
    container: 'map',
    style: {
        version: 8,
        sources: {
            osm: {
                type: 'raster',
                tiles: [
                    'https://tile.openstreetmap.jp/{z}/{x}/{y}.png',
                ],
                tileSize: 256,
                attribution:
                    '<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
            },
            elementarySchoolDistrict: {
                type: 'vector',
                tiles: [
                    // 用意したサーバーサイドのURLを指定。今回は小学校区ポリゴンで試してみた
                    'http://127.0.0.1:3300/elementary_school_district?response_format=pbf&z={z}&x={x}&y={y}'
                ],
                // ズームレベルは11（市）～15（詳細）で指定可能
                "minzoom": 11,
                "maxzoom": 15,
            },
        },
        layers: [
            // 背景地図レイヤー
            {
                id: 'osmLayer',
                type: 'raster',
                source: 'osm',
                minzoom: 0,
                maxzoom: 22,
            },
            // 小学校区 塗りつぶしレイヤー
            {
                id: 'elementarySchoolDistrictPolygonLayer',
                type: 'fill',
                source: 'elementarySchoolDistrict',
                // ベクトルタイルにはhitsレイヤーとmetaレイヤーがあるっぽい。hitsレイヤーは小学校区ポリゴン、metaレイヤーはタイルのメッシュポリゴン
                'source-layer': 'hits',
                paint: {
                    'fill-color': '#FD7E00',
                    'fill-opacity': 0.6,
                },
            },
            // 小学校区 ラインレイヤー
            {
                id: 'elementarySchoolDistrictLineLayer',
                type: 'line',
                source: 'elementarySchoolDistrict',
                'source-layer': 'hits',
                paint: {
                    'line-color': '#666',
                    'line-opacity': 0.6,
                },
            },
        ]
    },
    center: [139.7671, 35.6812],
    zoom: 11,
});
```
表示結果
![地図に不動産情報ライブラリのベクトルタイルを表示した例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325378/787543ea-cdcf-40e3-0d83-730e8614c952.png)

## ベクトルタイルのsource-layerについて
不動産情報ライブラリのベクトルタイルには以下の二つのレイヤーがあるようです。
- hits
- meta

hitsレイヤーは目的とするジオメトリ情報（今回試した例では小学校区ポリゴン）が入っていて、metaレイヤーはタイルのメッシュ情報のようでした。metaレイヤーだけを表示するケースはないと思いますので、hitsレイヤーのみを使うか、hitsレイヤーとmetaレイヤーを合わせて使うかのどちらかになるでしょう。

metaレイヤーも重ねて表示した例です。タイルっぽいメッシュポリゴンが表示されます。
分かりやすいようにline-widthを太めにしてあります。
![metaレイヤーも一緒に地図に不動産情報ライブラリのベクトルタイルを表示した例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325378/6481fe43-d4eb-a479-e8d5-c4811549d171.png)