昨日は、FOSS4G Hokkaido 2025 が開催されていました。様々なトピックが飛び交う中、DuckDB に関する発表はなんと2つもありました。GIS 分野での DuckDB の盛り上がりが伺えますね。
そんな中、Geospatialの世界最前線を探る [2025年版] という発表での DuckDB の紹介のスライドに、なにやら気になるキーワードが…
SedonaDB、みなさんは聞いたことありますか? 「Apache Sedona なら聞いたことあるよ」という人もいるかもしれません。実は SedonaDB は、数日前に発表されたばかりの新しい OSS です。まだネット上に情報もあまりないので、ここで軽くまとめておこうと思います。
以下が Apache Sedona、Wherobots それぞれのブログ記事です。
Apache SedonaDB とは
SedonaDB についての説明をどこから始めればいいか難しいですが、まずは公式サイトの以下の説明からスタートしましょう。曰く、SedonaDB とは、シングルノードで動く、オープンソースのデータベースエンジンで、地理情報データを扱うことを念頭に設計されています。
SedonaDB is an open-source single-node analytical database engine with geospatial as a first-class citizen.
シングルノード、というのはどういう意味なのでしょうか? 実は、分散処理環境(Spark、Flink、Snowflake)で動く Apache Sedona というものがすでにあり、Apache SedonaDB はそのシングルノード版、つまり手元の PC で動くものとして開発されました。バカでかいデータの処理には引き続き Apache Sedona を、手頃なサイズのデータには手元で動く Apache SedonaDB を使ってください、ということのようです。
Apache SedonaDB を使ってみる
SedonaDB がどういう立ち位置のものなのか、というのがこの記事で語りたいことですが、いったんそれは置いておいて SedonaDB を使ってみましょう。
インストール
SedonaDB には、Python・R・CLI の3つのインターフェースがあるようです。Python は pip でインストールできます(conda も多分動くはず)。R は、公式のものはまだないですが、https://paleolimbot.r-universe.dev/sedonadbからインストールできます。ここではとりあえず Python で進めてみましょう。
pip install "apache-sedona[db]"
データの読み込み
現状、read_parquet()
で GeoParquet ファイルを読み込むのが唯一の方法のようです。以下の例では URL を指定していますが、ローカルのパスでも同様に動きました。試せてないですが、S3 の URI も使えるんだと思います。
ちなみに、read_parquet()
はデータをすべて読み込むのではなく、メタデータだけを読んでいます。実際のデータは、.show()
や .sql()
などが実行されてデータを読む必要が出てから、必要な分だけのデータが読まれるようです。こういうことができるのは Parquet の利点ですね。
>>> countries = sd.read_parquet(
... "https://raw.githubusercontent.com/geoarrow/geoarrow-data/v0.2.0/natural-earth/files/natural-earth_countries_geo.parquet"
... )
>>> countries.show()
┌─────────────────────────────┬───────────────┬───────────────────────────────────────────────────┐
│ name ┆ continent ┆ geometry │
│ utf8 ┆ utf8 ┆ geometry │
╞═════════════════════════════╪═══════════════╪═══════════════════════════════════════════════════╡
│ Fiji ┆ Oceania ┆ MULTIPOLYGON(((180 -16.067132663642447,180 -16.5… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ United Republic of Tanzania ┆ Africa ┆ POLYGON((33.90371119710453 -0.9500000000000001,3… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Western Sahara ┆ Africa ┆ POLYGON((-8.665589565454809 27.656425889592356,-… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Canada ┆ North America ┆ MULTIPOLYGON(((-122.84000000000003 49.0000000000… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ United States of America ┆ North America ┆ MULTIPOLYGON(((-122.84000000000003 49.0000000000… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Kazakhstan ┆ Asia ┆ POLYGON((87.35997033076265 49.21498078062912,86.… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Uzbekistan ┆ Asia ┆ POLYGON((55.96819135928291 41.30864166926936,55.… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Papua New Guinea ┆ Oceania ┆ MULTIPOLYGON(((141.00021040259185 -2.60015105551… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Indonesia ┆ Asia ┆ MULTIPOLYGON(((141.00021040259185 -2.60015105551… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Argentina ┆ South America ┆ MULTIPOLYGON(((-68.63401022758323 -52.6363704588… │
└─────────────────────────────┴───────────────┴───────────────────────────────────────────────────┘
データの集計
SedonaDB では、データに対する操作は基本的に SQL で行います。SQL を使わない API もそのうち用意されるのかな…?という気はしていますが、現状は生の SQL を書く必要があります。
ということで SQL を書いていくぞ!、といきたいところですが、上で読み込んだデータはまだ SQL からはアクセスできません。まずは to_view()
で view を作りましょう。とりあえず countries
という名前にしてみます。
>>> countries.to_view("countries")
これで SQL が使えるようになりました。sd.sql()
で適当な集計クエリを書いてみましょう。ST_*
のような GIS 系の関数もある程度は用意されています。関数一覧は公式ドキュメントで確認できます。たとえば、ST_Area()
を使って大陸ごとの面積を求めてみましょう。
>>> sd.sql("""
... SELECT continent,
... count(1) as count,
... sum(ST_Area(geometry)) as area
... FROM countries
... GROUP BY continent
... """).show()
┌─────────────────────────┬───────┬────────────────────┐
│ continent ┆ count ┆ area │
│ utf8 ┆ int64 ┆ float64 │
╞═════════════════════════╪═══════╪════════════════════╡
│ South America ┆ 13 ┆ 1547.9576927617466 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Seven seas (open ocean) ┆ 1 ┆ 1.4329281249999883 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ North America ┆ 18 ┆ 3752.2944755823783 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Antarctica ┆ 1 ┆ 6028.836194274538 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Oceania ┆ 7 ┆ 769.921437995673 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Europe ┆ 39 ┆ 3759.9140240305524 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Africa ┆ 51 ┆ 2562.302016746849 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Asia ┆ 47 ┆ 3074.332218475997 │
└─────────────────────────┴───────┴────────────────────┘
データの更新
INSERT したり UPDATE したりできるのかな?と思ったんですが、試したところエラーになりました。まあ、HTTPS 越しの GeoParquet ファイルには書き込みできないと思うので、直接書き込めないのはそういうものなんでしょう。INSERT したりしたい場合は、一度 SedonaDB のメモリ上に temporary table をつくって、それを操作して最後に書き出す、みたいな感じになるんだと思います。
>>> sd.sql("INSERT INTO countries VALUES ('', '', ST_Point(1, 1))").show()
Traceback (most recent call last):
File "" , line 1, in module>
File "/...snip.../.venv/lib/python3.12/site-packages/sedonadb/dataframe.py", line 380, in show
print(self._impl.show(self._ctx, limit, width, ascii), end="")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sedonadb._lib.SedonaError: Insert into not implemented for this table
データの書き出し
データの出力は、今のところ以下の3つの手段があるようです。
-
to_parquet()
: Parquet ファイルとして書き出し -
to_pandas()
: GeoDataFrame に変換 -
to_arrow_table()
: PyArrow のテーブルに変換
ということで、GeoParquet のデータを読み込んで、ちょっとした集計をして、他のライブラリに渡す、というくらいのことはもうすでにできそうです。
SedonaDB の注目ポイント
「まあでもこれくらいなら DuckDB にもできるし、DuckDB でいいんじゃない?」と思うかもしれません。たしかに、現状は DuckDB の方が勝っている部分が多いですね。それでも、SedonaDB は DuckDB spatial を超えていくポテンシャルがあると私は思っています。その理由は主に3つあります。
- Wherobots がかなり力を入れて開発している
- Apache エコシステムのパワー
- ラスターデータの処理
それぞれもう少し詳しく説明していきましょう。
Wherobots がかなり力を入れて開発している
DuckDB も GIS に力を入れていないわけではないですが、duckdb-spatial のコミット数を見るとわかるように、Maxxen さんが超人的な開発力で1人で開発している、というのが現状です。
Maxxen さんは duckdb-spatial だけを担当しているわけではなく、他にもいろいろ掛け持ちしながらなので限界があります(その中で ST_AsMvt()
とか魅力的な新機能をコンスタントに追加していってるのはまじですごい…)。
一方で、SedonaDB は Wherobots の複数の人が開発に関わっています。CTO がちゃんと見てるという力の入れようです。というのはたぶん、SedonaDB が普及すると Wherobots が提供しているマネージドの Sedona のユーザーが増えるからです(DuckDB と MotherDuck の関係みたいな感じ)。そうしたビジネス上のモチベーションがある以上、Wherobots の SedonaDB へのコミットメントは今後も続くでしょう。
SedonaDB と Sedona の関係
SedonaDB が普及すると Wherobots が提供しているマネージドの Sedona のユーザーが増える
と書きましたが、ここまでで SedonaDB と Sedona の関係についてちゃんと説明していないことに気付いたので、少し補足させてください。これは、上で挙げた Apache Sedona のブログ記事の「Why SedonaDB and SedonaSpark are Both Needed」という節に書かれています。
The SedonaDB spatial functions are compatible with the SedonaSpark functions, so SQL chunks that work for one engine will usually work for the other. Over time, we will ensure that both project APIs are fully interoperable.
SedonaDB でのデータ操作は(もっとこなれた Python API が用意されるかもしれませんが)基本的に SQL で行います。SedonaDB で動く SQL は Sedona でも動くので、開発者は、ローカルの SedonaDB で試しながら SQL を組み立てて、それを Sedona に持っていく、ということができます。Sedona のつらいところは環境構築が大変なのでローカルでテストしづらい、という点でしたが、SedonaDB が登場することでこれを解決できるのです。Wherobots はマネージドの Sedona を提供しているので、SedonaDB によって Sedona の開発者体験を上げることが売上につながるはずです。
Apache エコシステムのパワー
SedonaDB は、突然出てきたわけではなく、Apache の名を冠する様々な OSS の上に成り立っています。例えば Parquet というデータフォーマット自体も Apache のプロジェクトですし、効率的なデータ交換を実現する Apache Arrow もあります。
ここで特に知ってもらいたいのは、クエリエンジン部分を担っている Apache DataFusion です。
Rust を使わない方にはあまり知られていないかもしれませんが、DataFusion は Rust のデータ系エコシステムの中でもスター的な存在になっています。時系列データベースとして商用サービスも提供されている InfluxDB の内部で使われていたり、Apple 社でも Apache Spark のクエリ高速化(Apache Comet として Apache に寄贈)に利用されていたり、実績のあるプロダクトです。DuckDB も高速な処理速度で定評がありますが、DataFusion の力を借りた SedonaDB もそれに負けない性能があるはずです。
ラスターデータの処理
Sedona はベクターデータだけでなくラスターデータも扱うことができます(RS_
というプレフィックスのついたラスター用の関数が用意されている)。アーキテクチャ図をみると、SedonaDB もラスターを扱えるようになるみたいなので楽しみです。
まとめ
SedonaDB は、DuckDB spatial のように、ローカルで SQL を使って GIS データと戯れるためのツールです。まだまだ発展途上ですが、ポテンシャルのあるツールなので注目していきましょう!
Views: 0