MySQLには、緯度/経度の距離計算をサポートする地理空間拡張関数はありません。 MySQLの時点であります5.7
。
あなたは地球の表面に近接円を求めています。質問の中で、フラグ
の各行に緯度/経度の値があると述べています テーブル、およびユニバーサル横メルカトル図法
(UTM)いくつかの異なるUTMゾーン
の1つで予測された値 。 UK Ordnance Surveyマップを正しく覚えていれば、UTMはそれらのマップ上のアイテムを見つけるのに役立ちます。
同じゾーン内の2点間の距離を計算するのは簡単です UTMの場合:カルテシアン距離がうまくいきます。ただし、ポイントが異なるゾーンにある場合、その計算は機能しません。
したがって、質問に記載されているアプリケーションでは、 Great CircleDistance> 、これは、半正矢関数または別の適切な式を使用して計算されます。
MySQLは、地理空間拡張機能で拡張され、さまざまな平面形状(ポイント、ポリライン、ポリゴンなど)を幾何学的プリミティブとして表現する方法をサポートしています。 MySQL 5.6は、文書化されていない距離関数 st_distance(p1、p2)
を実装しています。 。ただし、この関数はデカルト距離を返します。したがって、まったく不適切 緯度と経度に基づく計算用。温帯の緯度では、緯度の線が極の近くで互いに近づくため、緯度の程度は経度の程度(東西)のほぼ2倍の表面距離(南北)になります。
したがって、循環近接式では、本物の緯度と経度を使用する必要があります。
アプリケーションでは、すべてのフラグ
を見つけることができます 特定のlatpoint、longpoint
から法定マイル10マイル以内のポイント 次のようなクエリで:
SELECT id, coordinates, name, r,
units * DEGREES(ACOS(LEAST(1.0, COS(RADIANS(latpoint))
* COS(RADIANS(latitude))
* COS(RADIANS(longpoint) - RADIANS(longitude))
+ SIN(RADIANS(latpoint))
* SIN(RADIANS(latitude))))) AS distance
FROM flags
JOIN (
SELECT 42.81 AS latpoint, -70.81 AS longpoint,
10.0 AS r, 69.0 AS units
) AS p ON (1=1)
WHERE MbrContains(GeomFromText (
CONCAT('LINESTRING(',
latpoint-(r/units),' ',
longpoint-(r /(units* COS(RADIANS(latpoint)))),
',',
latpoint+(r/units) ,' ',
longpoint+(r /(units * COS(RADIANS(latpoint)))),
')')), coordinates)
20 km以内の地点を検索する場合は、クエリのこの行を変更してください
20.0 AS r, 69.0 AS units
これに、例えば
20.0 AS r, 111.045 AS units
r
検索する半径です。 ユニットコード> 地球の表面の緯度ごとの距離単位(マイル、km、ハロン、必要なものは何でも)です。
このクエリは、 MbrContains
とともに境界緯度/経度を使用します 開始点から明らかに遠すぎるポイントを除外するには、大圏距離の式を使用して残りのポイントの距離を生成します。 これらすべての説明はここにあります
。テーブルがMyISAMアクセス方式を使用し、空間インデックスがある場合、 MbrContains
そのインデックスを利用して、検索を高速化します。
最後に、上記のクエリは長方形内のすべてのポイントを選択します。円内のポイントのみに絞り込み、近接順に並べ替えるには、次のようにクエリをまとめます。
SELECT id, coordinates, name
FROM (
/* the query above, paste it in here */
) AS d
WHERE d.distance <= d.r
ORDER BY d.distance ASC