MugeSoの日記 このページをアンテナに追加 RSSフィード

2008-09-30

[][]携帯GPS位置情報取得方法まとめ

結構はまったので書いておきます。

docomo

<a href="[普通のURL]" lcs="lcs">なんたら</a>

au

<a href="device:gpsone?url=[urlエンコードした絶対URL]&amp;ver=1&amp;datum=0&amp;unit=0">なんたら</a>

SoftBank

<a href="location:auto?url=[普通のURL]">なんたら</a>

ソフトバンクURL指定が普通のURLなのにハマった。

2008-09-20

[][]2点間距離(1点からの距離)による検索方法3

一つ目にトラックバックが付いていたので補足

もう少し説明すると、半径 r の検索をするとして、UTM上で1辺 2r の外接矩形を求めますよね。

その矩形の四隅の点自体は、経緯度座標に戻しても、中心点から √2r の距離を持つ点として意味を持ちますが、いかんせん経緯度座標系に戻してしまった時点で、四隅の点を結ぶ辺自体が大圏コースじゃなくなってしまうので、駄目だと思います。

ここギコ!:UTM上での半径検索は、検索まで全部UTM上で行ってから経緯度に戻す

2点間距離(1点からの距離)による検索方法2でも言ったように、&&絞込みに限定するなら四隅の点によるジオメトリ(ポリゴン)のバウンディングボックス等距離円を内包すればいいはずです。*1

f:id:MugeSo:20080920213908j:image

これはあるゾーンでの第2象限*2における等距離円とUTMで得た外接矩形(赤)、経緯度座標での外接矩形(青)、expand_by_meterで得られるポリゴンバウンディングボックスの関係を示したものです。このように、青で示した外接矩形よりも大きくはなりますが、ポリゴンバウンディングボックスは等距離円を内包しています。

中央経線を跨ぐ場合にはバウンディングボックスの北側の辺が等距離円に食い込みますがこれは前のエントリの方法で回避できます。

私がなぜこのような方法に固執するのかというと、検索対象レコードが等距離円を持っていて条件として与えた点をその等距離園内に含むすべてのレコードを得たいからです。等距離円は中心を示すgeometry型列と半径を示すdouble型列を用いて表現しています。このとき、中心点の列で空間インデックスを張っても半径を得るために逐次検索となってしまうのです。

考えてみるとUTM上で外接矩形を用いたインデックスを張る手もありますが、国内で動かす場合6つのゾーンすべてについてインデックスを張らなければいけないのが気になります。検索対象が頻繁に移動することがあるため避けたいところなのです。

[][]2点間距離(1点からの距離)による検索方法2

今回は昨日書いたexpand_by_meterについてもう少し考察してみたいと思います。

昨日書いたexpand_by_meterは与えられた点を一度最適なUTM上に射影し、UTM上でのバウンディングボックスを生成して再射影して元の座標系でのジオメトリを得るというものでした。

ところが得られたジオメトリはUTM上での正方形の4頂点を頂点として持つ四角形(正方形とは限らない)になり、極を内包しない条件では等距離円がはみ出してしまいます。

しかし得られるジオメトリは&&演算での絞り込みに用いることに着目すると、UTM上での中央経線を含まない場合は十分に動作することが分かります。これは、得られたジオメトリは等距離円を内包しませんがそのバウンディングボックスは等距離円を内包していて、なおかつ&&演算がジオメトリのバウンディングボックス同士が重なっているかを調べるためです。

けれど、中央経線を含む場合はうまくいきません。これはUTMでの正方形の極側の辺上の最北点が中央経線との交点にあるためです。赤道を挟むと南北両辺が食い込みます。解決方法としてはUTM上で中央経線と正方形の交点を求め、元の座標系でこの点も含めたバウンディングボックスを得ればOKなはずです。

とここまで考察して、そもそもUTMバウンディングボックスだっていくらか(6/10000程度)食い込んでるってことに気が付きました。そしてもう一つ、中央経線上では十分狭い範囲では緯線はほぼ横軸?と平行です。食い込みもそれほどでもないかもです。

そもそも、真面目にやるなら等距離円の方程式を得てそのバウンディングボックスを得るのが正しいはずです。それができないのならどこかで妥協するしかありません。重要なのはどこで妥協するかってことです。 どこでしょう。

*1:このとき四点を結ぶ大圏コースを内包する必要はありません。

*2:原点の北西

2008-09-19

[][]2点間距離(1点からの距離)による検索方法

via: ここギコ!:PostGISで1点からの半径検索は、UTMなりに変換してから検索するのがベストプラクティス?, ここギコ!:PostGISのGeospatial化大作戦 その3(デタラメ編)

最近、GISにかかわり始めたばかりなので間違いかもしれませんが、上記ふたつを元にこんなこと考えてみました。

CREATE OR REPLACE FUNCTION expand_by_meter(geometry,double precision)
RETURNS geometry
AS '
    DECLARE
        utm_sid integer;
        geo geometry;
    BEGIN
        utm_sid = 32600 + ceil((ST_X($1)+180)/6)::int;
        geo = ST_Transform(ST_Expand(ST_Transform($1, utm_sid), $2), ST_SRID($1));
        RETURN geo;
    END
' IMMUTABLE LANGUAGE plpgsql;

処理の流れはこんな感じです。

  1. 与えられた点に最適なUTM(WGS84)を取得
  2. UTMに変換
  3. UTM上で円に外接する矩形を取得
  4. 得られた矩形をもとの座標系に変換

たぶんこの矩形の少なくとも2辺は円の内側を通ってしまいます。どうしましょう。