1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: gdal: Fixed memory leak introduced in the refactor caused by unnecessary cloning of SpatialReference objects from Features; fixed windows-compatibility issues (no error code returned by some destruction routines by windows libraries); OFTDate/Time fields return None if invalid date is encountered (thanks tlp).

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6707 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-11-20 15:10:20 +00:00
parent 20a1c654f0
commit f23597cdd7
6 changed files with 32 additions and 23 deletions

View File

@ -33,7 +33,12 @@ class Feature(object):
if self._ptr: destroy_feature(self._ptr)
def __getitem__(self, index):
"Gets the Field at the specified index."
"""
Gets the Field object at the specified index, which may be either
an integer or the Field's string label. Note that the Field object
is not the field's _value_ -- use the `get` method instead to
retrieve the value (e.g. an integer) instead of a Field instance.
"""
if isinstance(index, basestring):
i = self.index(index)
else:
@ -86,16 +91,8 @@ class Feature(object):
"Returns the OGR Geometry for this Feature."
# Retrieving the geometry pointer for the feature.
geom_ptr = get_feat_geom_ref(self._ptr)
return OGRGeometry(clone_geom(geom_ptr))
# Attempting to retrieve the Spatial Reference for the geometry.
try:
srs_ptr = get_geom_srs(geom_ptr)
srs = SpatialReference(clone_srs(srs_ptr))
except OGRException:
srs = None
# Geometry is cloned so the feature isn't invalidated.
return OGRGeometry(clone_geom(geom_ptr), srs)
@property
def geom_type(self):
"Returns the OGR Geometry Type for this Feture."
@ -105,8 +102,8 @@ class Feature(object):
def get(self, field):
"""
Returns the value of the field, instead of an instance of the Field
object. May take a string of the field name or a Field object as
parameters.
object. May take a string of the field name or a Field object as
parameters.
"""
field_name = getattr(field, 'name', field)
return self[field_name].value

View File

@ -128,7 +128,10 @@ class OFTDate(Field):
def value(self):
"Returns a Python `date` object for the OFTDate field."
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
return date(yy.value, mm.value, dd.value)
try:
return date(yy.value, mm.value, dd.value)
except ValueError:
return None
class OFTDateTime(Field):
@property
@ -139,14 +142,20 @@ class OFTDateTime(Field):
# See http://lists.maptools.org/pipermail/gdal-dev/2006-February/007990.html
# The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
# 100=GMT, 104=GMT+1, 80=GMT-5, etc.
return datetime(yy.value, mm.value, dd.value, hh.value, mn.value, ss.value)
try:
return datetime(yy.value, mm.value, dd.value, hh.value, mn.value, ss.value)
except ValueError:
return None
class OFTTime(Field):
@property
def value(self):
"Returns a Python `time` object for this OFTTime field."
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
return time(hh.value, mn.value, ss.value)
try:
return time(hh.value, mn.value, ss.value)
except ValueError:
return None
# List fields are also just subclasses
class OFTIntegerList(Field): pass

View File

@ -6,6 +6,7 @@ from django.contrib.gis.gdal.error import OGRException
if os.name == 'nt':
# Windows NT shared library
lib_name = 'libgdal-1.dll'
errcheck_flag = False
elif os.name == 'posix':
platform = os.uname()[0]
if platform == 'Darwin':
@ -14,6 +15,7 @@ elif os.name == 'posix':
else:
# Attempting to use .so extension for all other platforms.
lib_name = 'libgdal.so'
errcheck_flag = True
else:
raise OGRException('Unsupported OS "%s"' % os.name)

View File

@ -5,7 +5,7 @@
"""
from ctypes import c_char_p, c_int, c_long, c_void_p, POINTER
from django.contrib.gis.gdal.envelope import OGREnvelope
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.libgdal import lgdal, errcheck_flag
from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, geom_output, int_output, \
srs_output, void_output, voidptr_output
@ -47,7 +47,7 @@ get_field_defn = voidptr_output(lgdal.OGR_FD_GetFieldDefn, [c_void_p, c_int])
### Feature Routines ###
clone_feature = voidptr_output(lgdal.OGR_F_Clone, [c_void_p])
destroy_feature = void_output(lgdal.OGR_F_Destroy, [c_void_p])
destroy_feature = void_output(lgdal.OGR_F_Destroy, [c_void_p], errcheck=errcheck_flag)
feature_equal = int_output(lgdal.OGR_F_Equal, [c_void_p, c_void_p])
get_feat_geom_ref = geom_output(lgdal.OGR_F_GetGeometryRef, [c_void_p])
get_feat_field_count = int_output(lgdal.OGR_F_GetFieldCount, [c_void_p])

View File

@ -1,6 +1,6 @@
from ctypes import c_char, c_char_p, c_double, c_int, c_ubyte, c_void_p, POINTER
from django.contrib.gis.gdal.envelope import OGREnvelope
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.libgdal import lgdal, errcheck_flag
from django.contrib.gis.gdal.prototypes.errcheck import check_bool, check_envelope
from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, geom_output, int_output, \
@ -72,7 +72,7 @@ get_geom_name = const_string_output(lgdal.OGR_G_GetGeometryName, [c_void_p])
get_geom_type = int_output(lgdal.OGR_G_GetGeometryType, [c_void_p])
get_point_count = int_output(lgdal.OGR_G_GetPointCount, [c_void_p])
get_point = void_output(lgdal.OGR_G_GetPoint, [c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)], errcheck=False)
geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p])
geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p], errcheck=errcheck_flag)
# Topology routines.
ogr_contains = topology_func(lgdal.OGR_G_Contains)

View File

@ -1,5 +1,5 @@
from ctypes import c_char_p, c_int, c_void_p, POINTER
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.libgdal import lgdal, errcheck_flag
from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, int_output, \
srs_output, string_output, void_output
@ -22,8 +22,9 @@ def units_func(f):
# Creation & destruction.
clone_srs = srs_output(lgdal.OSRClone, [c_void_p])
new_srs = srs_output(lgdal.OSRNewSpatialReference, [c_char_p])
release_srs = void_output(lgdal.OSRRelease, [c_void_p])
srs_validate = void_output(lgdal.OSRValidate, [c_void_p], errcheck=True)
release_srs = void_output(lgdal.OSRRelease, [c_void_p], errcheck=errcheck_flag)
destroy_srs = void_output(lgdal.OSRDestroySpatialReference, [c_void_p], errcheck=errcheck_flag)
srs_validate = void_output(lgdal.OSRValidate, [c_void_p])
# Getting the semi_major, semi_minor, and flattening functions.
semi_major = srs_double(lgdal.OSRGetSemiMajor)
@ -67,4 +68,4 @@ isprojected = int_output(lgdal.OSRIsProjected, [c_void_p])
# Coordinate transformation
new_ct= srs_output(lgdal.OCTNewCoordinateTransformation, [c_void_p, c_void_p])
destroy_ct = void_output(lgdal.OCTDestroyCoordinateTransformation, [c_void_p])
destroy_ct = void_output(lgdal.OCTDestroyCoordinateTransformation, [c_void_p], errcheck=errcheck_flag)