Django

Code

root/django/branches/gis/django/contrib/gis/db/models/proxy.py

Revision 7641, 2.4 kB (checked in by jbronn, 5 months ago)

gis: Refactor of the GeoQuerySet; new features include:

(1) Creation of internal API that eases generation of GeoQuerySet methods.
(2) GeoQuerySet.distance now returns Distance objects instead of floats.
(3) Added the new GeoQuerySet methods: area, centroid, difference, envelope, intersection, length, make_line, mem_size, num_geom, num_points, perimeter, point_on_surface, scale, svg, sym_difference, translate, union.
(4) The model_att keyword may be used to customize the attribute that GeoQuerySet methods attach output to.
(5) Geographic distance lookups and GeoQuerySet.distance calls now use ST_distance_sphere by default (performance benefits far outweigh small loss in accuracy); ST_distance_spheroid may still be used by specifying an option.
(6) GeoQuerySet methods may now operate accross ForeignKey? relations specified via the field_name keyword (but this does not work on Oracle).
(7) Area now has the same units of measure as Distance.

Backward Incompatibilites:

  • The aggregate union method is now known as unionagg.
  • The field_name keyword used for GeoQuerySet methods may no longer be specified via positional arguments.
  • Distance objects returned instead of floats from GeoQuerySet.distance.
  • ST_Distance_sphere used by default for geographic distance calculations.
Line 
1 """
2  The GeometryProxy object, allows for lazy-geometries.  The proxy uses
3  Python descriptors for instantiating and setting Geometry objects
4  corresponding to geographic model fields.
5
6  Thanks to Robert Coup for providing this functionality (see #4322).
7 """
8
9 from types import NoneType, StringType, UnicodeType
10
11 class GeometryProxy(object):
12     def __init__(self, klass, field):
13         """
14         Proxy initializes on the given Geometry class (not an instance) and
15         the GeometryField.
16         """
17         self._field = field
18         self._klass = klass
19      
20     def __get__(self, obj, type=None):
21         """
22         This accessor retrieves the geometry, initializing it using the geometry
23         class specified during initialization and the HEXEWKB value of the field. 
24         Currently, only GEOS or OGR geometries are supported.
25         """
26         # Getting the value of the field.
27         geom_value = obj.__dict__[self._field.attname]
28        
29         if isinstance(geom_value, self._klass):
30             geom = geom_value
31         elif (geom_value is None) or (geom_value==''):
32             geom = None
33         else:
34             # Otherwise, a Geometry object is built using the field's contents,
35             # and the model's corresponding attribute is set.
36             geom = self._klass(geom_value)
37             setattr(obj, self._field.attname, geom)
38         return geom
39      
40     def __set__(self, obj, value):
41         """
42         This accessor sets the proxied geometry with the geometry class
43         specified during initialization.  Values of None, HEXEWKB, or WKT may
44         be used to set the geometry as well.
45         """
46         # The OGC Geometry type of the field.
47         gtype = self._field._geom
48        
49         # The geometry type must match that of the field -- unless the
50         # general GeometryField is used.
51         if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'):
52             # Assigning the SRID to the geometry.
53             if value.srid is None: value.srid = self._field._srid
54         elif isinstance(value, (NoneType, StringType, UnicodeType)):
55             # Set with None, WKT, or HEX
56             pass
57         else:
58             raise TypeError('cannot set %s GeometryProxy with value of type: %s' % (obj.__class__.__name__, type(value)))
59
60         # Setting the objects dictionary with the value, and returning.
61         obj.__dict__[self._field.attname] = value
62         return value
Note: See TracBrowser for help on using the browser.