2

I am using django together with django-nonrel on google appengine for one of my projects using python.

I have Entities that has a geo location coded in lat/lon as DecimalFiled (for now, can change that)

I want to make bounding box queries on these Entities as well as direct lookups and bounding box queries.

Which library or extension can I use for that?

I already came accross GeoDjango, which does not run on appegine and GeoModel, which does not seem to run with django-nonrel.

Any recommendations?

wzr1337
  • 3,609
  • 5
  • 30
  • 53

2 Answers2

2

GeoDjango requires a few things not supported by GAE. First, it requires Python modules with C extensions to work properly. In particular, Geos and GDAL. Second, you need a geospatial backend that is supported by GeoDjango. Currently, you have Spatialite, Postgis, Oracle, and MySQL as your options. So, GeoDjango is not an option if you are working on GAE, Jython or any other platform that does not support those C extensions.

However, there are options available. There is a project called nonrel-geomodel, but it doesn't look like it has been updated in a while. There are also a few projects for doing geospatial search using GAE. You mentioned geomodel as an option for GAE. It doesn't give you tight Django integration, but there is a way around this. One way around this is to create a custom manager that implements the features you need. It isn't actually as difficult as you may imagine.

Lastly, you could roll your own if you wanted. MongoDB supports geospatial queries using geohashing. There are a few Python geohashing libraries available. One option is to create an abstract base class like this.

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)

Then you would have to implement the search feature. It isn't trivial, but definitly possible.

You may also want to look at this related question on how to do geospatial queries with Django nonrel and MongoDB.

Community
  • 1
  • 1
Shawn H
  • 1,227
  • 1
  • 12
  • 18
0

From what I remember, it wasn't easy. But I got it working with django-nonrel using GeoManager and geoutilsman functions. I update the GeoCells on the entities upon saving. I query with a Bounding Box Some snippets:

model:

   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

Usage

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): """Syncs underlying geocell properties with the entity's location.

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 = []
jonincanada
  • 417
  • 5
  • 5