# -*- coding: utf-8 -*-
""" 指定关注地点(经纬度),搜索周边商户的模块。 """
import math
from csv import reader as csv_reader
from tg import config
from ourspass import model
from ourspass.model import DBSession
from zope.sqlalchemy import ZopeTransactionExtension
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import desc, or_
GEO_BLOCK_SIZE = 0.1 # 地图划分小格的大小(单位:公里),划分越细搜索结果越准确,但对查询性能的影响也越明显。
def _get_geo_ids(geo_tuple):
"""输入经纬度,返回地理分格坐标的函数。
参数说明:
* geo_tuple: (longitude, latitude)
输入内容:
(longitude_id, latitude_id)
"""
longitude, latitude = geo_tuple
latitude_id = int(111 * (float(latitude) - 39.9415939096045) / GEO_BLOCK_SIZE)
longitude_id = int(111 * (float(longitude) - 116.311569213867) * math.cos(39.9415939096045) / GEO_BLOCK_SIZE)
return (longitude_id, latitude_id)
def update_block_shop(shop):
"""更新单个商户在地理位置划分中的缓存状态。"""
geoblocks = shop.geoblocks
if len(geoblocks) == 0:
geoblock = model.GeoBlock(shop.id, 0, 0)
DBSession.add(geoblock)
else:
geoblock = geoblocks[0]
geoblock.longitude_id, geoblock.latitude_id = _get_geo_ids((shop.longitude, shop.latitude))
# 本函数不会主动调用 DBSession.flush() ,因为它的主要应用场景是在 ourspass.model.shop_ext 中作为 DB Session 的扩展在 before_flush 情形下被调用,
# 也即本函数执行的时间点是 Session 即将进行 flush 操作时,因此即使本函数不显式调用 flush ,
# shop_ext 中的扩展也会在执行 flush 操作时自动包含本函数中完成的修改。
# 这样,其他调用本函数的场合(比如 update_block_data() 函数)就必须额外显式调用 flush() 操作。
# DBSession.flush()
def update_block_data():
"""更新系统中所有商户的地理位置划分缓存数据。"""
for shop in DBSession.query(model.Shop):
update_block_shop(shop)
# 在更新完所有店铺数据时进行一次显式 flush() 操作:
DBSession.flush()
def limit_by_geo(shops, longitude, latitude, area=3.0):
"""根据地理位置对 shops 的 Query 对象进行过滤限制。
参数说明:
* shops: 这是对 model.Shop 进行 DBSession.query 操作生成的 Query 对象。
* longitude: float,地理搜索中心点的经度数据。
* latitude: float,地理搜索中心点的维度数据。
* area: float,距离搜索中心点的半径公里数约束。
输出内容:
是增加地理限制条件后的 Query 对象,和一般的 DBSession.query 操作产生的结果是一致的。
"""
longitude_id, latitude_id = _get_geo_ids((longitude, latitude))
geo_area = int(area / GEO_BLOCK_SIZE)
shops = shops.join(model.Shop.geoblocks) #.filter(model.GeoBlock.shop_id == model.Shop.id)
shops = shops.filter(model.GeoBlock.longitude_id >= longitude_id - geo_area)
shops = shops.filter(model.GeoBlock.longitude_id <= longitude_id + geo_area)
shops = shops.filter(model.GeoBlock.latitude_id >= latitude_id - geo_area)
shops = shops.filter(model.GeoBlock.latitude_id <= latitude_id + geo_area)
return shops
def _test():
shop = DBSession.query(model.Shop).filter(model.Shop.id == 1).one()
print 'shop:', shop.longitude, shop.latitude
geoblock = shop.geoblocks[0]
print 'geo:', geoblock.longitude_id, geoblock.latitude_id
shop.longitude = 110
DBSession.flush()
print 'shop new:', shop.longitude, shop.latitude
print 'geo new:', geoblock.longitude_id, geoblock.latitude_id
def get_promos_by_latlng(lat,lng,area_type=3.0,count=5):
promos = DBSession.query(model.Promo).join(model.Promo.shop)
promos = limit_by_geo(promos, lng, lat,area_type)
promos = promos.filter(model.Promo.flag==0).order_by(desc(model.Promo.period)).limit(count)
return promos
def get_districts():
"""
获得商圈信息
"""
cache = config.cm.get_cache('CommonData')
def _districts_helper():
return [
{
'name': item[2].decode('utf-8'),
'longitude': float(item[3]),
'latitude': float(item[4]),
}
for item in csv_reader(
open(
'%s%s' % (
config.data.shop_districts_db_path,
config.data.shop_districts_db_file),
'rb'))
]
return cache.get_value(
'data_districts',
createfunc = _districts_helper,
expiretime = config.period.cache_normal
)
if __name__ == "__main__":
update_block_data()
geosearch.rar_Python经纬度_python 经纬度
版权申诉
184 浏览量
2022-07-15
03:30:05
上传
评论
收藏 2KB RAR 举报
林当时
- 粉丝: 101
- 资源: 1万+
最新资源
- vmware workstation pro 17 linux版
- 3479521_1710042575-1.rwmod
- 安装及环境配置UMCM-2023C-ma笔记
- (完整)数据库课程设计餐厅点餐说明书-21ab6d3c8beb172ded630b1c59eef8c75ebf952c.doc
- 2023-04-06-项目笔记 - 第一百五十四阶段 - 4.4.2.152全局变量的作用域-152 -2024.06.04
- 松哥解协议松哥解协议松哥解协议松哥解协议松哥解协议
- 618节日618节日618节日
- tensorflow-gpu-2.9.1-cp37-cp37m-win-amd64.whl
- tensorflow-gpu-2.9.0-cp37-cp37m-win-amd64.whl
- tensorflow-gpu-2.9.0-cp39-cp39-win-amd64.whl
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