web-dev-qa-db-ja.com

mysqlで緯度と経度を使用して2点間の距離を見つける

こんにちは私は次の表を持っています

 --------------------------------------------
 |  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つのポイントから他のすべてのポイントまでの距離を見つけます。ここで、ある地点から別の地点までの距離を取得します。

ガイドラインは大歓迎です。

23
Enthusiast

あなたの質問は、距離を計算する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/

63
O. Jones

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.
6
Umesh Jee

距離の計算がどのように行われているかはわかりませんが、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
3
Rahul

次のMySQL関数は、2つの緯度/経度のペアを取り、2つのポイント間の距離を度単位で示します。 Haversine式を使用して距離を計算します。地球は完全な球体ではないため、極と赤道の近くに多少の誤差があります。

  • マイルに変換するには、3961を掛けます。
  • キロメートルに変換するには、6373を掛けます。
  • メートルに変換するには、6373000を掛けます。
  • フィートに変換するには、(3961 * 5280)20914080を掛けます。
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;
3
Sloan Thrasher

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 ;

また、サイト上の異なる言語で同じ機能を見つけることができます。

1
user2288580