GeoJSONをGeoParquetに変換する理由
GeoJSONは読み書きが簡単で、まさにそれこそがウェブ上で地図データを共有するための既定フォーマットとして普及した理由です。しかし、データセットが数千フィーチャーを超えると、その手軽さ自体がコストになります。GeoJSONはすべての座標をJSON構造内のプレーンテキストとして保存するため、リーダーは1つのプロパティを見るだけでもファイル全体を波括弧単位で解析しなければなりません。必要な列だけを読み取る方法はなく、ファイルを開いてすべてを走査しない限り、その範囲を知る方法もありません。
GeoParquetは、データエンジニアが大規模な表形式データセットにすでに使用している列指向のストレージを取り入れることで、この問題を解決します。各プロパティは独立した列になり、ジオメトリはWKB値のバイナリ列になり、ファイルにはジオメトリの種類と全体のバウンディングボックスをあらかじめ示す小さなメタデータブロックが含まれます。これにより、DuckDBやGeoPandasのようなツールは、クエリが実際に必要とする列だけを読み取り、対象領域と重ならないバウンディングボックスを持つファイルをスキップし、地名やステータスコードのような繰り返し値をParquet組み込みの圧縮機能で縮小できます。
このツールは、その最初の一歩の面倒をなくすために作られました。GDAL、Python環境、コマンドラインツールをインストールする代わりに、GeoJSONファイルをブラウザにドロップするだけで、数秒で動作するGeoParquetファイルが得られます。変換はWebAssemblyを使用してクライアント側で実行されるため、ファイルが10フィーチャーであっても10万フィーチャーであっても同じように動作し、データがどこかに送信されることもありません。
GeoParquet:歴史、構造、事実
GeoParquetは、Apache Parquetという列指向のファイル形式の上に構築されています。Apache Parquetは、TwitterとClouderaがHadoop上での大規模データ処理のために2013年にオープンソースプロジェクトとして公開したものです。Parquet自体は座標が何であるかを知りません。単に型付き列を効率的に保存し、列ごとの圧縮と、リーダーが不要なデータブロック全体をスキップできるメタデータを備えているだけです。
GeoParquet仕様は、この汎用フォーマットの上に地理空間に関するルールを追加します。これはCloud-Native Geospatial Forumのもとで活動するオープンなコミュニティによって開発され、最初の1.0.0リリースは2023年8月に公開されました。2024年にリリースされたバージョン1.1.0では、行ごとのバウンディングボックス列と"covering"フィールドへのオプション対応が追加され、これによりリーダーはすべてのジオメトリをデコードすることなく行をフィルタリングできるようになりました。
知っておくと役立ついくつかの事実です。GeoParquetは既定でジオメトリをWKBとして保存するため、WKBライブラリさえあれば、GeoParquet専用のツールがなくてもジオメトリ列を読み取れます。この仕様は、ファイルがPROJJSONを使って別の座標参照系を宣言しない限り、OGC:CRS84における経度・緯度の順序を前提としています。そして、GeoParquetはすでに実験的な用途を超えて広く採用されています。Amazon、Meta、Microsoft、TomTomが支援する共同地図プロジェクトであるOverture Mapsは、建物、場所、道路、行政境界を含む全世界のデータセットをGeoParquet形式で公開しており、Source Cooperativeは、クラウドストレージから直接クエリできる公開GeoParquetデータセットを数十件ホストしています。
要するに、GeoParquetは新しいジオメトリモデルではありません。すでに存在し、よく理解されているジオメトリエンコーディングを、データエンジニアリングの世界がすでに信頼している高速な列指向ファイル形式の中に置くための取り決めなのです。
ステップバイステップガイド

コンピュータから.geojsonファイルを選択するか、GeoJSONテキストを直接ボックスに貼り付けるか、「Try sample」をクリックしてドイツの都市データを含む小さなサンプルファイルを読み込みます。

