2

Python を使用するプロジェクトの 1 つで、Google appengine で django-nonrel と一緒に django を使用しています。

DecimalFiled として緯度/経度でコード化された地理的位置を持つエンティティがあります (今のところ、それを変更できます)

これらのエンティティに対してバウンディング ボックス クエリを作成するだけでなく、直接ルックアップやバウンディング ボックス クエリも作成したいと考えています。

そのためにどのライブラリまたは拡張機能を使用できますか?

私はすでにappegineでは実行されない GeoDjango と、django- nonrelでは実行されないように見える GeoModel に遭遇しました。

推奨事項はありますか?

4

2 に答える 2

2

GeoDjangoには、GAEでサポートされていないものがいくつか必要です。まず、正しく機能するには、C拡張機能を備えたPythonモジュールが必要です。特に、GeosとGDAL。次に、GeoDjangoでサポートされている地理空間バックエンドが必要です。現在、オプションとしてSpatialite、Postgis、Oracle、およびMySQLがあります。したがって、GAE、Jython、またはこれらのC拡張機能をサポートしていないその他のプラットフォームで作業している場合、GeoDjangoはオプションではありません。

ただし、利用可能なオプションがあります。nonrel-geomodelというプロジェクトがありますが、しばらく更新されていないようです。GAEを使用して地理空間検索を行うためのプロジェクトもいくつかあります。GAEのオプションとしてジオモデルについて言及されました。Djangoとの緊密な統合はできませんが、これを回避する方法があります。これを回避する1つの方法は、必要な機能を実装するカスタムマネージャーを作成することです。あなたが想像するほど実際には難しいことではありません。

最後に、必要に応じて自分でロールすることができます。MongoDBは、ジオハッシュを使用した地理空間クエリをサポートしています。利用可能なPythonジオハッシュライブラリがいくつかあります。1つのオプションは、このような抽象基本クラスを作成することです。

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)

次に、検索機能を実装する必要があります。それは些細なことではありませんが、間違いなく可能です。

また、Djangononrelと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 に答える