いつの間にかAmazon AuroraのPostgreSQL 10.5互換版がリリースされていました。
これでようやくAuroraでベクトルタイルを扱えるようになったということで、試してみました。
経緯
はじめに「Aurora PostgreSQLでベクトルタイルが扱えるのが10.5から」ということの経緯を振り返ってみたいと思います。
特に興味のない方は構築までスキップしてください。
PostGISでのベクトルタイル
PostGISでは2.4以降、 ST_AsMVT を使うことでベクトルタイルを扱えるようになりました。
ここで1つ注意点があり、MVTがProtoBufでエンコーディングされる仕様のため、PostGISインストール時にprotobuf-c supportを有効にする必要があります。
Amazon RDSのPostGISサポート
RDS for PostgreSQLではPostGISをサポートしていますが、
RDSはマネージドサービスですので、利用できる拡張機能はRDSでのリリースバージョンに紐付いています。
PostgreSQL 9.6まではPostGIS 2.3系がサポートされており、
PostGIS 2.4はPostgreSQL 10系から対応しました。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.96x
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.101x
RDSのベクトルタイルサポート
ですが、ここにはlibprotobuf-cが含まれていなかったため、PostgreSQL 10.4までは ST_AsMVT が使えない状態でした。
このことについてAWS Developer Forumsで要望が挙がり、開発チームで検討の結果サポートされたのが10.5からとなります。
https://forums.aws.amazon.com/thread.jspa?threadID=277371
https://aws.amazon.com/jp/about-aws/whats-new/2018/10/rds-postgresql-supports-minor-versions/
そしてこの度AuroraでもPostgreSQLの10.5互換がリリースされたため、MVTが使えるようになったことになります。
構築
クラスターの起動
RDSの起動画面から、Auroraエンジンを選択します。
画面下のエディションから「PostgreSQL対応」を選択します。
次の画面へ進み、DBエンジンのバージョンから「compatible with PostgreSQL 10.5)を選択します。
あとは環境に合わせてユーザ名・クラスター名等を設定していき、作成します。
拡張機能の読み込み
PostGISの拡張機能を有効にします。
手順は下記AWSのドキュメントにある通りです。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html#Appendix.PostgreSQL.CommonDBATasks.PostGIS
create extension postgis;
create extension fuzzystrmatch;
create extension postgis_tiger_geocoder;
create extension postgis_topology;
alter schema tiger owner to rds_superuser;
alter schema tiger_data owner to rds_superuser;
alter schema topology owner to rds_superuser;
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO rds_superuser;')
FROM (
SELECT nspname, relname
FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid)
WHERE nspname in ('tiger','topology') AND
relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
Tileと緯度経度を変換するFunctionの作成
Tileのxyzを緯度経度に変換するFunctionはOSMのWikiを参考に作成しておきます。
https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#PostgreSQL
これで ST_AsMVT を含むPostGISの一通りの機能が使用できるようになります。
使用例
実際の使用法等に関してはこちらを参考にさせていただきました、
http://waigani.hatenablog.jp/entry/2017/12/22/060000
SQLクエリによってベクトルタイルを生成することが出来るということは動的にfeatureのpropertyを構築出来るということですので、featureデータの格納されたマスターテーブルとユーザーデータの格納されたデータテーブルをJOINしてみます。
SELECT st_asmvt(v, 'geom', 4096, 'geom') mvt FROM (
SELECT l.keycode, l.hasData, st_asmvtgeom(l.geom, bbox, 4096, 0, true) AS geom
FROM
(SELECT j.keycode, j.geom, e.geom bbox, COUNT(user_data.id) > 0 AS hasData
FROM
tokachi j -- featureデータテーブル
INNER JOIN
(SELECT st_makeenvelope(tile2lon(58883, 16), tile2lat(24090, 16), tile2lon(58884, 16), tile2lat(24091, 16), 4326) as geom) e -- 指定のxyzで矩形を作成
ON
st_intersects(j.geom, e.geom) -- tileの矩形に含まれるfeatureデータをst_intersectsで抽出
LEFT JOIN
user_data -- ユーザーデータ
ON
j.keycode = records.keycode -- polygonのキーと関連するデータを連結
GROUP BY j.keycode, j.geom, bbox) l
) v;
このクエリを実行すると、各featureのpropertyに"ユーザデータが存在するかどうか"を表すhasDataが追加されます。
あとはleafletなどでの表示時にhasdataの有無で色を変えたりCallbackを仕掛けること等が出来ます。
var style = function(feature) {
var s = {};
if (feature.properties["hasdata"]) {
s.clickable = true;
s.fillColor = "#43C2FF";
} else {
s.fillColor = "#E200FF";
}
return s;
};
動的なデータを用いて高速なベクトルタイルを生成できるのは魅力的ですね。
マネージドでスケールさせやすいAuroraでベクトルタイルを提供することが出来るというのは夢が広がります。