问题描述
我找到了一些不错的建议https://pypi.org/project/RESTinstance/,以找到一对具有单一经度和纬度的位置。但是,我正在寻找一种有效的方法来查找一组(多对)纬度和经度附近的位置。然后将结果分组。我可以在MysqL中使用UNION在下面编写的查询中使用。但是我正在寻找没有UNION的方法。我的表格(user_locations)
+----+--------+-----------+-----------+-----------------------------+
| id | userid | lat | lng | point |
+----+--------+-----------+-----------+-----------------------------+
| 1 | 18 | 48.204784 | 16.369640 | POINT(16.369640,48.204784) |
+----+--------+-----------+-----------+-----------------------------+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946,48.205872) |
+----+--------+-----------+-----------+-----------------------------+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867,48.205914) |
+----+--------+-----------+-----------+-----------------------------+
具有一个纬度和经度对的查询:查找[48.205546,16.368667]附近的用户
SELECT
name,( 3959 * acos( cos( radians(48.205546) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians(16.368667)) + sin(radians(48.205546))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我希望将上面的查询与一组给定的经度一起使用:查找附近的用户: [[48.205546,16.368667],[48.205084、16.369712],[48.205660、16.367947]]
SELECT
name,( 3959 * acos( cos( radians($lat1,$lat2,$lat3,$lat4) ) * cos( radians( locations.lat ) )
* cos( radians(locations.lng) - radians($lng1,$lng2,$lng3,$lng4)) + sin(radians($lat))
* sin( radians(locations.lat)))) AS distance
FROM user_locations
WHERE active = 1
HAVING distance < 10
ORDER BY distance;
我并不是真正在寻找特定的输出,因为结果将被分组,所以距离并不是那么重要。用户18可能靠近多个纬度对。将结果与userid分组只会检索一行userid:18。
+----+--------+-----------+-----------+-----------------------------+--+
| id | userid | lat | lng | point | |
+----+--------+-----------+-----------+-----------------------------+--+
| 2 | 21 | 48.205872 | 16.368946 | POINT(16.368946,48.205872) | |
+----+--------+-----------+-----------+-----------------------------+--+
| 3 | 11 | 48.205914 | 16.367867 | POINT(16.367867,48.205914) | |
+----+--------+-----------+-----------+-----------------------------+--+
解决方法
收集:[[48.205546,16.368667],[48.205084,16.369712],[48.205660,16.367947]]
Hacky解决方案:
SELECT locations.* FROM user_locations AS locations
WHERE (MBRContains
(
LineString
(
Point (
16.368667 + 10 / ( 111.320 / COS(RADIANS(48.205546))),48.205546 + 10 / 111.133
),Point (
16.368667 - 10 / ( 111.320 / COS(RADIANS(48.205546))),48.205546 - 10 / 111.133
)
),locations.point
)
OR MBRContains
(
LineString
(
Point (
16.369712 + 10 / ( 111.320 / COS(RADIANS(48.205084))),48.205084 + 10 / 111.133
),Point (
16.369712 - 10 / ( 111.320 / COS(RADIANS(48.205084))),48.205084 - 10 / 111.133
)
),locations.point
)
OR MBRContains
(
LineString
(
Point (
16.367947 + 10 / ( 111.320 / COS(RADIANS(48.205660))),48.205660 + 10 / 111.133
),Point (
16.367947 - 10 / ( 111.320 / COS(RADIANS(48.205660))),48.205660 - 10 / 111.133
)
),locations.point
))
查询持续时间:0.109秒(精细)。
注意:点域具有空间索引
10(公里内的距离)
16.368667(长)
48.205546(lat)