如何对django进行空间查询,不依赖于appengine

时间:2012-07-08 20:44:49

标签: django google-app-engine django-nonrel

我正在使用django和django-nonrel在google appengine上使用python进行我的一个项目。

我有实体,其地理位置以纬度/经度编码为DecimalFiled(目前可以更改)

我想对这些实体以及直接查找和边界框查询进行边界框查询。

我可以使用哪个库或扩展程序?

我已经遇到了GeoDjango,它不会在appegine和GeoModel上运行,而这似乎不会与django-nonrel一起运行。

有什么建议吗?

2 个答案:

答案 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 = []