web-dev-qa-db-ja.com

空間ポイントタイプを使用してMySQLにLat Lng値を格納する

使用される技術:MySQL 5.1およびPHP 5.3

私が書いているサイトの新しいデータベースを設計しています。 LatとLngの値を保存する最良の方法を探しています。

過去にはDECIMALを使用しており、次の形式でPHP/MySQLのselectを使用しています。

_SQRT(POW(69.1 * (fld_lat - ( $lat )), 2) + POW(69.1 * (($lon) - fld_lon) * COS(fld_lat / 57.3 ), 2 )) AS distance
_

最寄りの一致する場所を見つけるため。

新しいテクノロジーの詳細を読み始めると、空間拡張機能を使用する必要があるかどうか疑問に思っています。 http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html

しかし、情報は非常に薄く、データの保存方法について質問がありました。 DECIMALを使用する代わりに、POINTをデータ型として使用しますか?

また、POINTとして保存すると、マップにプロットしたい場合や、緯度経度をDECIMALSとして再度保存する必要がある場合に、緯度経度の値を取得するのは簡単ですか?

ここでのほとんどの投稿は新しいDBを学びたくないと言っているので、私はPostGISを使用する必要があることを知っています!

フォローアップ

新しいPOINTタイプで遊んでいます。以下を使用してLat Lng値を追加できました。

_INSERT INTO spatialTable (placeName, geoPoint) VALUES( "London School of Economics", GeomFromText( 'POINT(51.514 -0.1167)' ));
_

次に、以下を使用して、DatからLat値とLng値を取得できます。

_SELECT X(geoPoint), Y(geoPoint) FROM spatialTable;
_

これはすべて良さそうですが、距離の計算は私が解決する必要があるビットです。どうやらMySQLには距離関数のプレースホルダーがありますが、しばらくはリリースされません。いくつかの投稿で、以下のようなことをする必要があることがわかりましたが、コードが少し間違っていると思います。

_SELECT
 placeName,
 ROUND(GLength(
  LineStringFromWKB(
   LineString(
    geoPoint, 
    GeomFromText('POINT(52.5177, -0.0968)')
  )
  )
))
AS distance
FROM spatialTable
ORDER BY distance ASC;
_

この例では、geoPointは上記のINSERTを使用してDBに入力されたPOINTです。

GeomFromText('POINT(52.5177, -0.0968)'は、距離を計算する緯度経度の値です。

さらにフォローアップ

どちらかといえば、私はSQLのROUND部分を考えずに入れただけです。これを取り出すと、次のようになります。

_SELECT
placeName,
(GLength(
LineStringFromWKB(
  LineString(
    geoPoint, 
    GeomFromText('POINT(51.5177 -0.0968)')
  )
 )
))
AS distance
FROM spatialTable
ORDER BY distance ASC
_

これは私に必要な正しい距離を与えるようです。

現在答える必要があるのは、今Spatialを使って自分の人生を困難にしているのか、それとも将来に備えて自分自身を守るのかについての考えだけだと思います...

37
bateman_ap

常に、簡単に入手できる最高レベルの抽象化を使用する必要があると思います。データが空間データである場合は、空間オブジェクトを使用します。

しかし、注意してください。 Mysqlは、最悪の地理空間データベースです。ポイントはOKですが、すべてのポリゴン関数は完全に壊れています。ポリゴンを境界の長方形に変更し、その上で答えを出します。

私を襲った最悪の例は、日本を表すポリゴンがあり、日本のどこにあるかを尋ねた場合、ウラジオストクがリストに追加されることです!

OracleとPostGISにはこの問題はありません。 MSSQLには対応しておらず、エンジンにJTSを使用しているJavaデータベースは対応していません。地理空間は良好です。MySQL地理空間は不良です。

ここをお読みください MySQL空間クエリを使用してX半径内のすべてのレコードを検索するにはどうすればよいですか 5.6.1で修正されました。

フーラー!

8
Julian

バックエンドに追加のコードを配置するのが嫌な場合は、Geohashを使用してください。

接頭辞がより広い領域を示すように、座標を文字列にエンコードします。文字列が長いほど、精度が高くなります。

そして、それは多くの言語のためのバインディングを持っています。

http://en.wikipedia.org/wiki/Geohashhttps://www.elastic.co/guide/en/elasticsearch/guide/current/geohashes.html

1
Vajk Hermecz

クエリで空間インデックスを使用できるようになるため、これは良いことです。たとえば、比較する行の数を制限するには、境界ボックスに制限します。

1
aredridel

Mysql GIS yagni:

GISの経験がない場合、空間拡張の学習は、実際には、新しいデータベースに加えて、少しの数学と多くの頭字語を学習することと同じです。マップ、投影法、srids、フォーマット...特定の緯度/経度を指定してポイント間の距離を計算するために、それらすべてを学習する必要があります。おそらくそうではありません。サードパーティのGISデータを統合するか、ポイントよりも複雑なものを操作することになりますか?座標系を使用しますか?

Yagniに戻って、可能な限り単純なことを行います。この場合、phpまたは単純なSQLでコードを実装します。障壁に到達し、空間が必要だと判断したら、GISシステム、座標系、プロジェクト、および慣習を読んでください。

それまでに、おそらくPostGISが必要になるでしょう。

1
ashwoods