GeoJSONが読み込まれたら、「Convert to GeoParquet」をクリックします。変換は完全にブラウザ内で行われ、通常のファイルであれば一瞬で完了します。

変換されたフィーチャー数、検出されたジオメトリの種類、バウンディングボックス、プロパティ列、結果のファイルサイズをまとめた概要が表示されます。

元のフィーチャーが地図上に描画されるため、何もダウンロードする前に正しいデータが変換されたことを確認できます。

「Download converted.parquet」をクリックすると、完成したGeoParquetファイルをコンピュータに保存できます。
実際の活用例6選
ファイル形式そのものを超えて、GeoParquetが実際にどのような場面で使われているかをご紹介します。
- 大規模なオープンデータセットの公開。 Overture Mapsのようなプロジェクトは、世界規模の建物や場所のデータセットをGeoParquet形式で公開しています。単一のファイルに数百万のフィーチャーを収めながら、地域ごとのクエリを高速に保てるためです。
- クラウドデータウェアハウスへの地理空間データの読み込み。 BigQuery、Snowflake、DuckDBはいずれもParquetをネイティブに読み込めます。先にGeoJSONをGeoParquetに変換しておくことで、別途インポート処理を行うことなく、ジオメトリ列がテーブルの他の部分と一緒に読み込まれます。
- 機械学習パイプラインへのデータ供給。 多数の小さなファイルを読み込む学習パイプラインは、Parquetの列指向レイアウトの恩恵を受けます。座標と1つのラベル列だけを必要とするモデルは、行ごとにGeoJSONオブジェクト全体を解析する代わりに、他のすべてのプロパティをスキップできます。
- 自治体・行政GISデータセットのアーカイブ化。 現在、都市境界、ゾーニング、地籍データをGeoJSONとして配布しているオープンデータポータルは、それと並行してGeoParquet版も提供することで、まったく同じデータをより小さく、より速くクエリできるファイルとしてアナリストに提供できます。
- 衛星画像・リモートセンシングのフットプリントのカタログ化。 衛星画像のシーンやタイルのフットプリントは、本質的に表形式のデータです。1行につき1つのジオメトリと、撮影日や雲量といったメタデータが対応しており、これはまさにParquetのような列指向フォーマットが得意とする構造です。
- ウェブマッピングパイプライン向けのデータ前処理。 ベクトルタイルや地図バックエンドを構築するデータエンジニアは、生のGeoJSONを先にGeoParquetとして準備することがよくあります。DuckDB spatialやApache Sedonaのような下流ツールは、JSONテキストを再解析するよりもはるかに高速に、数百万のフィーチャーをフィルタリング・変形できるためです。
技術的な質問と回答
この変換ツールの仕組みに関するよくある10の質問に、率直にお答えします。
1. GeoParquetとは、わかりやすく言うと何ですか?
GeoParquetは、地図データ(点、線、ポリゴン、それらに付随する情報)を通常のApache Parquetファイル内に保存する方法です。Parquetは高速な分析のために構築された列ベースのファイル形式です。GeoParquetは、ジオメトリ列がParquetファイル内に存在しながらGISソフトウェアで正しく読み取れるよう、小さなルールのセットを追加しているだけです。
2. ジオメトリはファイル内で実際どのように保存されていますか?
各ジオメトリはWKB(Well-Known Binaryの略)としてエンコードされます。WKBはバイト単位のレシピです。1バイトが数値がリトルエンディアンかビッグエンディアンかを示し、4バイトがジオメトリの種類(点、線、ポリゴンなど)を示し、その後に座標そのものが生の8バイト数値として続きます。このWKB値は、Parquetファイルの1つのバイナリ列に、フィーチャーごとに1行ずつ保存されます。
3. 1つのGeoParquetファイルに複数のジオメトリタイプを含めることはできますか?
はい。WKBはすべての値の中に自身の型コードを持っているため、1つのジオメトリ列に点、線、ポリゴンを混在させることができます。この変換ツールは、検出したすべてのジオメトリタイプをファイルメタデータ内の"geometry_types"リストに記録するため、リーダーはすべての行を走査しなくても、事前に何を想定すればよいかを把握できます。
4. "geo"メタデータキーとは何ですか、なぜ重要なのですか?
すべてのGeoParquetファイルは、"geo"という名前のスキーマレベルのキーの下に小さなJSONオブジェクトを持っています。これは主要なジオメトリ列を示し、エンコーディング(WKB)を宣言し、存在するジオメトリの種類を一覧化し、ファイルのバウンディングボックスを示します。このキーがなければ、Parquetファイルは単なるバイトのテーブルにすぎません。このキーがあれば、GeoParquetに対応したツールは、そのバイトを実際のジオメトリに戻す方法を正確に把握できます。
5. ファイルサイズと読み込み速度の点で、GeoParquetはGeoJSONとどう違いますか?
GeoJSONは座標をテキストとして保存するため、13.404954のような数値は9文字を占めます。GeoParquetは同じ数値を8バイトのバイナリdouble型として保存し、さらにParquetが列全体にわたって繰り返しパターンを圧縮します。実際のデータセットでは、これによりGeoJSONと比べて5倍から10倍小さいファイルになることが常です。また、Parquetは列指向であるため、1つのプロパティ列だけを必要とするクエリは、ジオメトリの読み込みを完全にスキップできます。
6. GeoParquetは既定でどの座標参照系を使用しますか?
ファイルが別途宣言していない限り、GeoParquetリーダーは座標が標準的なGeoJSONと同じ座標順序・データムであるOGC:CRS84における経度・緯度であると想定します。この変換ツールはGeoJSONを入力として受け取るため、この既定値に従っています。
7. ファイルはデータセット全体のバウンディングボックスを保存しますか?
はい。この変換ツールは、各フィーチャーを処理する間に、XとYの最小値・最大値からなる累積バウンディングボックスを計算し、それを"geo"メタデータ内に列のbboxとして書き込みます。リーダーは、ファイルを開くかどうかを判断する前に、この単一のbboxを確認できます。これは、多数のファイルを地域でフィルタリングする際に便利です。
8. このツールが生成する.parquetファイルは、どのソフトウェアで開けますか?
GeoParquet仕様に基づいて構築されたツールであれば読み取れます。具体的には、空間拡張機能付きのDuckDB、GeoPandas、Apache Sedona、QGIS(最近のバージョン)、そしてジオメトリを認識するリーダーを備えたほとんどのクラウドデータウェアハウスです。内部的には通常のApache Parquetであるため、空間非対応のParquetリーダーでもファイルを開き、ジオメトリをバイナリ列として確認できます。
9. 変換によって座標の精度が失われることはありますか?
いいえ。GeoJSONの座標はJSON数値であり、JavaScriptはすでに内部でIEEE-754倍精度浮動小数点数として表現しています。WKBは各座標をまったく同じIEEE-754のdouble型として保存するため、この変換は丸め処理ではなく、直接的なバイナリの再エンコードです。この往復変換は、開発中にバイト単位で検証されています。
10. GeoJSONファイルはサーバーにアップロードされますか?
いいえ。解析、WKBエンコーディング、Parquetの書き込みは、すべてWebAssemblyを使用してブラウザ内で実行されます。ファイルがお使いの端末から出ることはなく、変換処理のいかなる部分もサーバーに触れることはありません。
変換を支える数学
この変換には曖昧さや推定は一切ありません。すべてのステップはバイトと数値に対する固定的かつ可逆的な操作であり、これがバイト単位での完全な往復変換を可能にしています。実際にデータに何が起きているのかをご紹介します。
1. 座標はすでにIEEE-754のdouble型である
13.404954のようなGeoJSON座標は、JavaScriptのJSONパーサーによって64ビットのIEEE-754倍精度浮動小数点数として解析されます。これは符号ビット1桁、指数部11桁、仮数部52桁からなり、有効数字にしておよそ15〜17桁の精度が得られます。WKBは各座標を、まったく同じ8バイトのdouble型として、リトルエンディアンのバイト順で保存します。ここでは丸めやフォーマットの変更は一切行われず、変換はすでにメモリ上にある同じ64ビットを出力バッファにコピーするだけです。
2. WKBのバイト構造とサイズ
すべてのWKB値は、1バイトのエンディアンフラグと4バイトの符号なしジオメトリ型コードで始まるため、固定ヘッダーは常に5バイトです。そこから先のサイズはジオメトリの種類によって変わります。LineStringやPolygonの各リングで使用されるn個の座標ペアからなるリングの場合、4バイトで点数を記録し、その後の各ペアには16バイト(X用8バイト、Y用8バイト)が使われます。
ring_bytes(n) = 4 + 16n Point = 5 + 16 = 21 bytes LineString(n) = 5 + ring_bytes(n) Polygon(rings) = 5 + 4 + Σ ring_bytes(ring) for each ring MultiPoint(n) = 5 + 4 + 21n (each point repeats the 5-byte header) MultiLineString = 5 + 4 + Σ (5 + ring_bytes(line)) for each line MultiPolygon = 5 + 4 + Σ (5 + 4 + Σ ring_bytes(ring)) for each polygon, each ring
これは近似ではなく正確な値です。この変換ツールは、バッファを確保する前にジオメトリの正確なバイトサイズを計算し、DataViewを使ってヘッダーと各座標を書き込み、書き込みの途中でバッファのサイズを変更することは決してありません。そのため、単純な2点間の線分は、どのプラットフォームでも常に正確に5 + 4 + 32 = 41バイトになります。
3. バウンディングボックスは一度の線形処理で求められる
バウンディングボックス[minX, minY, maxX, maxY]は、すべての座標ペアをちょうど1回ずつ訪問し、累積の最小値と最大値を保持することで計算されます。これは、nをすべてのフィーチャーにわたる座標ペアの総数としたときのO(n)の削減処理です。並べ替えも2回目の処理も不要で、新しい座標はそれぞれ4つの累積値と比較するだけで済むため、bboxの計算コストはデータセットのサイズに対して線形に増加し、それより速くも遅くもなりません。
4. ファイルサイズが小さくなる理由
[13.404954, 52.520008]のようなGeoJSON座標ペアは、角括弧とカンマを含めるとテキストとして約20バイトを占めます。同じペアを2つのWKB double型として表すと、正確に16バイトになります。これ自体はささやかな節約です。より大きな効果は、Parquetの列レベルのエンコーディングから得られます。国名のように何千行にもわたって繰り返される文字列プロパティの列は、辞書エンコーディングによって極めて高い圧縮率が得られます。これは、Parquetが個々の異なる文字列を一度だけ保存し、あとは行ごとに短い整数の参照を持つだけで済むためです。数値列も、値が繰り返されたり、狭い範囲に収まったりする場合には、ラン・レングス・エンコーディングやビットパッキングによって同様に恩恵を受けます。こうした最適化は、すべての値を1行ごとにテキストとして書き直すGeoJSONのような行ベースのテキスト形式では利用できません。
まとめると、この変換パイプラインはすべての段階で決定的です。既知のIEEE-754のdouble型を解析し、既知のバイト構造に書き込み、累積の最小値・最大値を追跡し、その結果を汎用的な列指向コンプレッサーに渡します。この決定性こそが、この往復変換を無損失にしている理由であり、同じGeoJSONファイルを異なる2台のマシンで2回変換しても、バイト単位で同一のGeoParquet出力が得られる理由です。
変換はApache Arrowとparquet-wasmのWebAssemblyビルドを使用して、すべてブラウザ内で完結します。ファイルがサーバーにアップロードされることは一切ありません。 地図タイル © OpenStreetMap の貢献者、Protomapsで描画(ホスティング:KONAKTIVE)、予備としてCARTO。
