基于纬度和频率的半径滤波器的Python Flask转换计算对SQLalchemy的经度

时间:2017-01-23 10:34:47

标签: python sqlalchemy

我目前正在尝试实施半径计算:

我有一个带房间的数据库,每个房间都有不同的地址,还有经度和经度。

用户可以在搜索表单中输入城市名称以搜索此城市中的房间。在这里,我想显示一个结果页面,其中包含搜索到的城市中的房间+距离搜索城市60公里半径范围内的其他城市的所有房间。

Here我找到了一些我想尝试的解决方案,但我无法弄清楚如何将其转换为SQLalchemy查询:

SELECT * FROM Places WHERE acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) * 6371 <= 60;

所以理论上我必须用搜索到的城市的纬度和经度替换1.3963-0.6981,我会得到我想要的东西。

3 个答案:

答案 0 :(得分:0)

您可以使用SQL alchemy的from_statement(statement)方法,如下所述:

http://docs.sqlalchemy.org/en/latest/orm/query.html

有了这个,您不需要将其转换为SQL Alchemy“语法”,QueryAPI将为您完成。

所以你可以这样做:

q = session.query(PlacesClass).from_statement(
    'SELECT * FROM Places WHERE acos(sin(1.3963) * sin(Lat) + '\
    'cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) * 6371 <= 60;')

答案 1 :(得分:0)

以下是sqlalchemy中的解决方案:

loc是有人搜索的位置。例如,用户输入城市名称。

Zimmer是我的表,其中所有数据库条目都是,每个Zimmer都有一个lat和lng,这些用于计算输入loc的半径。为了限制半径,我们使用<= 100(100公里)。

all_rooms_in_city = Zimmer.query.filter(func.acos(func.sin(func.radians(loc_latitude)) * func.sin(func.radians(Zimmer.zimmer_lat)) + func.cos(func.radians(loc_latitude)) * func.cos(func.radians(Zimmer.zimmer_lat)) * func.cos(func.radians(Zimmer.zimmer_lng) - (func.radians(loc_longitude)))) * 6371 <= 100)

只需在order_by()中添加相同的代码并省略限制<= 100半径即可进行排序:

.order_by(asc(func.acos(func.sin(func.radians(loc_latitude)) * func.sin(func.radians(Zimmer.zimmer_lat)) + func.cos(func.radians(loc_latitude)) * func.cos(func.radians(Zimmer.zimmer_lat)) * func.cos(func.radians(Zimmer.zimmer_lng) - (func.radians(loc_longitude)))) * 6371))

不要忘记从sqlalchemy导入func,因为否则数学方法在查询中不起作用。如果您已将lat和lng保存在数据库的Radians列中,则不需要进行类型转换。我使用func.radians()因为我的lat和lng保存在Float Column中

答案 2 :(得分:0)

尽管@Roman的上述回答为我提供了实现此目标的基本思路,但是,他的解决方案对我不起作用。所以,这是我的解决方案:

OPTIONS = ChromeOptions()
OPTIONS.add_argument("--user-data-dir=./User_Data")
Chrome(chrome_options=OPTIONS)

这里Location.query.filter( (func.degrees( func.acos( func.sin(func.radians(lat)) * func.sin(func.radians(Location.latitude)) + func.cos(func.radians(lat)) * func.cos(func.radians(Location.latitude)) * func.cos(func.radians(lon-Location.longitude)) ) ) * 60 * 1.1515 * 1.609344) <= distance) lat是我计算距离的给定坐标。该距离受查询中给定的lon的限制。此查询正在计算distance中的距离,如果要在km中计算距离,请从查询中删除mile