2014-01-18 7 views
9

400000行のMySQLデータベースに 'flags'というテーブルがあります。この表は、英国のさまざまな地位を表す地理空間的なポイントで構成されています。バウンディングボックス内のすべての地理空間点を選択

私が作成しているアプリケーションは、Googleマップを使用しています。マップには、地図上のフラグの可視性を切り替えるボタンがあります。バウンディングボックスを渡すと、バウンディングボックス内のすべてのフラグが返される(マップに表示されるようにする)APIを作成するのが私の仕事です。

渡されるパラメータは、北東緯度/経度、およびビューポートの現在位置の南西緯度/経度です。

これで、この座標セット(ビューポート)の内側にあるすべての地理空間ポイントを返すSQLクエリを実行する必要があります。

理想的には、検索する行が多数あるため、ソリューションを最適化する必要があります。ユーザーがフラグを表示する前に、アプリケーションは特定のレベルにズームする必要があります。

フラグテーブル:

  • ID

例行座標:

1 | [ジオメトリ - 25B] | Tenacy AB

座標フィールドは、AsText(座標)を使用してリテラルポイントに変換することもできます。しかし、XとY関数はこれを行います。私はあなたがXとYの関数を使用することができるポイントの緯度/経度を取得するために知っているPOINT

座標列は、データ・タイプです。 X(座標)

DBMS:MySQLの
DBMSバージョン:5.6.14

+0

は、 'flags'テーブルの定義を非常に参考にします。また、そのテーブルの6つのサンプル行を表示することもできます。また、英国は本来の子午線に跨っているので、経度の符号(+ - )が重要になります。 –

+0

@OllieJonesありがとうOllie、私はフラグテーブル構造で質問を編集しました – jskidd3

答えて

22

geometry列のPOINTデータのxとy項目はおそらく緯度と経度です。

MySQLでこのルックアップを効率的に行うには、いくつかのことが必要です。

  • MyISAMテーブル(またはMySQLバージョン5)。7以降のいずれかのInnoDBテーブルまたはMyISAM)あなたはGeomFromTextの
  • 利用を検索したい長方形のテキスト表現を作成するためにあなたのジオメトリ列
  • 空間インデックスALTER TABLE flags ADD SPATIAL INDEX (coordinates)
  • コード上
  • A NOT NULL資格およびSELECTステートメントのMBRContains/MBRWithin関数を使用します。

緯度/経度のボックスが、約Winchester Cathedral (51.0606, -1.3131)を中心とする1度の矩形であるとします。その点の周りにバウンディングボックスが必要です。このMySQLクエリは、その境界ボックスを斜めに横切っている行のLINESTRING(テキスト)を生成します。テキスト文字列の類似したソートを思い付くホスト言語で

LINESTRING(50.5606 -1.8131,51.5606 -0.8131) 

ます。また、使用できる文字列の処理:

SELECT 
     CONCAT('LINESTRING(', 
       latitude-0.5,' ',longitude-0.5, 
       ',', 
       latitude+0.5 ,' ',longitude +0.5, 
       ')') AS box 
    FROM (
     SELECT 51.0606 AS latitude, -1.3131 AS longitude 
    ) AS coord 

クエリはあなたにこれを取得します。必要なフォーマットはこれです。

SELECT whatever, whatever 
    FROM flags 
WHERE MBRContains(
     GeomFromText('LINESTRING(50.5606 -1.8131,51.5606 -0.8131)'), 
     flags.coordinates)  

これは、空間インデックスを活用し、その座標がその対角線のバウンディングボックス内にあるflagsのすべての行を見つけます:次のように

LINESTRING(lat1 long1, lat2 long2) 

次に、あなたの空間テーブルを検索するためにそれを使用することができます。

ここにいくつかのドキュメントがあります。

http://dev.mysql.com/doc/refman/5.6/en/functions-for-testing-spatial-relations-between-geometric-objects.html#function_mbrcontains

あなたflags表は千数百行より少ない含まれている場合は、緯度と経度の列(FLOATデータ型、インデックス付け)と(いない空間テーブル)が通常のテーブルを見つけることにも行い、開発とデバッグが容易です。

私はそのテクニックについてチュートリアルを書いています。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/

+1

十分にありがとうございます。素晴らしい答え、ありがとう!私は数日後にMySQLの地理空間の主題について非常に知識があるように思えるので、あなたの助けを必要とするかもしれません。私はあなたの電子メールをあなたのGoogle Plusで見ました。数日後に別のStack質問へのリンクがあるメールを送ってもらえますか?あなたの助けは非常に高く評価されました(あなたが推測していない場合に備えて)!もちろん – jskidd3

+0

。あなたのアプリで幸運。 –

+0

@OllieJonesは、MySQLがX/YをLong/Latとして、Lat/LongではなくSOで広く使用されているように見えます。点(x y)は実際には点(y x)である。 – kouton

0

あなたはquadkeyを使用することができ、例えば、ポイントの緯度は、このような検索することができます。ディメンションが減少し、空間検索が容易になります。私はPHPクラスhilbert-curve @ phpclasses.orgを書いています。また、Microsoft Bingマップのタイリングからクワッドキーについて読むこともできます。基本的にクワッドキーは、x、y、z座標でタイルを見つけるのに役立ちます。ソース:http://msdn.microsoft.com/en-us/library/bb259689.aspx

関連する問題