我正在使用django和django-nonrel在google appengine上使用python进行我的一个项目。
我有实体,其地理位置以纬度/经度编码为DecimalFiled(目前可以更改)
我想对这些实体以及直接查找和边界框查询进行边界框查询。
我可以使用哪个库或扩展程序?
我已经遇到了GeoDjango,它不会在appegine和GeoModel上运行,而这似乎不会与django-nonrel一起运行。
有什么建议吗?
答案 0 :(得分:2)
GeoDjango需要一些GAE不支持的东西。首先,它需要具有C扩展的Python模块才能正常工作。特别是Geos和GDAL。其次,您需要GeoDjango支持的地理空间后端。目前,您可以选择Spatialite,Postgis,Oracle和MySQL。因此,如果您正在使用GAE,Jython或任何其他不支持这些C扩展的平台,则GeoDjango不是一个选项。
但是,有一些选择。有一个名为nonrel-geomodel的项目,但它看起来好像有一段时间没有更新。还有一些使用GAE进行地理空间搜索的项目。您提到geomodel作为GAE的选项。它没有给你紧凑的Django集成,但有一种解决方法。解决此问题的一种方法是创建一个custom manager来实现您需要的功能。它实际上并不像你想象的那么困难。
最后,如果你愿意,你可以自己动手。 MongoDB支持使用geohashing的地理空间查询。有几个Python geohashing库可用。一种选择是创建一个这样的抽象基类。
class SomethingWithLocation(models.Model):
lon = models.FloatField()
lat = models.FloatField()
geohash = models.CharField(editable=False)
def save(self,*args,**kwargs):
#Compute geohash here
super(SomethingWithLocation,self).save(*args,**kwargs)
然后你必须实现搜索功能。这不是微不足道的,但绝对可能。
您可能还想查看有关如何使用Django nonrel和MongoDB进行地理空间查询的related question。
答案 1 :(得分:0)
从我记忆中,这并不容易。但我使用GeoManager和geoutilsman函数使用django-nonrel。我在保存时更新实体上的GeoCells。我用边界框查询 一些片段:
<强>模型:强>
latitude = models.FloatField(_('latitude'), default=0,blank=True, null=True)
longitude = models.FloatField(_('longitude'), default=0,blank=True, null=True)
location_geocells=fields.ListField(models.CharField(max_length=15),null=True,blank=True) #
objects = GeoManager() # Bring in other class objects for geomodel
<强>用法强>
from geoutilsmain.geotypes import Point
from functions.panafunctions import get_bounding_box
...
center_point = Point(latitude, longitude)
logging.info("GEO search. Point: "+str(center_point)+" Radius: "+str(radius))
mybox=get_bounding_box(latitude, longitude, radius) # 10: half side in miles
north=mybox.lat_max # Jon verified defs of north vs lat
south=mybox.lat_min
west=mybox.lon_min
east=mybox.lon_max
logging.info("Bounding box co-ords: North: "+str(north)+" East: "+str(east)+" South: "+str(south)+" West: "+str(west))
query_results=conceptdb.objects.within(north, east, south, west,max_results=limit)# within(north, east, south, west)
myarray=QuerySetToDict(query_results)
...
def update_geocells(self): msgstr“”“将基础geocell属性与实体的位置同步。
Updates the underlying geocell properties of the entity to match the
entity's location property. A put() must occur after this call to save
the changes to App Engine."""
if self.latitude and self.longitude:
max_res_geocell = geocell.compute(self.location)
self.location_geocells = [max_res_geocell[:res]
for res in
range(1, geocell.MAX_GEOCELL_RESOLUTION + 1)]
else:
self.location_geocells = []