Tìm vĩ độ / kinh độ gần nhất với truy vấn SQL


173

Tôi có vĩ độ và kinh độ và tôi muốn lấy bản ghi từ cơ sở dữ liệu, có vĩ độ và kinh độ gần nhất theo khoảng cách, nếu khoảng cách đó dài hơn chỉ định, thì đừng lấy lại.

Cấu trúc bảng:

id
latitude
longitude
place name
city
country
state
zip
sealevel

1
Đây là một bản sao của câu hỏi tìm kiếm gần .
Darius Bacon

1
Có một bộ slide của Alexander Rubin trên tìm kiếm Geo (lân cận) với MySQL (liên kết PDF)
Martijn Pieters

Câu trả lời:


209
SELECT latitude, longitude, SQRT(
    POW(69.1 * (latitude - [startlat]), 2) +
    POW(69.1 * ([startlng] - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;

trong đó [starlat][startlng] là vị trí bắt đầu đo khoảng cách.


49
Chỉ là một ghi chú về hiệu suất, tốt nhất không nên biến sqrt biến khoảng cách mà thay vào đó bình phương giá trị thử nghiệm '25' ... sau đó sqrt kết quả đã vượt qua nếu bạn cần hiển thị khoảng cách
sradforth

9
Điều gì sẽ là cùng một truy vấn cho khoảng cách được tính bằng mét? (hiện đang trong dặm, phải không?)
httpete

8
Số đo đó là 25?
Donffan Donal

16
Chỉ cần làm rõ ở đây là 69,1 chuyển đổi yếu tố hàng dặm để độ vĩ độ. 57.3 là khoảng 180 / pi, do đó, chuyển đổi từ độ sang radian, cho chức năng cosine. 25 là bán kính tìm kiếm trong dặm. Đây là công thức để sử dụng khi sử dụng độ thập phân và dặm luật.
John Vance

8
Ngoài ra, nó không tính đến độ cong của trái đất. Đây không phải là một vấn đề cho bán kính tìm kiếm ngắn. Mặt khác, câu trả lời của Evan và Igor hoàn chỉnh hơn.
John Vance

63

Giải pháp của Google:

Tạo bảng

Khi bạn tạo bảng MySQL, bạn muốn đặc biệt chú ý đến các thuộc tính lat và lng. Với khả năng thu phóng hiện tại của Google Maps, bạn chỉ cần 6 chữ số chính xác sau số thập phân. Để giữ không gian lưu trữ cần thiết cho bảng của bạn ở mức tối thiểu, bạn có thể chỉ định rằng các thuộc tính lat và lng có kích thước nổi (10,6). Điều đó sẽ cho phép các trường lưu trữ 6 chữ số sau số thập phân, cộng với tối đa 4 chữ số trước số thập phân, ví dụ -123,456789 độ. Bảng của bạn cũng phải có một thuộc tính id để dùng làm khóa chính.

CREATE TABLE `markers` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  `name` VARCHAR( 60 ) NOT NULL ,
  `address` VARCHAR( 80 ) NOT NULL ,
  `lat` FLOAT( 10, 6 ) NOT NULL ,
  `lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;

Dân cư bảng

Sau khi tạo bảng, đã đến lúc điền dữ liệu vào bảng. Dữ liệu mẫu được cung cấp dưới đây là cho khoảng 180 pizzarias rải rác trên khắp Hoa Kỳ. Trong phpMyAdmin, bạn có thể sử dụng tab NHẬP để nhập các định dạng tệp khác nhau, bao gồm CSV (giá trị được phân tách bằng dấu phẩy). Cả Microsoft Excel và Google Bảng tính đều xuất sang định dạng CSV, do đó bạn có thể dễ dàng chuyển dữ liệu từ bảng tính sang bảng MySQL thông qua xuất / nhập tệp CSV.

INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Frankie Johnnie & Luigo Too','939 W El Camino Real, Mountain View, CA','37.386339','-122.085823');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Amici\'s East Coast Pizzeria','790 Castro St, Mountain View, CA','37.38714','-122.083235');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Kapp\'s Pizza Bar & Grill','191 Castro St, Mountain View, CA','37.393885','-122.078916');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Round Table Pizza: Mountain View','570 N Shoreline Blvd, Mountain View, CA','37.402653','-122.079354');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Tony & Alba\'s Pizza & Pasta','619 Escuela Ave, Mountain View, CA','37.394011','-122.095528');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Oregano\'s Wood-Fired Pizza','4546 El Camino Real, Los Altos, CA','37.401724','-122.114646');

Tìm vị trí với MySQL

Để tìm các vị trí trong bảng đánh dấu của bạn nằm trong khoảng cách bán kính nhất định của một vĩ độ / kinh độ nhất định, bạn có thể sử dụng câu lệnh CHỌN dựa trên công thức Haversine. Công thức Haversine thường được sử dụng để tính khoảng cách vòng tròn lớn giữa hai cặp tọa độ trên một mặt cầu. Một lời giải thích sâu về toán học được đưa ra bởi Wikipedia và một cuộc thảo luận tốt về công thức vì nó liên quan đến lập trình trên trang web của Movable Type.

Dưới đây là các câu lệnh SQL mà sẽ tìm ra 20 địa điểm gần nhất mà là trong vòng bán kính 25 dặm về phía 37, -122 phối hợp. Nó tính toán khoảng cách dựa trên vĩ độ / kinh độ của hàng đó và vĩ độ / kinh độ đích, sau đó chỉ yêu cầu các hàng có giá trị khoảng cách nhỏ hơn 25, sắp xếp toàn bộ truy vấn theo khoảng cách và giới hạn ở 20 kết quả. Để tìm kiếm theo km thay vì dặm, thay thế 3959 với 6371.

SELECT 
id, 
(
   3959 *
   acos(cos(radians(37)) * 
   cos(radians(lat)) * 
   cos(radians(lng) - 
   radians(-122)) + 
   sin(radians(37)) * 
   sin(radians(lat )))
) AS distance 
FROM markers 
HAVING distance < 28 
ORDER BY distance LIMIT 0, 20;

Cái này là để tìm các vĩ độ và kinh độ trong một khoảng cách ít hơn 28 dặm.

Một số khác là để tìm thấy chúng trong một khoảng cách từ 28 đến 29 dặm:

SELECT 
id, 
(
   3959 *
   acos(cos(radians(37)) * 
   cos(radians(lat)) * 
   cos(radians(lng) - 
   radians(-122)) + 
   sin(radians(37)) * 
   sin(radians(lat )))
) AS distance 
FROM markers 
HAVING distance < 29 and distance > 28 
ORDER BY distance LIMIT 0, 20;

https://developers.google.com/maps/articles/phpsqlsearch_v3#creating-the-map


1
Nó phải HAVING distance < 25như chúng ta truy vấn địa điểm trong vòng bán kính 25 dặm?
Vitalii Elenhaupt

nó phải> 25, sau đó nó sẽ tìm kiếm tất cả các hồ sơ
vidur trừngj

Bạn có chắc chắn @vidurastaj khoảng> 25?
Amranur Rahman

Tôi cố gắng truy vấn sql sử dụng: khoảng cách <25 nhưng không tìm thấy kết quả .. như khoảng cách đánh dấu mẫu tất cả đều trên 25 ...
IbrahimShendy

37, -122 tọa độ, vĩ độ và kinh độ này cho vị trí mà chúng ta cần tìm khoảng cách?
Prasobh.Kollattu

28

Đây là giải pháp đầy đủ của tôi được thực hiện trong PHP.

Giải pháp này sử dụng công thức Haversine như được trình bày trong http://www.scribed.com/doc/2569355/Geo-Distance-Search-with-MyQuery .

Cần lưu ý rằng công thức Haversine gặp phải điểm yếu xung quanh các cực. Câu trả lời này cho thấy cách triển khai công thức vincenty Great Circle Khoảng cách để giải quyết vấn đề này, tuy nhiên tôi đã chọn chỉ sử dụng Haversine vì nó đủ tốt cho mục đích của tôi.

Tôi đang lưu trữ vĩ độ là DECIMAL (10,8) và kinh độ là DECIMAL (11,8). Hy vọng điều này sẽ giúp!

showClosest.php

<?PHP
/**
 * Use the Haversine Formula to display the 100 closest matches to $origLat, $origLon
 * Only search the MySQL table $tableName for matches within a 10 mile ($dist) radius.
 */
include("./assets/db/db.php"); // Include database connection function
$db = new database(); // Initiate a new MySQL connection
$tableName = "db.table";
$origLat = 42.1365;
$origLon = -71.7559;
$dist = 10; // This is the maximum distance (in miles) away from $origLat, $origLon in which to search
$query = "SELECT name, latitude, longitude, 3956 * 2 * 
          ASIN(SQRT( POWER(SIN(($origLat - latitude)*pi()/180/2),2)
          +COS($origLat*pi()/180 )*COS(latitude*pi()/180)
          *POWER(SIN(($origLon-longitude)*pi()/180/2),2))) 
          as distance FROM $tableName WHERE 
          longitude between ($origLon-$dist/cos(radians($origLat))*69) 
          and ($origLon+$dist/cos(radians($origLat))*69) 
          and latitude between ($origLat-($dist/69)) 
          and ($origLat+($dist/69)) 
          having distance < $dist ORDER BY distance limit 100"; 
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_assoc($result)) {
    echo $row['name']." > ".$row['distance']."<BR>";
}
mysql_close($db);
?>

./assets/db/db.php

<?PHP
/**
 * Class to initiate a new MySQL connection based on $dbInfo settings found in dbSettings.php
 *
 * @example $db = new database(); // Initiate a new database connection
 * @example mysql_close($db); // close the connection
 */
class database{
    protected $databaseLink;
    function __construct(){
        include "dbSettings.php";
        $this->database = $dbInfo['host'];
        $this->mysql_user = $dbInfo['user'];
        $this->mysql_pass = $dbInfo['pass'];
        $this->openConnection();
        return $this->get_link();
    }
    function openConnection(){
    $this->databaseLink = mysql_connect($this->database, $this->mysql_user, $this->mysql_pass);
    }

    function get_link(){
    return $this->databaseLink;
    }
}
?>

./assets/db/dbSinstall.php

<?php
$dbInfo = array(
    'host'      => "localhost",
    'user'      => "root",
    'pass'      => "password"
);
?>

Có thể tăng hiệu suất bằng cách sử dụng quy trình lưu trữ MySQL như được đề xuất bởi bài viết "Geo-Khoảng cách-Tìm kiếm-với-MySQL" được đăng ở trên.

Tôi có cơ sở dữ liệu ~ 17.000 địa điểm và thời gian thực hiện truy vấn là 0,054 giây.


Làm thế nào tôi có thể có được khoảng cách tính bằng Km hoặc Mét? Trân trọng!
hóa trị

2
dặm * 1.609344 = km
Sinan Dizdarević 30/03/2015

2
CẢNH BÁO. Giải pháp Excelent, nhưng nó có một lỗi. Tất cả absnên được loại bỏ. Không cần phải lấy giá trị abs khi chuyển đổi từ độ sang radian, và, ngay cả khi bạn đã làm, bạn đang làm điều đó chỉ là một trong những vĩ độ. Vui lòng chỉnh sửa nó để sửa lỗi.
Chango

1
Và đối với những ai muốn này theo mét: Chuyển đổi 3956 dặm sang km: bán kính của Trái Đất; Chuyển đổi 69 dặm sang km: chiều dài aproxímate của 1 vĩ độ ở km; Và nhập khoảng cách bằng km.
Chango

1
Và thay thế 69bằng 111,044736(quên rằng trong nhận xét trên)
rkeet

24

Chỉ trong trường hợp bạn lười biếng như tôi, đây là một giải pháp được hợp nhất từ ​​câu trả lời này và các câu trả lời khác về SO.

set @orig_lat=37.46; 
set @orig_long=-122.25; 
set @bounding_distance=1;

SELECT
*
,((ACOS(SIN(@orig_lat * PI() / 180) * SIN(`lat` * PI() / 180) + COS(@orig_lat * PI() / 180) * COS(`lat` * PI() / 180) * COS((@orig_long - `long`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS `distance` 
FROM `cities` 
WHERE
(
  `lat` BETWEEN (@orig_lat - @bounding_distance) AND (@orig_lat + @bounding_distance)
  AND `long` BETWEEN (@orig_long - @bounding_distance) AND (@orig_long + @bounding_distance)
)
ORDER BY `distance` ASC
limit 25;

1
chính xác những gì bounding_distanceđại diện? giá trị này có giới hạn kết quả trong một dặm không? Vì vậy, trong trường hợp này, nó sẽ trả về kết quả trong vòng 1 dặm?
James

1
@ binding_distance tính theo độ ở đây và được sử dụng để tăng tốc các phép tính bằng cách giới hạn vùng tìm kiếm hiệu quả. Ví dụ: nếu bạn biết người dùng của mình ở một thành phố nào đó và bạn biết rằng bạn có một vài điểm trong thành phố đó, bạn có thể đặt khoảng cách giới hạn của mình một cách an toàn ở một vài độ.
Evan

1
Công thức khoảng cách địa lý này được sử dụng?
bbodenmiller

12

Dễ dàng một;)

SELECT * FROM `WAYPOINTS` W ORDER BY
ABS(ABS(W.`LATITUDE`-53.63) +
ABS(W.`LONGITUDE`-9.9)) ASC LIMIT 30;

Chỉ cần thay thế tọa độ với những yêu cầu của bạn. Các giá trị phải được lưu trữ là gấp đôi. Đây là một ví dụ MySQL 5.x đang hoạt động.

Chúc mừng


2
Không biết tại sao upvote, OP muốn giới hạn và đặt hàng theo khoảng cách nhất định, không giới hạn 30 và đặt hàng trướcdx+dy
okm

3
Điều này đã làm điều đó cho tôi. Đó không phải là những gì OP muốn, nhưng đó là những gì tôi muốn, vì vậy cảm ơn bạn đã trả lời! :)
Quản trị trang web G

ABS ngoài cùng () là đủ.
dzona

6

Hãy thử điều này, nó hiển thị các điểm gần nhất với tọa độ được cung cấp (trong vòng 50 km). Nó hoạt động hoàn hảo:

SELECT m.name,
    m.lat, m.lon,
    p.distance_unit
             * DEGREES(ACOS(COS(RADIANS(p.latpoint))
             * COS(RADIANS(m.lat))
             * COS(RADIANS(p.longpoint) - RADIANS(m.lon))
             + SIN(RADIANS(p.latpoint))
             * SIN(RADIANS(m.lat)))) AS distance_in_km
FROM <table_name> AS m
JOIN (
      SELECT <userLat> AS latpoint, <userLon> AS longpoint,
             50.0 AS radius, 111.045 AS distance_unit
     ) AS p ON 1=1
WHERE m.lat
BETWEEN p.latpoint  - (p.radius / p.distance_unit)
    AND p.latpoint  + (p.radius / p.distance_unit)
    AND m.lon BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
    AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
ORDER BY distance_in_km

Chỉ cần thay đổi <table_name>. <userLat><userLon>

Bạn có thể đọc thêm về giải pháp này tại đây: http://www.plumislandmedia.net/mysql/haversine-mysql-gầnest-loc/


5

Bạn đang tìm kiếm những thứ như công thức haversine . Xem tại đây là tốt.

Có những cái khác nhưng đây là trích dẫn phổ biến nhất.

Nếu bạn đang tìm kiếm thứ gì đó mạnh mẽ hơn nữa, bạn có thể muốn xem xét khả năng của cơ sở dữ liệu GIS. Chúng có khả năng làm một số điều thú vị như cho bạn biết liệu một điểm (Thành phố) có xuất hiện trong một đa giác nhất định (Vùng, Quốc gia, Lục địa) hay không.


Nó thực sự được trích dẫn nhiều nhất, nhưng nhiều bài viết đề cập đến phần cứng máy tính cũ khi nói về các tính toán không chính xác bằng các phương pháp khác. Xem thêm Movable-type.co.uk/scripts/latlong.html#cosine-law
Arjan

5

Các câu trả lời ban đầu cho câu hỏi là tốt, nhưng các phiên bản mới hơn của mysql (MySQL 5.7.6 trở đi) hỗ trợ các truy vấn địa lý, do đó giờ đây bạn có thể sử dụng chức năng tích hợp thay vì thực hiện các truy vấn phức tạp.

Bây giờ bạn có thể làm một cái gì đó như:

select *, ST_Distance_Sphere( point ('input_longitude', 'input_latitude'), 
                              point(longitude, latitude)) * .000621371192 
          as `distance_in_miles` 
  from `TableName`
having `distance_in_miles` <= 'input_max_distance'
 order by `distance_in_miles` asc

Các kết quả được trả về trong metersvì vậy nếu bạn muốn KMthay vì dặm sử dụng .0001thay vì.000621371192

Tài liệu MySql ở đây


Nếu có thể xin vui lòng thêm phiên bản mysql trong câu trả lời.
Parixit

ST_Distance_Spherekhông tồn tại trong cài đặt máy chủ của tôi ( mysql Ver 15.1 Distrib 10.2.23-MariaDB). Tôi đọc ở đâu đó để thay thế ST_Distancenhưng khoảng cách là cách.
ashleedawg

@ashleedawg - Từ phiên bản, tôi nghĩ bạn đang sử dụng MariaDB, một nhánh của mysql. Từ cuộc trò chuyện này, có vẻ như MariaDB đã không triển khaiST_Distance_Sphere
Sherman

4

Kiểm tra mã này dựa trên bài viết Geo-Khoảng cách-Tìm kiếm với MySQL :

Ví dụ: tìm ra 10 khách sạn gần vị trí hiện tại của tôi trong bán kính 10 dặm:

#Please notice that (lat,lng) values mustn't be negatives to perform all calculations

set @my_lat=34.6087674878572; 
set @my_lng=58.3783670308302;
set @dist=10; #10 miles radius

SELECT dest.id, dest.lat, dest.lng,  3956 * 2 * ASIN(SQRT(POWER(SIN((@my_lat -abs(dest.lat)) * pi()/180 / 2),2) + COS(@my_lat * pi()/180 ) * COS(abs(dest.lat) *  pi()/180) * POWER(SIN((@my_lng - abs(dest.lng)) *  pi()/180 / 2), 2))
) as distance
FROM hotel as dest
having distance < @dist
ORDER BY distance limit 10;

#Also notice that distance are expressed in terms of radius.

3
simpledb.execSQL("CREATE TABLE IF NOT EXISTS " + tablename + "(id INTEGER PRIMARY KEY   AUTOINCREMENT,lat double,lng double,address varchar)");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2891001','70.780154','craftbox');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2901396','70.7782428','kotecha');");//22.2904718 //70.7783906
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2863155','70.772108','kkv Hall');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.275993','70.778076','nana mava');");
            simpledb.execSQL("insert into '" + tablename + "'(lat,lng,address)values('22.2667148','70.7609386','Govani boys hostal');");


    double curentlat=22.2667258;  //22.2677258
    double curentlong=70.76096826;//70.76096826

    double curentlat1=curentlat+0.0010000;
    double curentlat2=curentlat-0.0010000;

    double curentlong1=curentlong+0.0010000;
    double curentlong2=curentlong-0.0010000;

    try{

        Cursor c=simpledb.rawQuery("select * from '"+tablename+"' where (lat BETWEEN '"+curentlat2+"' and '"+curentlat1+"') or (lng BETWEEN         '"+curentlong2+"' and '"+curentlong1+"')",null);

        Log.d("SQL ", c.toString());
        if(c.getCount()>0)
        {
            while (c.moveToNext())
            {
                double d=c.getDouble(1);
                double d1=c.getDouble(2);

            }
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

2

Có vẻ như bạn muốn thực hiện một tìm kiếm hàng xóm gần nhất với một số ràng buộc về khoảng cách. SQL không hỗ trợ bất cứ điều gì như thế này theo như tôi biết và bạn sẽ cần sử dụng cấu trúc dữ liệu thay thế như cây R hoặc cây kd .


2

Tìm người dùng gần nhất với tôi:

Khoảng cách tính bằng mét

Dựa trên công thức của Vincenty

tôi có bảng người dùng:

+----+-----------------------+---------+--------------+---------------+
| id | email                 | name    | location_lat | location_long |
+----+-----------------------+---------+--------------+---------------+
| 13 | xxxxxx@xxxxxxxxxx.com | Isaac   | 17.2675625   | -97.6802361   |
| 14 | xxxx@xxxxxxx.com.mx   | Monse   | 19.392702    | -99.172596    |
+----+-----------------------+---------+--------------+---------------+

sql:

-- my location:  lat   19.391124   -99.165660
SELECT 
(ATAN(
    SQRT(
        POW(COS(RADIANS(users.location_lat)) * SIN(RADIANS(users.location_long) - RADIANS(-99.165660)), 2) +
        POW(COS(RADIANS(19.391124)) * SIN(RADIANS(users.location_lat)) - 
       SIN(RADIANS(19.391124)) * cos(RADIANS(users.location_lat)) * cos(RADIANS(users.location_long) - RADIANS(-99.165660)), 2)
    )
    ,
    SIN(RADIANS(19.391124)) * 
    SIN(RADIANS(users.location_lat)) + 
    COS(RADIANS(19.391124)) * 
    COS(RADIANS(users.location_lat)) * 
    COS(RADIANS(users.location_long) - RADIANS(-99.165660))
 ) * 6371000) as distance,
users.id
FROM users
ORDER BY distance ASC

bán kính trái đất: 6371000 (tính bằng mét)


1

Phiên bản MS SQL tại đây:

        DECLARE @SLAT AS FLOAT
        DECLARE @SLON AS FLOAT

        SET @SLAT = 38.150785
        SET @SLON = 27.360249

        SELECT TOP 10 [LATITUDE], [LONGITUDE], SQRT(
            POWER(69.1 * ([LATITUDE] - @SLAT), 2) +
            POWER(69.1 * (@SLON - [LONGITUDE]) * COS([LATITUDE] / 57.3), 2)) AS distance
        FROM [TABLE] ORDER BY 3

0

Âm thanh như bạn chỉ nên sử dụng PostGIS, SpatialLite, SQLServer2008 hoặc Oracle Spatial. Tất cả họ có thể trả lời câu hỏi này cho bạn bằng SQL không gian.


7
Nghe có vẻ như bạn KHÔNG nên đề nghị mọi người chuyển đổi toàn bộ nền tảng cơ sở dữ liệu của họ và khiến các kết quả không liên quan hiển thị trong tìm kiếm google của tôi khi tôi tìm kiếm một cách rõ ràng "Oracle" ...
Tôi đã vật lộn một con gấu.

0

Trong trường hợp cực đoan, cách tiếp cận này không thành công, nhưng để thực hiện, tôi đã bỏ qua lượng giác và chỉ đơn giản là tính bình phương đường chéo.


-13

Vấn đề này không khó lắm, nhưng nó sẽ phức tạp hơn nếu bạn cần tối ưu hóa nó.

Ý tôi là, bạn có 100 vị trí trong cơ sở dữ liệu của bạn hay 100 triệu? Điều đó gây ra một khác biệt lớn.

Nếu số lượng vị trí ít, hãy lấy chúng ra khỏi SQL và nhập mã bằng cách thực hiện ->

Select * from Location

Khi bạn nhận được chúng vào mã, hãy tính khoảng cách giữa mỗi lat / lon và bản gốc của bạn với công thức Haversine và sắp xếp nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.