LoginSignup
2
3

More than 5 years have passed since last update.

RDBMS-GIS における小技

Posted at

はじめに

皆さん位置情報を取り扱ってますか?位置情報データをどのように蓄えてますか?
elasticsearch?ひとつの選択肢ではありますが、RDBMS(MySQLやPostgreSQL)でやるのもいいですよ、ということで、RDBMSで位置情報を取り扱うときのtipsをご紹介。サンプルのクエリは PostgreSQL w/PostGIS 向けになっております。

都道府県

都道府県ごとのポリゴンデータを持つテーブルを用意して、任意の都道府県情報を持たない位置情報(Point なり Polygon なり)を都道府県ごとに取り出すことができます。データの正規化をきちんとやっていけるのが大きなメリットですね。

以下の
- id と name カラムを持つ prefectures テーブル
- prefecture_id と boundary(Polygon) カラムを持つ prefecture_zones テーブル
- boundary(Polygon) カラムを持つ hoges テーブル

の3テーブルがあるとすると

SELECT hoges.*
FROM hoges
INNER JOIN prefecture_zones ON ST_Intersects(hoges.boundary, prefecture_zones.boundary)
INNER JOIN prefectures ON prefecture_zones.prefecture_id = prefectures.id
WHERE prefectures.name = '東京都';

というクエリで、東京都の範囲を含む hoge を抽出できます
(記法は PostGIS)

おまけ・都道府県のポリゴンデータの作り方

ポリゴンデータは国土交通省から頂いて、QGISで適当にリダクションして使用すると良いでしょう。市区町村レベルまではこれで行けます。
それより細かいデータは総務省統計局にあります。

特定ジオグラフィーから一定距離内にあるジオグラフィーを得る

tips記事なので「ジオグラフィーとは?」という説明は省略します

ST_DWithin を使います。距離を測るのはST_Distanceですが、制約条件(WHEREとか)に ST_Distance を使ってもインデックスを利用しないので、インデックスを使う ST_DWithin を利用するべきです。

2回やればドーナツ状の検索もできますね。
↓サンプル
- name と boundary(Polygon) カラムを持つ hoges テーブル

SELECT
  hoges.name as name,
  ST_Distance(hoges.boundary, ST_GeographyFromText('POINT(139.707345 35.658634)')) as distance

FROM
  hoges
WHERE
  not ST_DWithin(hoges.boundary, ST_GeographyFromText('POINT(139.707345 35.658634)'), 0)
AND
  ST_DWithin(hoges.boundary, ST_GeographyFromText('POINT(139.707345 35.658634)'), 1000)
GROUP BY name, ph.user_id, distance
ORDER BY distance asc;

指定座標を含んでいないが boundary が指定座標からの距離が 1000m 以内の hoge の name と 距離を得ます。

終わりに

位置情報は楽しいのでみんな気軽に取り扱っていきましょう

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3