My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Usage  
How to use GeoModel
Featured
Updated Aug 1, 2009 by api.roman.public@gmail.com

Creating and saving GeoModel-derived entities

To use the GeoModel class, simply declare a new model class inheriting from the geo.GeoModel class like so:

from geo.geomodel import GeoModel

class MyEntity(GeoModel):
  foo = db.StringProperty()
  bar = db.IntegerProperty()

Currently, only single-point entities are supported. Entities of the new MyEntity kind will have a location property of type db.GeoPt, which can be set as needed. Before put()'ing entities to the datastore, make sure to call update_location to synchronize the entity's underlying geocell indexing properties:

some_entity = MyEntity(location=db.GeoPt(37, -122),
                       foo='Hello',
                       bar=5)
...
some_entity.location = db.GeoPt(38, -122)
some_entity.update_location()
some_entity.put()

Querying your entities

There are currently two types of basic geospatial queries supported by the GeoModel library:

  • bounding box queries
  • proximity (nearest-n) queries

To perform a bounding box query, use the bounding_box_fetch class method like so:

results = MyEntity.bounding_box_fetch(
              MyEntity.all().filter('bar >', 5),  # Rich query!
              geotypes.Box(39, -121, 37, -123),
              max_results=10)

Be careful not to request too many results or else you'll get a datastore or request timeout!

To perform a proximity query, use the proximity_fetch class method like so:

resuts = MyEntity.proximity_fetch(
             MyEntity.all().filter('bar <', 10),  # Rich query!
             geotypes.Point(39, -121),  # Or db.GeoPt
             max_results=10,
             max_distance=80467)  # Within 50 miles.

Note that for rich queries on multiple properties you'll need to set up the proper indexes in your index.yaml file. Testing your app on the development server should populate that file with the required indexes. Also, GeoModel currently requires many internal properties on each entity (one for each geocell resolution), which can lead to messy looking index.yaml files. That's something that will hopefully change in future versions.

Comment by jon.midd...@gmail.com, Aug 23, 2009

Looks fantastic

Comment by col.wils...@gmail.com, Aug 28, 2009

I'll be giving this a go very soon.

Comment by katz...@gmail.com, Jan 1, 2011

I tried it. It is very convenient, but also very costly. A proximity_fetch on a ancestor query takes between 20000 and 60000 cpu+api_ms and has cpm_usd=0.327598. That is quite high. Not sure if it can be optimized.

Comment by bogo.gie...@gmail.com, Mar 28, 2011

Thank you very much for that guys! Made my life so much easier -- proximity_fetch is query expensive, but works like charm!

Comment by ana...@gmail.com, Jul 25, 2011

How Can I install geomodel on my app on AppEngine??

Comment by oggystyl...@gmail.com, Nov 8, 2011

proximity_fetch does not work for me.. I always get 0 objects back, even if I use the same coordinates the whole time. Has anyone experienced the same problem?

Comment by cezeo...@yahoo.com, Dec 31, 2011

@oggystyl: Yes, I am experiencing the same issue. Were you able to resolve it?

Comment by cezeo...@yahoo.com, Dec 31, 2011

Resolved. I forgot this line when saving: some_entity.update_location()

Comment by grzegorz...@gmail.com, Jan 20, 2012

Hi, I try to use it and get an error: <type 'exceptions.ImportError?'>: No module named geo.geomodel

args = ('No module named geo.geomodel',) message = 'No module named geo.geomodel'

on line from geo.geomodel import GeoModel?

any ideas on how to fix that?

Comment by grzegorz...@gmail.com, Jan 20, 2012

ok it was a silly first python/google engine app problem. for the other begginers: download .egg file: http://pypi.python.org/pypi/geomodel/0.2.0 change .egg to .zip unzip file in the root directory of your app engine project so you get the geo/ directory

Comment by matt.e.m...@gmail.com, Jan 26, 2012

What am I doing wrong?

I'm getting when I try this via unit tests using GAEUnit.

File "test/datastore_tests.py", line 100, in retrieve_messages

self.assertEquals(len(results), 1)
AssertionError?: 2 != 1

Seems it's retrieving both test messages which it shouldn't.


def retrieve_messages(self):

logging.info("TEST_RETRIEVE_MESSAGES begin...")
pt1 = db.GeoPt?(lat=8.407168,lon=-174.023437) pt2 = db.GeoPt?(lat=54.572062,lon=56.601563)
user_key = db.Key.from_path('User', 'matt'); content = unicode("Unit test message.")
test_message = message.Message(parent=user_key, location=pt1, content=content) test_message.location = pt1 test_message.update_location() test_message.put()
test_message1 = message.Message(parent=user_key, location=pt2, content=content) test_message1.location = pt2 test_message1.update_location() test_message1.put()
  1. ODO: this will be the method and query that is acutally tested when moved to message
bounding_box = message.BoundingBox?.get_bounding_box(pt1.lat, pt1.lon, 0.5) results = message.Message.proximity_fetch(
message.Message.all().ancestor(user_key), # Rich query! db.GeoPt?(lat=54.572000,lon=56.601500), max_results=10, max_distance=1000000)
self.assertEquals(len(results), 1) msg = results0? logging.info("Origin pt:%f,%f Bounding box: (%f,%f) - (%f,%f), Retrieved message location:%f,%f", pt1.lat, pt1.lon, bounding_box.lat_min, bounding_box.lon_min, bounding_box.lat_max, bounding_box.lon_max, msg.location.lat, msg.location.lon) self.assertEquals(msg.location, pt2)


I haven't tried in normal code (i.e. non-unit testing).

Thanks in advance,

Matt

Comment by jer...@smartnsoft.com, Feb 1, 2012

Can i have the same example code in java plz ?


Sign in to add a comment
Powered by Google Project Hosting