У меня есть таблица с идентификатором, широтой (широта), долготой (lng), высотой (alt). У меня есть координаты, и я хотел бы найти ближайшую запись в БД. Я использовал это, но еще не работал правильно:

SELECT lat,ABS(lat - TestCordLat), lng, ABS(lng - TestCordLng), alt AS distance
FROM dhm200
ORDER BY distance
LIMIT 6

У меня есть таблица с 6 ближайшими точками, показывающая мне широту, долготу и высоту.

1
user3439871 2 Янв 2018 в 01:15

2 ответа

Лучший ответ

Вам нужно будет использовать Формула Хаверсинуса для расчета расстояний с учетом широты и долготы:

dlon = lon2 - lon1 
 dlat = lat2 - lat1 
 a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2 
 c = 2 * atan2( sqrt(a), sqrt(1-a) ) 
 distance = R * c (where R is the radius of the Earth)

Однако высота увеличивает сложность проблемы. Если между точкой A и точкой B на разных высотах дорога имеет много перепадов высот, то предположение, что производная линии высоты между двумя точками неизменна, может вводить в заблуждение, а не принимать это во внимание вообще может вводить в заблуждение. Сравните расстояние между точкой в Китае и точкой в Индии, где Гималаи находятся между ними, с расстоянием между двумя точками на поверхности Тихого океана. Можно было бы изменять R как среднее значение высоты для каждого сравнения, но в случае больших расстояний это может ввести в заблуждение, как обсуждалось ранее.

0
Lajos Arpad 2 Янв 2018 в 01:26

Запрос на получение ближайшего расстояния в kilometer (km) от mysql:

SELECT id, latitude, longitude, SQRT( POW(69.1 * (latitude - 4.66455174) , 2) + POW(69.1 * (-74.07867091 - longitude) * COS(latitude / 57.3) , 2)) AS distance FROM ranks ORDER BY distance ASC;

Вы можете ограничить радиус синтаксисом HAVING.

... AS distance FROM ranks HAVING distance < '150' ORDER BY distance ASC;

Примере:

mysql> describe ranks;
+------------+---------------+------+-----+---------+----------------+
| Field      | Type          | Null | Key | Default | Extra          |
+------------+---------------+------+-----+---------+----------------+
| id         | int           | NO   | PRI | NULL    | auto_increment |
| latitude   | decimal(10,8) | YES  | MUL | NULL    |                |
| longitude  | decimal(11,8) | YES  |     | NULL    |                |
+------------+---------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> SELECT id, latitude, longitude, SQRT( POW(69.1 * (latitude - 4.66455174) , 2) + POW(69.1 * (-74.07867091 - longitude) * COS(latitude / 57.3) , 2)) AS distance FROM ranks ORDER BY distance ASC;
+----+-------------+--------------+--------------------+
| id | latitude    | longitude    | distance           |
+----+-------------+--------------+--------------------+
|  4 |  4.66455174 | -74.07867091 |                  0 |
| 10 |  4.13510880 | -73.63690401 |  47.59647003096195 |
| 11 |  6.55526689 | -73.13373892 | 145.86590936973073 |
|  5 |  6.24478548 | -75.57050110 | 149.74731096011348 |
|  7 |  7.06125013 | -73.84928550 | 166.35723903407165 |
|  9 |  3.48835279 | -76.51532198 | 186.68173882319724 |
|  8 |  7.88475514 | -72.49432589 | 247.53456848808233 |
|  1 | 60.00001000 | 101.00001000 |  7156.836171031409 |
|  3 | 60.00001000 | 101.00001000 |  7156.836171031409 |
+----+-------------+--------------+--------------------+
9 rows in set (0.00 sec)


0
Euph0rix 11 Апр 2020 в 10:38