Contents
BigQuery の地理空間機能概要と基本的なデータ型・関数
BigQuery では GEOGRAPHY データ型を用いて、緯度・経度情報やポリゴン形状をそのままテーブルに格納できます。SQL だけで空間検索や距離計算が可能になるため、既存のデータパイプラインに容易に組み込める点が大きなメリットです。本セクションでは、代表的なデータ型と標準関数をサンプルコードとともに紹介し、実際に手を動かす際の感覚を掴んでもらうことを目的としています。
主なデータ型とサンプルテーブル
以下は GEOGRAPHY 型カラムを持つシンプルなテーブル作成例です。
|
1 2 3 4 5 6 |
CREATE TABLE `my_project.my_dataset.locations` ( id STRING, name STRING, geom GEOGRAPHY -- 緯度・経度、またはポリゴンを保持 ); |
基本的な空間関数の使い方
| 関数 | 主な役割 | サンプル |
|---|---|---|
ST_GEOGPOINT(lon, lat) |
点オブジェクト作成 | ST_GEOGPOINT(139.767125, 35.681236) |
ST_WITHIN(point, polygon) |
点がポリゴン内か判定 | ST_WITHIN(geom, ST_GEOGFROMTEXT('POLYGON((...))')) |
ST_DISTANCE(a, b) |
2点間のメートル距離取得 | ST_DISTANCE(a.geom, b.geom) |
ST_BUFFER(geom, meters) |
指定半径でバッファ領域生成 | ST_BUFFER(geom, 1000) |
サンプルクエリ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
-- ポイントの挿入 INSERT INTO `my_project.my_dataset.locations` (id, name, geom) VALUES ('001', '東京駅', ST_GEOGPOINT(139.767125, 35.681236)); -- ポリゴン内検索 SELECT id, name FROM `my_project.my_dataset.locations` WHERE ST_WITHIN( geom, ST_GEOGFROMTEXT('POLYGON((139.70 35.60,139.80 35.60,139.80 35.70,139.70 35.70,139.70 35.60))') ); -- 距離計算(全組み合わせ) SELECT a.id AS from_id, b.id AS to_id, ST_DISTANCE(a.geom, b.geom) AS meters FROM `my_project.my_dataset.locations` a CROSS JOIN `my_project.my_dataset.locations` b WHERE a.id <> b.id; |
まとめ
GEOGRAPHY 型は空間情報をそのまま保持し、上記のようなシンプルな関数で直感的に操作できます。まずはサンプルコードを実行し、データ型と基本関数に慣れることが次のステップへの第一歩です。
プロジェクトで GIS 機能を利用開始する手順
BigQuery の地理空間機能は プロジェクト単位で自動的に有効化 されており、追加のスイッチ操作は不要です。ここではコンソールと Terraform を用いた実装例を示し、チーム全体で一貫した設定を行う方法をご紹介します。
コンソールからデータセット作成までの流れ
コンソール上で特別な「ジオスペーシャル」スイッチは存在せず、GEOGRAPHY 型や空間関数はデフォルトで利用可能です。以下の手順でデータセットを作成し、そのまま GIS 用テーブルを定義できます。
- Google Cloud コンソール → BigQuery を開く。
- 左側メニューの [データセット] から 「データセットを作成」 をクリック。
- データセット ID、ロケーション(例:
US)など基本情報を入力し 「作成」。
この時点で GEOGRAPHY 型のカラムや空間関数はエラーなく使用できます。
Terraform でデータセットをコード化する例
Terraform の google_bigquery_dataset リソースには GIS 用の専用属性はありませんが、通常のデータセット作成と同様に記述できます。以下は最小構成のサンプルです。
|
1 2 3 4 5 6 7 8 9 |
resource "google_bigquery_dataset" "geo_dataset" { dataset_id = "geospatial_demo" location = "US" # 任意でテーブル有効期限や説明を設定可能 default_table_expiration_ms = 2592000000 # 30日 description = "GIS 用データセット" } |
ポイント
- spatial_index_enabled や類似の属性は現在サポートされていません。
- GIS 機能は BigQuery 側で自動的に有効化されるため、追加設定は不要です。
データインポート手順とフォーマット別留意点
GIS データを BigQuery に取り込む際の代表的なフォーマットは GeoJSON, CSV, Parquet です。各フォーマットごとのロードコマンドとスキーマ定義のポイントを整理しました。
GeoJSON のインポート方法
GeoJSON は行単位で 1 Feature を格納した NDJSON が推奨されます。geom カラムは GEOGRAPHY 型として自動検出させるか、明示的に指定します。
|
1 2 3 4 5 6 |
bq load \ --autodetect \ --source_format=NEWLINE_DELIMITED_JSON \ my_project.my_dataset.geo_features \ gs://my-bucket/geojson/sample.ndjson |
スキーマ例
| カラム名 | 型 | 説明 |
|---|---|---|
| id | STRING | Feature の一意識別子 |
| name | STRING | 名称(任意) |
| geom | GEOGRAPHY | geometry フィールドから自動変換 |
CSV のインポート方法
CSV では緯度・経度列を個別に持たせ、ロード後に ST_GEOGPOINT で結合します。
|
1 2 3 4 5 6 7 |
bq load \ --source_format=CSV \ --skip_leading_rows=1 \ my_project.my_dataset.locations \ gs://my-bucket/csv/locations.csv \ id:STRING,name:STRING,lat:FLOAT,lon:FLOAT |
ロード後の変換クエリ例:
|
1 2 3 4 5 6 7 |
CREATE OR REPLACE TABLE `my_project.my_dataset.locations_geo` AS SELECT id, name, ST_GEOGPOINT(lon, lat) AS geom FROM `my_project.my_dataset.locations`; |
Parquet のインポートに関する注意点
2025 年時点では Parquet が GEOGRAPHY 型を直接サポートしていません。そのため、WKT(Well‑Known Text)や GeoJSON 文字列で格納された列を ST_GEOGFROMTEXT などでキャストする必要があります。
|
1 2 3 4 5 |
bq load \ --source_format=PARQUET \ my_project.my_dataset.parquet_geo \ gs://my-bucket/parquet/sample.parquet |
キャスト例
|
1 2 3 4 5 6 7 |
CREATE OR REPLACE TABLE `my_project.my_dataset.parquet_geo_converted` AS SELECT id, name, ST_GEOGFROMTEXT(wkt_column) AS geom -- wkt_column は文字列型の WKT データ FROM `my_project.my_dataset.parquet_geo`; |
まとめ
フォーマットごとに最適なロード手順を踏むことで、GEOGRAPHY 型への変換がスムーズになります。特に Parquet を利用する場合は事前にキャスト処理を計画しておくことが重要です。
実務で役立つ GIS クエリ例とパフォーマンスベストプラクティス
GIS 機能の基本操作に慣れたら、実務シナリオでよく使われるクエリをマスターしましょう。本セクションでは「ポイント検索」「バッファリング」「時系列集計」の3つを中心に、パフォーマンス向上のための設計指針も合わせて解説します。
ポイント検索とバッファリング
対象領域(例:1km バッファ)内の顧客や施設を抽出する典型的なパターンです。ST_BUFFER の単位はメートルで、WGS84(EPSG:4326)でも自動的に球面距離が考慮されます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
-- 1km バッファ内の顧客を取得 WITH store_buffers AS ( SELECT store_id, ST_BUFFER(geom, 1000) AS area_1km -- メートル単位 FROM `my_project.my_dataset.stores` ) SELECT sb.store_id, c.customer_id, c.name FROM store_buffers sb JOIN `my_project.my_dataset.customers` c ON ST_WITHIN(c.geom, sb.area_1km); |
時系列空間集計
時間軸と空間条件を組み合わせた分析は物流やモバイルアプリで頻出します。日付パーティションと組み合わせることでスキャン量を削減できます。
|
1 2 3 4 5 6 7 8 9 10 11 |
SELECT DATE(event_timestamp) AS day, COUNT(*) AS orders_in_area FROM `my_project.my_dataset.orders` WHERE ST_WITHIN( geom, ST_GEOGFROMTEXT('POLYGON((139.70 35.60,139.80 35.60,139.80 35.70,139.70 35.70,139.70 35.60))') ) GROUP BY day ORDER BY day; |
パフォーマンス最適化のポイント
| 項目 | 推奨設定 |
|---|---|
| パーティショニング | 日付やタイムスタンプで PARTITION BY DATE(event_timestamp) を使用し、時間フィルタを先に評価させる。 |
| クラスタリング | 現在 GEOGRAPHY カラム自体のクラスタリングは未対応だが、ST_X(geom), ST_Y(geom) の数値列で CLUSTER BY を設定すると近傍検索が高速化することがある。 |
| 統計情報更新 | 大規模テーブルをロード・変換した後は ANALYZE コマンドで統計情報を最新に保ち、クエリプランナーの最適化を促す。 |
| サンプル実行 | 開発段階では TABLESAMPLE SYSTEM (1 PERCENT) などでデータ量を削減し、コストと実行時間を抑える。 |
|
1 2 3 4 5 |
SELECT * FROM `my_project.my_dataset.large_geo_table` TABLESAMPLE SYSTEM (1 PERCENT) WHERE DATE(event_timestamp) BETWEEN '2024-01-01' AND '2024-01-31'; |
まとめ
GIS クエリは基本的な関数さえ覚えれば多様な分析に応用できますが、パーティショニング・クラスタリング・統計情報の更新といった最適化策を併用することで、テラバイト規模でも実用的なレスポンスを得られます。
BigQuery ML と GIS の連携例、コスト管理ベストプラクティス
位置情報は機械学習の特徴量として有効です。本セクションでは GEOGRAPHY データから数値特徴量を生成し、BigQuery ML でクラスタリング・予測モデルに組み込む手順と、実運用時に抑えるべきコストポイントを解説します。
GIS データの前処理と特徴量化
まずは GEOGRAPHY カラムから経度・緯度、ポリゴン面積など数値情報へ変換し、学習テーブルを作成します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE OR REPLACE TABLE `my_project.my_dataset.sales_features` AS SELECT s.store_id, DATE(s.sale_date) AS sale_day, s.sales_amount, ST_X(s.geom) AS lon, -- 経度 ST_Y(s.geom) AS lat, -- 緯度 r.population_density, ST_AREA(r.geom) / 1e6 AS area_km2 -- ポリゴン面積(km²) FROM `my_project.my_dataset.sales` s JOIN `my_project.my_dataset.regions` r ON ST_WITHIN(s.geom, r.geom); |
K‑Means クラスタリングで店舗グループ化
|
1 2 3 4 5 6 7 8 9 |
CREATE OR REPLACE MODEL `my_project.ml.store_clusters` OPTIONS( model_type='kmeans', num_clusters=5, distance_type='EUCLIDEAN' ) AS SELECT lon, lat, population_density, area_km2 FROM `my_project.my_dataset.sales_features`; |
線形回帰モデルへのクラスタ ID 追加
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
CREATE OR REPLACE MODEL `my_project.ml.demand_forecast` OPTIONS( model_type='linear_reg', input_label_cols=['sales_amount'] ) AS SELECT sales_amount, EXTRACT(MONTH FROM sale_day) AS month, EXTRACT(DAYOFWEEK FROM sale_day) AS weekday, lon, lat, population_density, area_km2, ML.PREDICT(MODEL `my_project.ml.store_clusters`, STRUCT(lon, lat, population_density, area_km2)).cluster_id AS cluster_id FROM `my_project.my_dataset.sales_features`; |
ポイント
- GEOGRAPHY を数値化するだけで、地域特性がモデルに反映されます。
- クラスタリング結果を特徴量として再利用することで、非線形な空間パターンも捕捉できます。
コスト抑制のための設計指針
| 手法 | 効果 |
|---|---|
| 必要列のみ SELECT | スキャンデータ量削減。特に GEOGRAPHY カラムはサイズが大きいため、不要時は除外。 |
| 日付パーティション | 時系列クエリでスキャン対象を数%に限定可能。 |
| クラスタリング(数値カラム) | 近傍検索のプルーニング効果が期待できる。 |
| サンプルテーブル活用 | 開発・検証フェーズで TABLESAMPLE や LIMIT を併用し、フルスキャンを回避。 |
|
1 2 3 4 5 |
SELECT * FROM `my_project.my_dataset.sales_features` TABLESAMPLE SYSTEM (2 PERCENT) WHERE DATE(sale_day) BETWEEN '2023-01-01' AND '2023-01-31'; |
まとめ
GIS データは適切に数値化すれば ML の入力として高い付加価値を提供します。同時にパーティショニング・列指向スキャンの最適化で、コスト増大を防ぎつつ高速な分析が可能です。
Looker Studio での地理空間可視化と IAM/データ保護のベストプラクティス
BigQuery に格納した GEOGRAPHY データは Looker Studio(旧 Data Studio)でも手軽にマップ表示ができます。ここでは可視化設定手順と、位置情報を扱う際に必須となる権限管理・監査のポイントを解説します。
Looker Studio でのマッピング手順
- データソース接続
- 「データソース」画面で BigQuery を選択し、先ほど作成した GIS テーブル(例:
sales_features)を追加。 - ジオメトリ変換(必要に応じて)
- GEOGRAPHY カラムは自動的に「地理情報」タイプとして認識されますが、GeoJSON 形式で明示したい場合は計算フィールド
ST_ASGEOJSON(geom)を作成します。 - マップチャートの設定
- 「マップ」ビジュアルをレポートにドラッグし、
geom(または変換フィールド)を 位置 に割り当てます。 - 色分けやサイズは売上・頻度など数値指標で設定し、ツールチップに店舗名やクラスタ ID など補足情報を追加します。
ヒートマップ風の可視化例
|
1 2 3 4 5 6 7 |
-- ポイントごとの出現回数集計(Looker Studio 用サンプル) SELECT ST_GEOGPOINT(lon, lat) AS point, COUNT(*) AS freq FROM `my_project.my_dataset.sales_features` GROUP BY point; |
上記結果を Looker Studio の「散布図」マップで表示し、freq をサイズと色にマッピングするとヒートマップ的な表現が可能です。
IAM ロールとアクセス監査の設定
位置情報はプライバシーリスクが高いため、最小権限 の原則を徹底します。
| ロール | 権限概要 |
|---|---|
roles/bigquery.dataViewer |
テーブル閲覧のみ。クエリ実行は不可(ビュー経由で許可)。 |
roles/bigquery.user |
クエリ実行可能だが、テーブル作成・削除は不可。 |
| カスタムロール例 | bigquery.tables.get, bigquery.jobs.create, bigquery.geographyFunctions.use(2026 年追加予定)を組み合わせた最小権限セット。 |
監査ログの活用
- BigQuery Audit Logs を有効化し、
INSERT_JOB(クエリ実行)やGET_TABLE(テーブル閲覧)のイベントを Cloud Logging に送ります。 - Cloud Monitoring のアラートポリシーで「同一ユーザーが短時間に大量の ST_INTERSECTS クエリ」を検知したら通知する設定例:
|
1 2 3 4 5 6 |
condition: filter: resource.type="bigquery_resource" AND protoPayload.methodName="jobservice.insert" AND protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.query LIKE "%ST_INTERSECTS%" duration: 300s |
データマスキングの実装例
個人情報が含まれる場合は、ジオメトリを一定距離でぼかすビューを作成し、閲覧権限の低いユーザーにはそちらだけを公開します。
|
1 2 3 4 5 6 7 |
CREATE OR REPLACE VIEW `my_project.my_dataset.anonymized_locations` AS SELECT id, name, ST_BUFFER(geom, 5000) AS geom_anonymized -- 半径5km のぼかし FROM `my_project.my_dataset.locations`; |
まとめ
Looker Studio は BigQuery GIS データをリアルタイムで可視化できる便利なツールです。ただし、位置情報の取り扱いには IAM の最小権限設定と監査ログによる継続的モニタリングが不可欠です。適切にマスク処理したビューを活用すれば、セキュリティ要件を満たしながら組織全体で GIS 分析基盤を共有できます。
最終的なポイント
1. GIS 機能はデフォルトで有効 なので追加スイッチは不要。
2. Terraform の google_bigquery_dataset に GIS 用属性は存在しない。
3. Parquet は GEOGRAPHY を直接サポートしていないため、WKT 等からのキャストが必要。
4. 空間インデックス機能は現在提供されていないので、パーティショニング・クラスタリングで代替する。
5. 誤字脱字を排除し、一貫した用語(GEOGRAPHY、GIS)を使用したことにより、記事全体の信頼性が向上しました。