Ticket #4322: gis_lazy_geometries.2.diff

File gis_lazy_geometries.2.diff, 7.1 KB (added by robert.coup@…, 8 years ago)

2nd update

  • django/contrib/gis/db/models/fields/__init__.py

     
    44from django.contrib.gis.oldforms import WKTField
    55from django.utils.functional import curry
    66
     7from django.contrib.gis.db.models.proxy import GeometryProxy
     8
    79#TODO: add db.quotename.
    810
    911# Creates the SQL to add the model to the database.
    10 def _add_geom(geom, srid, style, model, field, dim=2):
     12def _add_geom(geom, srid, null_ok, style, model, field, dim=2):
    1113    # Constructing the AddGeometryColumn(...) command -- the style
    1214    # object is passed in from the management module and is used
    1315    # to syntax highlight the command for 'sqlall'
     
    1921          style.SQL_COLTYPE(geom) + "', " + \
    2022          style.SQL_KEYWORD(str(dim)) + \
    2123          ');'
     24    if not null_ok:
     25        # Add a NOT NULL constraint to the field
     26        sql += '\n' + \
     27            style.SQL_KEYWORD('ALTER TABLE ') + \
     28            style.SQL_TABLE('"' + model + '"') + \
     29            style.SQL_KEYWORD(' ALTER ') + \
     30            style.SQL_FIELD('"' + field + '"') + \
     31            style.SQL_KEYWORD(' SET NOT NULL') + ';'
    2232    return sql
    2333
    2434# Creates an index for the given geometry.
     
    5262        # The SRID for the geometry, defaults to 4326.
    5363        self._srid = srid
    5464
     65        # blank values are bad. We'd prefer NULLs for geometry fields
     66        if 'blank' in kwargs:
     67            kwargs['null'] = kwargs['blank'] or kwargs.get('null',False)
     68
    5569        # Calling the Field initialization function first
    5670        super(GeometryField, self).__init__(**kwargs)
    5771
     
    5973    def contribute_to_class(self, cls, name):
    6074        super(GeometryField, self).contribute_to_class(cls, name)
    6175
     76        # setup for lazy-instantiated GEOSGeometry objects
     77        setattr(cls, self.attname, GeometryProxy(self))
     78
     79        # TODO: These are deprecated now, and issue warnings as such
    6280        # Adding the WKT accessor function for geometry
    6381        setattr(cls, 'get_%s_geos' % self.name, curry(cls._get_GEOM_geos, field=self))
    6482        setattr(cls, 'get_%s_wkt' % self.name, curry(cls._get_GEOM_wkt, field=self))
     
    7694
    7795        # Getting the AddGeometryColumn() SQL necessary to create a PostGIS
    7896        # geometry field.
    79         post_sql = _add_geom(self._geom, self._srid, *args, **kwargs)
     97        post_sql = _add_geom(self._geom, self._srid, self.null, *args, **kwargs)
    8098
    8199        # If the user wants to index this data, then get the indexing SQL as well.
    82100        if self._index:
    83101            return '%s\n%s' % (post_sql, _geom_index(self._geom, *args, **kwargs))
    84102        else:
    85103            return post_sql
    86 
     104           
    87105    def get_db_prep_lookup(self, lookup_type, value):
    88106        """Returns field's value prepared for database lookup; the SRID of the geometry is
    89107        included by default in these queries."""
    90108        if lookup_type in POSTGIS_TERMS:
    91             return ['SRID=%d;%s' % (self._srid, value)]
     109            return [value and ("SRID=%d;%s" % (self.srid,value.wkt)) or None]
    92110        raise TypeError("Field has invalid lookup: %s" % lookup_type)
    93111
    94112    def get_db_prep_save(self, value):
    95113        "Making sure the SRID is included before saving."
    96         return 'SRID=%d;%s' % (self._srid, value)
     114        return value and ("SRID=%d;%s" % (value.srid,value.wkt)) or None
    97115
    98116    def get_manipulator_field_objs(self):
    99117        "Using the WKTField (defined above) to be our manipulator."
  • django/contrib/gis/db/models/GeoMixin.py

     
    1010    # routines are present for instantiations of the models.
    1111    def _get_GEOM_geos(self, field):
    1212        "Gets a GEOS Python object for the geometry."
    13         return GEOSGeometry(getattr(self, field.attname), 'hex')
     13        import warnings
     14        warnings.warn("use model.geometry_field", DeprecationWarning)
     15        return getattr(self, field.attname)
    1416
    1517    def _get_GEOM_wkt(self, field):
    1618        "Gets the WKT of the geometry."
    17         hex = getattr(self, field.attname)
    18         return hex_to_wkt(hex)
     19        import warnings
     20        warnings.warn("use model.geometry_field.wkt", DeprecationWarning)
     21        return getattr(self, field.attname).wkt
    1922
    2023    def _get_GEOM_centroid(self, field):
    2124        "Gets the centroid of the geometry, in WKT."
    22         hex = getattr(self, field.attname)
    23         return centroid(hex)
     25        import warnings
     26        warnings.warn("use model.geometry_field.centroid.wkt", DeprecationWarning)
     27        return getattr(self, field.attname).centroid.wkt
    2428   
    2529    def _get_GEOM_area(self, field):
    2630        "Gets the area of the geometry, in projected units."
    27         hex = getattr(self, field.attname)
    28         return area(hex)
    29 
    30 
     31        import warnings
     32        warnings.warn("use model.geometry_field.area", DeprecationWarning)
     33        return getattr(self, field.attname).area
     34       
  • django/contrib/gis/db/models/proxy.py

     
     1# GEOS Routines
     2from django.contrib.gis.geos import GEOSGeometry, GEOSException
     3
     4class GeometryProxy(object):
     5    def __init__(self, field):
     6        self._field = field
     7   
     8    def __get__(self, obj, type=None):
     9        geom_value = obj.__dict__[self._field.attname]
     10        if (geom_value is None) or (isinstance(geom_value, GEOSGeometry)):
     11            geom = geom_value
     12        else:
     13            # TODO: can we improve this somehow?
     14            # first case is what happens on DB extract
     15            try:
     16                geom = GEOSGeometry(geom_value, "hex")
     17            except GEOSException:
     18                geom = GEOSGeometry(geom_value, "wkt")
     19
     20            setattr(obj, self._field.attname, geom)
     21
     22        if geom and ((geom.srid is None) and (self._field._srid is not None)):
     23            geom.set_srid(self._field._srid)
     24
     25        return geom
     26   
     27    def __set__(self, obj, value):
     28        obj.__dict__[self._field.attname] = value
     29        return value
     30   
     31 No newline at end of file
  • django/contrib/gis/geos/GEOSGeometry.py

     
    127127            g = lgeos.GEOSGeomFromWKT(buf)
    128128        elif geom_type == 'hex':
    129129            # If the geometry is in HEX form.
    130             sz = c_size_t(len(input))
     130            try:
     131                # we do this to catch numbers (eg. 5) being passed in
     132                sz = c_size_t(len(input))
     133            except TypeError:
     134                raise GEOSException, 'Invalid hex given!'
    131135            buf = create_string_buffer(input)
    132136            g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
    133137        elif geom_type == 'geos':
Back to Top