Added `reverse` and `force_rhr` methods to `GeoQuerySet`. Refs #12416.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12349 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
1733518095
commit
5b21033847
|
@ -50,6 +50,7 @@ class BaseSpatialOperations(object):
|
||||||
perimeter3d = False
|
perimeter3d = False
|
||||||
point_on_surface = False
|
point_on_surface = False
|
||||||
polygonize = False
|
polygonize = False
|
||||||
|
reverse = False
|
||||||
scale = False
|
scale = False
|
||||||
snap_to_grid = False
|
snap_to_grid = False
|
||||||
sym_difference = False
|
sym_difference = False
|
||||||
|
|
|
@ -88,6 +88,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
num_points = 'SDO_UTIL.GETNUMVERTICES'
|
num_points = 'SDO_UTIL.GETNUMVERTICES'
|
||||||
perimeter = length
|
perimeter = length
|
||||||
point_on_surface = 'SDO_GEOM.SDO_POINTONSURFACE'
|
point_on_surface = 'SDO_GEOM.SDO_POINTONSURFACE'
|
||||||
|
reverse = 'SDO_UTIL.REVERSE_LINESTRING'
|
||||||
sym_difference = 'SDO_GEOM.SDO_XOR'
|
sym_difference = 'SDO_GEOM.SDO_XOR'
|
||||||
transform = 'SDO_CS.TRANSFORM'
|
transform = 'SDO_CS.TRANSFORM'
|
||||||
union = 'SDO_GEOM.SDO_UNION'
|
union = 'SDO_GEOM.SDO_UNION'
|
||||||
|
|
|
@ -252,6 +252,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.envelope = prefix + 'Envelope'
|
self.envelope = prefix + 'Envelope'
|
||||||
self.extent = prefix + 'Extent'
|
self.extent = prefix + 'Extent'
|
||||||
self.extent3d = prefix + 'Extent3D'
|
self.extent3d = prefix + 'Extent3D'
|
||||||
|
self.force_rhr = prefix + 'ForceRHR'
|
||||||
self.geohash = GEOHASH
|
self.geohash = GEOHASH
|
||||||
self.geojson = GEOJSON
|
self.geojson = GEOJSON
|
||||||
self.gml = prefix + 'AsGML'
|
self.gml = prefix + 'AsGML'
|
||||||
|
@ -268,6 +269,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
|
||||||
self.perimeter3d = prefix + 'Perimeter3D'
|
self.perimeter3d = prefix + 'Perimeter3D'
|
||||||
self.point_on_surface = prefix + 'PointOnSurface'
|
self.point_on_surface = prefix + 'PointOnSurface'
|
||||||
self.polygonize = prefix + 'Polygonize'
|
self.polygonize = prefix + 'Polygonize'
|
||||||
|
self.reverse = prefix + 'Reverse'
|
||||||
self.scale = prefix + 'Scale'
|
self.scale = prefix + 'Scale'
|
||||||
self.snap_to_grid = prefix + 'SnapToGrid'
|
self.snap_to_grid = prefix + 'SnapToGrid'
|
||||||
self.svg = prefix + 'AsSVG'
|
self.svg = prefix + 'AsSVG'
|
||||||
|
|
|
@ -36,6 +36,9 @@ class GeoManager(Manager):
|
||||||
def extent3d(self, *args, **kwargs):
|
def extent3d(self, *args, **kwargs):
|
||||||
return self.get_query_set().extent3d(*args, **kwargs)
|
return self.get_query_set().extent3d(*args, **kwargs)
|
||||||
|
|
||||||
|
def force_rhr(self, *args, **kwargs):
|
||||||
|
return self.get_query_set().force_rhr(*args, **kwargs)
|
||||||
|
|
||||||
def geojson(self, *args, **kwargs):
|
def geojson(self, *args, **kwargs):
|
||||||
return self.get_query_set().geojson(*args, **kwargs)
|
return self.get_query_set().geojson(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -69,6 +72,9 @@ class GeoManager(Manager):
|
||||||
def point_on_surface(self, *args, **kwargs):
|
def point_on_surface(self, *args, **kwargs):
|
||||||
return self.get_query_set().point_on_surface(*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 scale(self, *args, **kwargs):
|
def scale(self, *args, **kwargs):
|
||||||
return self.get_query_set().scale(*args, **kwargs)
|
return self.get_query_set().scale(*args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from django.db import connections
|
||||||
from django.db.models.query import QuerySet, Q, ValuesQuerySet, ValuesListQuerySet
|
from django.db.models.query import QuerySet, Q, ValuesQuerySet, ValuesListQuerySet
|
||||||
|
|
||||||
from django.contrib.gis.db.models import aggregates
|
from django.contrib.gis.db.models import aggregates
|
||||||
from django.contrib.gis.db.models.fields import get_srid_info, GeometryField, PointField
|
from django.contrib.gis.db.models.fields import get_srid_info, GeometryField, PointField, LineStringField
|
||||||
from django.contrib.gis.db.models.sql import AreaField, DistanceField, GeomField, GeoQuery, GeoWhereNode
|
from django.contrib.gis.db.models.sql import AreaField, DistanceField, GeomField, GeoQuery, GeoWhereNode
|
||||||
from django.contrib.gis.geometry.backend import Geometry
|
from django.contrib.gis.geometry.backend import Geometry
|
||||||
from django.contrib.gis.measure import Area, Distance
|
from django.contrib.gis.measure import Area, Distance
|
||||||
|
@ -119,6 +119,15 @@ class GeoQuerySet(QuerySet):
|
||||||
"""
|
"""
|
||||||
return self._spatial_aggregate(aggregates.Extent3D, **kwargs)
|
return self._spatial_aggregate(aggregates.Extent3D, **kwargs)
|
||||||
|
|
||||||
|
def force_rhr(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Returns a modified version of the Polygon/MultiPolygon in which
|
||||||
|
all of the vertices follow the Right-Hand-Rule. By default,
|
||||||
|
this is attached as the `force_rhr` attribute on each element
|
||||||
|
of the GeoQuerySet.
|
||||||
|
"""
|
||||||
|
return self._geom_attribute('force_rhr', **kwargs)
|
||||||
|
|
||||||
def geojson(self, precision=8, crs=False, bbox=False, **kwargs):
|
def geojson(self, precision=8, crs=False, bbox=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a GeoJSON representation of the geomtry field in a `geojson`
|
Returns a GeoJSON representation of the geomtry field in a `geojson`
|
||||||
|
@ -244,6 +253,16 @@ class GeoQuerySet(QuerySet):
|
||||||
"""
|
"""
|
||||||
return self._geom_attribute('point_on_surface', **kwargs)
|
return self._geom_attribute('point_on_surface', **kwargs)
|
||||||
|
|
||||||
|
def reverse(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(),}
|
||||||
|
if connections[self.db].ops.oracle:
|
||||||
|
s['geo_field_type'] = LineStringField
|
||||||
|
return self._spatial_attribute('reverse', s, **kwargs)
|
||||||
|
|
||||||
def scale(self, x, y, z=0.0, **kwargs):
|
def scale(self, x, y, z=0.0, **kwargs):
|
||||||
"""
|
"""
|
||||||
Scales the geometry to a new size by multiplying the ordinates
|
Scales the geometry to a new size by multiplying the ordinates
|
||||||
|
@ -489,7 +508,8 @@ class GeoQuerySet(QuerySet):
|
||||||
|
|
||||||
# Performing setup for the spatial column, unless told not to.
|
# Performing setup for the spatial column, unless told not to.
|
||||||
if settings.get('setup', True):
|
if settings.get('setup', True):
|
||||||
default_args, geo_field = self._spatial_setup(att, desc=settings['desc'], field_name=field_name)
|
default_args, geo_field = self._spatial_setup(att, desc=settings['desc'], field_name=field_name,
|
||||||
|
geo_field_type=settings.get('geo_field_type', None))
|
||||||
for k, v in default_args.iteritems(): settings['procedure_args'].setdefault(k, v)
|
for k, v in default_args.iteritems(): settings['procedure_args'].setdefault(k, v)
|
||||||
else:
|
else:
|
||||||
geo_field = settings['geo_field']
|
geo_field = settings['geo_field']
|
||||||
|
|
|
@ -27,6 +27,12 @@ class State(models.Model):
|
||||||
objects = models.GeoManager()
|
objects = models.GeoManager()
|
||||||
def __unicode__(self): return self.name
|
def __unicode__(self): return self.name
|
||||||
|
|
||||||
|
class Track(models.Model):
|
||||||
|
name = models.CharField(max_length=30)
|
||||||
|
line = models.LineStringField()
|
||||||
|
objects = models.GeoManager()
|
||||||
|
def __unicode__(self): return self.name
|
||||||
|
|
||||||
if not spatialite:
|
if not spatialite:
|
||||||
class Feature(models.Model):
|
class Feature(models.Model):
|
||||||
name = models.CharField(max_length=20)
|
name = models.CharField(max_length=20)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.contrib.gis.tests.utils import \
|
||||||
mysql, oracle, postgis, spatialite
|
mysql, oracle, postgis, spatialite
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from models import Country, City, PennsylvaniaCity, State
|
from models import Country, City, PennsylvaniaCity, State, Track
|
||||||
|
|
||||||
if not spatialite:
|
if not spatialite:
|
||||||
from models import Feature, MinusOneSRID
|
from models import Feature, MinusOneSRID
|
||||||
|
@ -687,6 +687,33 @@ class GeoModelTest(TestCase):
|
||||||
ref = fromstr('MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))')
|
ref = fromstr('MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))')
|
||||||
self.failUnless(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, tol))
|
self.failUnless(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, tol))
|
||||||
|
|
||||||
|
@no_mysql
|
||||||
|
@no_spatialite
|
||||||
|
def test28_reverse(self):
|
||||||
|
"Testing GeoQuerySet.reverse()."
|
||||||
|
coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ]
|
||||||
|
Track.objects.create(name='Foo', line=LineString(coords))
|
||||||
|
t = Track.objects.reverse().get(name='Foo')
|
||||||
|
coords.reverse()
|
||||||
|
self.assertEqual(tuple(coords), t.reverse.coords)
|
||||||
|
if oracle:
|
||||||
|
self.assertRaises(TypeError, State.objects.reverse)
|
||||||
|
|
||||||
|
@no_mysql
|
||||||
|
@no_oracle
|
||||||
|
@no_spatialite
|
||||||
|
def test29_force_rhr(self):
|
||||||
|
"Testing GeoQuerySet.force_rhr()."
|
||||||
|
rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ),
|
||||||
|
( (1, 1), (1, 3), (3, 1), (1, 1) ),
|
||||||
|
)
|
||||||
|
rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ),
|
||||||
|
( (1, 1), (3, 1), (1, 3), (1, 1) ),
|
||||||
|
)
|
||||||
|
State.objects.create(name='Foo', poly=Polygon(*rings))
|
||||||
|
s = State.objects.force_rhr().get(name='Foo')
|
||||||
|
self.assertEqual(rhr_rings, s.force_rhr.coords)
|
||||||
|
|
||||||
from test_feeds import GeoFeedTest
|
from test_feeds import GeoFeedTest
|
||||||
from test_regress import GeoRegressionTests
|
from test_regress import GeoRegressionTests
|
||||||
from test_sitemaps import GeoSitemapTest
|
from test_sitemaps import GeoSitemapTest
|
||||||
|
|
Loading…
Reference in New Issue