Amazon Redshift が空間データのサポートを開始しました!

こんにちは!DA事業本部の大高です。

先日、Amazon Redshiftが空間データのサポートを開始しました!

Amazon Redshift announces support for spatial data

これにより、データ型にGEOMETRY型を利用することが可能となり、様々な空間関数も投げることが出来るようになりました。個人的にとても興味深い機能なので、早速試してみたいと思います。

また、AWSブログにも日本語訳がされた以下の記事もアップされていますので、こちらも参考にしながら進めていきたいと思います。

Amazon Redshift で空間的なデータを活用 | Amazon Web Services ブログ

前提条件

クラスタバージョンの1.0.11262以上で利用可能となっています。今回は、現時点での最新バージョンである1.0.11420で試してみます。また、クエリはマネージドコンソールのクエリエディタから実行しています。

データの投入

早速空間データの投入としてCOPY文でデータを投入しようと思ったのですが、以下の一文を見つけた為、一旦COPY文の検証はスキップしました。

従来の COPY を使って、行で区切られたテキストファイルから地理的データを取り込むこともできます。このファイルは、地理的データの表現のために標準的に使用される形式である、16 進数の Extended Well-Known Binary (EWKB) 形式での記述を想定しています。

EWKBとは?

Extended Well-Known Binary (EWKB)とは何か?ですが、具体的には以下のような値のことです。

01010000000000000000E060400000000000003E40

桁数は固定ではなく、GEOMETRYのデータに依存します。ちなみに上記はWKT形式のPOINT(135 30)をEWKB形式にしたものです。

空間データの形式として、テキスト表現のWell-Known Text(WKT)と、バイナリ表現のWell-Known Binary(WKB)が存在し、更にそれをPostGISの拡張フォーマットとして定義したものがExtended Well-Known Text(EWKT)と、Extended Well-Known Binary(EWKB)となります。

PostGIS拡張では、空間参照系識別子(SRID)とZM値の拡張がされています。詳細は以下のドキュメントが参考になります。

postgis/ZMSgeoms.txt at stable-3.0 · postgis/postgis

また、空間データまわりについては、以前にDevelopers.IO 2019 Tokyoで発表しましたので、よろしければご参照ください。

Developers.IO 2019 in TOKYO で「地理空間分析を行う上での必須知識+データ加工ノウハウ」を話しました #cmdevio

WKTでデータ投入だ!

ということで、簡単に記述できるものでは無いので、まずは手っ取り早くWKT形式の文字列として、INSERTでデータを投入しようと思います。データは弊社の秋葉原近辺のオフィスの座標を投入してみます。ここまでは、普通のデータです。

CREATE TABLE public.office(
    name VARCHAR(128)
  , wkt VARCHAR(512)
);

INSERT INTO public.office(name, wkt) VALUES ('秋葉原オフィス(本社)', 'POINT(35.697295 139.774764)');
INSERT INTO public.office(name, wkt) VALUES ('岩本町オフィス 1',       'POINT(35.694027 139.777609)');
INSERT INTO public.office(name, wkt) VALUES ('岩本町オフィス 2',       'POINT(35.693838 139.777139)');

これで、データが投入できました。

Spatial Functions(空間関数)を使ってみる

まずは、WKTデータをGEOMETRY型にしましょう。Spatial Functionsについては、以下にヘルプがあります。

Spatial Functions - Amazon Redshift

WKTからGEOMETRYに変換したいので、ST_GeomFromTextを利用します。また、SRIDWGS84である4326を指定しておきます。

CREATE TABLE public.office_spatial(
    name VARCHAR(128)
  , wkt VARCHAR(512)
  , geo GEOMETRY
);

INSERT INTO public.office_spatial(name, wkt, geo)
SELECT name, wkt, ST_GeomFromText(wkt, 4326) FROM public.office;

データをいれたら確認してみましょう。

SELECT name, wkt, geo FROM public.office_spatial;

よさそうに思えます…。(地図で見たい…!)

さて、GEOMETRY型にできたので、秋葉原オフィスから、各オフィスの直線距離を測ってみます。こういうケースではST_Distance関数が利用できますね。

ST_Distance - Amazon Redshift

ST_Distance(geom1, geom2)

引数に比較するGEOMETRYを指定すると、距離がDOUBLE PRECISION型で返ってきます。値の単位はGEOMETRYと同じとのことです。(この場合は…になるのでしょうか…?)

WITH akiba AS
(
  SELECT
      name
    , geo
  FROM
    public.office_spatial
  WHERE
    name = '秋葉原オフィス(本社)'
)
SELECT
    akiba.name AS from_name
  , office_spatial.name AS to_name
  , ST_Distance(akiba.geo, office_spatial.geo)
FROM
  public.office_spatial, akiba

返ってきた値は以下の通りです。正しそうですね。

まとめ

以上、Redshiftの空間データサポートを試してみた結果でした。

これまではAWS上でGEOMETRY型を扱いたい場合は、RDSのPostgreSQLにPostGIS拡張を自分でインストールするしかありませんでしたが、これからはすぐに空間データをRedshiftへ投入することができますね。また、GEOMETRYを地図として表示できるツールを利用することができれば、可視化も簡単になるはずです。

今後、もう少しそのあたりも含めて検証していければと思います。

どなたかのお役に立てば幸いです。それでは!