PostGIS ST_DWithin と 空間参照系の単位 七転び八起き 編

しばらくブリのエントリです。

宿題が残ってます。年内に片付ける!その一念です。

長崎県が対象なら当たり、それ以外ならおしい、です。EPSG:2443 は、平面直角座標系のI系です。日本全国を19に分けてますので、その地域にあわせて帰る必要があります。
http://vldb.gsi.go.jp/sokuchi/patchjgd/download/Help/jpc/jpc.htm
にテキストの説明と、各系の対象を色塗りしてくれている地図があります。
また、ジオグラフィ型 (ジオメトリ型でない) を使うと、座標系の変換を考えずに、経度緯度からメートル単位の距離が一気に出ます。

どもです。

EPSG:2443 は、平面直角座標系のI系です。日本全国を19に分けてます

(´・∀・`)ヘー そうなんですね。
正確に検索するには、不向きなんですね。
そもそも、緯度経度から最適なEPSGを選択するというロジックが思いつかんです。

また、ジオグラフィ型 (ジオメトリ型でない) を使うと、座標系の変換を考えずに、経度緯度からメートル単位の距離が一気に出ます。

  (  ゚д゚)
_(__つ/ ̄ ̄ ̄/_
  \/    /

  ( ゚д゚ ) ガタッ
  .r   ヾ
__|_| / ̄ ̄ ̄/_
  \/    / 

これに、します。

ジオグラフィ型 について検索してみました。
http://www.finds.jp/docs/pgisman/1.5.1/ch04.html#PostGIS_Geography

ジオグラフィ型は,「地理」座標(しばしば「測地」座標,"lat/lon", "lon/lat", 緯度経度, 経度緯度 などとも呼ばれます)上で表現された空間フィーチャーのネイティブサポートするためのものです.地理座標は角度の単位(度)で合わさられる球面座標です
〜 中略 〜
WGS84経度緯度(SRID:4326)のみサポートしているという制限があります. ジオグラフィと呼ばれる新しいデータ型を使用します. GEOS関数にこの新しい型をサポートする関数がありません. 回避策として,ジオメトリとジオグラフィの型変換を行うことができます.

んで、やってみる。

ちなみに、「ジオメトリとジオグラフィの型変換」があるとの記述ですが、これは、ソースが汚れるのでしない方向で行きます。勿論、リリース後ならこれにします。

ALTER TABLE テーブル名 ADD フィールド名 geography(POINT,4326);

すんなり出来た。

新しいジオグラフィカラムはgeometry_columnsに登録されてません.システムカタログを見るgeomgraphy_columnsという新しいビューに登録されるので,AddGeom... といった関数を使わずに,自動管理されます.

geometry_columnsビューを見ると、出来てる。

インデックスも作っておく

CREATE INDEX インデックス名 ON テーブル名 USING GIST (フィールド名);

オッケー!

早速、データを作成してみる(各自よろしく ノシ)。

UPDATE FROM テーブル名
set フィールド名 = ST_GeographyFromText('SRID=4326;POINT(経度 緯度)') );

データも出来たので、本題に行ってみます。

SELECT * FROM テーブル名 
WHERE 
	ST_DWithin(
		フィールド名,
		ST_GeographyFromText('SRID=4326;POINT(経度 緯度)'),
		1000
	)

単位は、メートルなので、一キロ圏内ってことです。
前回のエントリとほぼ同じ結果。
SQL周りは、すっきりしました。
なにより、EPSG云々から開放されるのが大きい!!

でも・・・

GEOGRAPHY型によって,経度緯度座標でデータを格納できるようになりましたが, GEOGRAPHYで定義されている関数が,GEOMETRYより少ないのと,実行にCPU時間がかかる,というところが犠牲になっています.

選択した型が,期待する領域から出ないことを条件とすべきです. 使用するデータは地球全体か,大陸か,州か,自治体か?

データが小さいエリア内におさまるなら,適切な投影を選択してGEOMETRYを使うのが,効率面でも機能面でも最も良い方法です.
データが地球全体か大陸なら,GEOGRAPHYで投影法の細かい問題を気にせずにシステムを構築できるでしょう.
投影法を理解していなくて,学習したくもなくて,かつ,GEOGRAPHYで使える関数が限られていることを受け入れるのなら,GEOGRAPHYを使った方が簡単です.単にデータを経度緯度でロードして,そこから進めて下さい.

ニャニャニャニーーーー!(*_*)
そんなに、重いの。・゚・(ノД`)・゚・。
最初はツンして、最後はデレるって、スゲェー上級者向け(何の!!)文章だ。
ん?いや、よく読むと、突き放しているような:(;゙゚'ω゚'):

まぁ、ケースバイケースというのか、トレードオフなのか、現場にあわせてってことですよね。