From 72c39410c80ee842bf3de22418086d102cb2b768 Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Fri, 29 Jan 2010 02:46:07 +0000 Subject: [PATCH] Renamed `reverse` to `reverse_geom` because of clash with existing `QuerySet` method; added `GeoQuerySet.geohash` support for producing GeoHash reprsentations. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12350 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/db/models/manager.py | 7 +++++-- django/contrib/gis/db/models/query.py | 17 ++++++++++++++++- django/contrib/gis/tests/geoapp/tests.py | 23 +++++++++++++++++++---- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/django/contrib/gis/db/models/manager.py b/django/contrib/gis/db/models/manager.py index 1e936c79cd..61fb82132b 100644 --- a/django/contrib/gis/db/models/manager.py +++ b/django/contrib/gis/db/models/manager.py @@ -39,6 +39,9 @@ class GeoManager(Manager): def force_rhr(self, *args, **kwargs): return self.get_query_set().force_rhr(*args, **kwargs) + def geohash(self, *args, **kwargs): + return self.get_query_set().geohash(*args, **kwargs) + def geojson(self, *args, **kwargs): return self.get_query_set().geojson(*args, **kwargs) @@ -72,8 +75,8 @@ class GeoManager(Manager): def point_on_surface(self, *args, **kwargs): return self.get_query_set().point_on_surface(*args, **kwargs) - def reverse(self, *args, **kwargs): - return self.get_query_set().reverse(*args, **kwargs) + def reverse_geom(self, *args, **kwargs): + return self.get_query_set().reverse_geom(*args, **kwargs) def scale(self, *args, **kwargs): return self.get_query_set().scale(*args, **kwargs) diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py index 781df8c76f..79eed853f9 100644 --- a/django/contrib/gis/db/models/query.py +++ b/django/contrib/gis/db/models/query.py @@ -162,6 +162,20 @@ class GeoQuerySet(QuerySet): } return self._spatial_attribute('geojson', s, **kwargs) + def geohash(self, precision=20, **kwargs): + """ + Returns a GeoHash representation of the given field in a `geohash` + attribute on each element of the GeoQuerySet. + + The `precision` keyword may be used to custom the number of + _characters_ used in the output GeoHash, the default is 20. + """ + s = {'desc' : 'GeoHash', + 'procedure_args': {'precision': precision}, + 'procedure_fmt': '%(geo_col)s,%(precision)s', + } + return self._spatial_attribute('geohash', s, **kwargs) + def gml(self, precision=8, version=2, **kwargs): """ Returns GML representation of the given field in a `gml` attribute @@ -253,12 +267,13 @@ class GeoQuerySet(QuerySet): """ return self._geom_attribute('point_on_surface', **kwargs) - def reverse(self, **kwargs): + def reverse_geom(self, **kwargs): """ Reverses the coordinate order of the geometry, and attaches as a `reverse` attribute on each element of this GeoQuerySet. """ s = {'select_field' : GeomField(),} + kwargs.setdefault('model_att', 'reverse_geom') if connections[self.db].ops.oracle: s['geo_field_type'] = LineStringField return self._spatial_attribute('reverse', s, **kwargs) diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py index ba662bb48b..ab915896e5 100644 --- a/django/contrib/gis/tests/geoapp/tests.py +++ b/django/contrib/gis/tests/geoapp/tests.py @@ -690,14 +690,14 @@ class GeoModelTest(TestCase): @no_mysql @no_spatialite def test28_reverse(self): - "Testing GeoQuerySet.reverse()." + "Testing GeoQuerySet.reverse_geom()." coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ] Track.objects.create(name='Foo', line=LineString(coords)) - t = Track.objects.reverse().get(name='Foo') + t = Track.objects.reverse_geom().get(name='Foo') coords.reverse() - self.assertEqual(tuple(coords), t.reverse.coords) + self.assertEqual(tuple(coords), t.reverse_geom.coords) if oracle: - self.assertRaises(TypeError, State.objects.reverse) + self.assertRaises(TypeError, State.objects.reverse_geom) @no_mysql @no_oracle @@ -714,6 +714,21 @@ class GeoModelTest(TestCase): s = State.objects.force_rhr().get(name='Foo') self.assertEqual(rhr_rings, s.force_rhr.coords) + @no_mysql + @no_oracle + @no_spatialite + def test29_force_rhr(self): + "Testing GeoQuerySet.geohash()." + if not connection.ops.geohash: return + # Reference query: + # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston'; + # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston'; + ref_hash = '9vk1mfq8jx0c8e0386z6' + h1 = City.objects.geohash().get(name='Houston') + h2 = City.objects.geohash(precision=5).get(name='Houston') + self.assertEqual(ref_hash, h1.geohash) + self.assertEqual(ref_hash[:5], h2.geohash) + from test_feeds import GeoFeedTest from test_regress import GeoRegressionTests from test_sitemaps import GeoSitemapTest