2

我在 google appengine 上将 django 和 django-nonrel 一起用于我使用 python 的项目之一。

我有一个在纬度/经度中编码为 DecimalFiled 的地理位置的实体(现在,可以改变它)

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

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

我已经遇到过GeoDjango,它不能在 appegine 和GeoModel上运行,它似乎不能用 django-nonrel 运行。

有什么建议吗?

4

2 回答 2

2

GeoDjango 需要一些 GAE 不支持的东西。首先,它需要带有 C 扩展的 Python 模块才能正常工作。特别是 Geos 和 GDAL。其次,您需要一个 GeoDjango 支持的地理空间后端。目前,您可以选择 Spatialite、Postgis、Oracle 和 MySQL。因此,如果您在 GAE、Jython 或任何其他不支持这些 C 扩展的平台上工作,则不能选择 GeoDjango。

但是,有可用的选项。有一个名为nonrel-geomodel的项目,但它看起来好像已经有一段时间没有更新了。还有一些使用 GAE 进行地理空间搜索的项目。您提到地理模型是 GAE 的一个选项。它不会为您提供紧密的 Django 集成,但有一种方法可以解决这个问题。解决此问题的一种方法是创建一个自定义管理器来实现您需要的功能。它实际上并没有你想象的那么困难。

最后,如果你愿意,你可以自己滚动。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 进行地理空间查询的相关问题。

于 2012-08-17T18:22:54.097 回答
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): """将基础地理单元属性与实体的位置同步。

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 = []
于 2012-12-06T04:27:42.837 回答