【问题标题】:How to make spatial queries on django non-rel on appengine如何在应用引擎上的 django non-rel 中进行空间查询
【发布时间】:2012-07-08 20:44:48
【问题描述】:

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

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

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

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

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

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    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)
    

    然后您必须实现搜索功能。这不是微不足道的,但绝对有可能。

    您可能还想查看related question,了解如何使用 Django nonrel 和 MongoDB 进行地理空间查询。

    【讨论】:

      【解决方案2】:

      据我所知,这并不容易。但是我使用 GeoManager 和 geoutilsman 函数让它与 django-nonrel 一起工作。我在保存时更新实体上的 GeoCells。我用边界框查询 一些sn-ps:

      型号:

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

      【讨论】:

        猜你喜欢
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-11
        相关资源
        最近更新 更多