こんにちは私は次の表を持っています
--------------------------------------------
| id | city | Latitude | Longitude |
--------------------------------------------
| 1 | 3 | 34.44444 | 84.3434 |
--------------------------------------------
| 2 | 4 | 42.4666667 | 1.4666667 |
--------------------------------------------
| 3 | 5 | 32.534167 | 66.078056 |
--------------------------------------------
| 4 | 6 | 36.948889 | 66.328611 |
--------------------------------------------
| 5 | 7 | 35.088056 | 69.046389 |
--------------------------------------------
| 6 | 8 | 36.083056 | 69.0525 |
--------------------------------------------
| 7 | 9 | 31.015833 | 61.860278 |
--------------------------------------------
次に、2点間の距離を取得します。ユーザーが都市3を持ち、ユーザーが都市7を持っているとします。私のシナリオでは、1人のユーザーが都市と緯度を持ち、経度が他のユーザーの都市からの距離を検索しています。たとえば、都市3を持つユーザーが検索しています。彼は、他の都市のユーザーの距離を7と言いたいと思っています。次のクエリを検索して見つけました。
SELECT `locations`.`city`, ( 3959 * acos ( cos ( radians(31.589167) ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians(64.363333) ) + sin ( radians(31.589167) ) * sin( radians( Latitude ) ) ) ) AS `distance` FROM `locations` HAVING (distance < 50)
私が知っているように、このクエリは1つのポイントから他のすべてのポイントまでの距離を見つけます。ここで、ある地点から別の地点までの距離を取得します。
ガイドラインは大歓迎です。
あなたの質問は、距離を計算する2つの都市のcity
値があると言っていると思います。
このクエリはジョブを実行し、km単位の距離を算出します。球面コサインの法則を使用します。
計算のために2つの座標ペアを取得できるように、テーブルをそれ自体に結合することに注意してください。
SELECT a.city AS from_city, b.city AS to_city,
111.111 *
DEGREES(ACOS(LEAST(COS(RADIANS(a.Latitude))
* COS(RADIANS(b.Latitude))
* COS(RADIANS(a.Longitude - b.Longitude))
+ SIN(RADIANS(a.Latitude))
* SIN(RADIANS(b.Latitude)), 1.0))) AS distance_in_km
FROM city AS a
JOIN city AS b ON a.id <> b.id
WHERE a.city = 3 AND b.city = 7
定数111.1111
は、赤道から極までの距離の1万分の1であるメートルの古いナポレオン定義に基づいた、緯度ごとのキロメートル数です。この定義は、ロケーションファインダーの作業に十分近いものです。
キロメートルではなく法定マイルが必要な場合は、69.0
代わりに。
http://sqlfiddle.com/#!2/abcc8/4/
近くのポイントを探しているなら、次のような節を使用したくなるかもしれません:
HAVING distance_in_km < 10.0 /* slow ! */
ORDER BY distance_in_km DESC
それは(私たちがボストンマサチューセッツ州マサチューセッツ州の近くで言うように)邪悪である。
その場合、境界ボックスの計算を使用する必要があります。その方法については、この記事をご覧ください。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
Heresは、2つの緯度と経度の間の距離を取得するために使用するMySQLクエリと関数であり、距離はKMで返されます。
Mysqlクエリ:-
SELECT (6371 * acos(
cos( radians(lat2) )
* cos( radians( lat1 ) )
* cos( radians( lng1 ) - radians(lng2) )
+ sin( radians(lat2) )
* sin( radians( lat1 ) )
) ) as distance from your_table
Mysql関数:-
DELIMITER $$
CREATE FUNCTION `getDistance`(`lat1` VARCHAR(200), `lng1` VARCHAR(200), `lat2` VARCHAR(200), `lng2` VARCHAR(200)) RETURNS varchar(10) CHARSET utf8
begin
declare distance varchar(10);
set distance = (select (6371 * acos(
cos( radians(lat2) )
* cos( radians( lat1 ) )
* cos( radians( lng1 ) - radians(lng2) )
+ sin( radians(lat2) )
* sin( radians( lat1 ) )
) ) as distance);
if(distance is null)
then
return '';
else
return distance;
end if;
end$$
DELIMITER ;
PHPコードで使用する方法
SELECT getDistance(lat1,lng1,$lat2,$lng2) as distance
FROM your_table.
距離の計算がどのように行われているかはわかりませんが、self join
テーブルを作成し、それに応じて計算を実行します。おそらくこのようなもの
select t1.id as userfrom,
t2.id as userto,
( 3959 * acos ( cos ( radians(31.589167) ) * cos( radians( t1.Latitude ) ) *
cos( radians( t1.Longitude ) - radians(64.363333) ) + sin ( radians(31.589167) ) *
sin( radians( t2.Latitude ) ) ) ) AS `distance`
from table1 t1
inner join table1 t2 on t2.city > t1.city
次のMySQL関数は、2つの緯度/経度のペアを取り、2つのポイント間の距離を度単位で示します。 Haversine式を使用して距離を計算します。地球は完全な球体ではないため、極と赤道の近くに多少の誤差があります。
DELIMITER $$
CREATE FUNCTION \`haversine\`(
lat1 FLOAT, lon1 FLOAT,
lat2 FLOAT, lon2 FLOAT
) RETURNS float
NO SQL
DETERMINISTIC
COMMENT 'Returns the distance in degrees on the Earth between two known points of latitude and longitude. To get miles, multiply by 3961, and km by 6373'
BEGIN
RETURN DEGREES(ACOS(
COS(RADIANS(lat1)) *
COS(RADIANS(lat2)) *
COS(RADIANS(lon2) - RADIANS(lon1)) +
SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))
));
END;
DELIMITER;
https://www.geodatasource.com/developers/javascript から変換した式を次に示します。
KMで距離を計算するすてきなクリーン関数です
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `FN_GET_DISTANCE`(
lat1 DOUBLE, lng1 DOUBLE, lat2 DOUBLE, lng2 DOUBLE
) RETURNS double
BEGIN
DECLARE radlat1 DOUBLE;
DECLARE radlat2 DOUBLE;
DECLARE theta DOUBLE;
DECLARE radtheta DOUBLE;
DECLARE dist DOUBLE;
SET radlat1 = PI() * lat1 / 180;
SET radlat2 = PI() * lat2 / 180;
SET theta = lng1 - lng2;
SET radtheta = PI() * theta / 180;
SET dist = sin(radlat1) * sin(radlat2) + cos(radlat1) * cos(radlat2) * cos(radtheta);
SET dist = acos(dist);
SET dist = dist * 180 / PI();
SET dist = dist * 60 * 1.1515;
SET dist = dist * 1.609344;
RETURN dist;
END$$
DELIMITER ;
また、サイト上の異なる言語で同じ機能を見つけることができます。