1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +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) if self._ptr: destroy_feature(self._ptr)
def __getitem__(self, index): 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): if isinstance(index, basestring):
i = self.index(index) i = self.index(index)
else: else:
@ -86,15 +91,7 @@ class Feature(object):
"Returns the OGR Geometry for this Feature." "Returns the OGR Geometry for this Feature."
# Retrieving the geometry pointer for the feature. # Retrieving the geometry pointer for the feature.
geom_ptr = get_feat_geom_ref(self._ptr) 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 @property
def geom_type(self): def geom_type(self):

View File

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

View File

@ -6,6 +6,7 @@ from django.contrib.gis.gdal.error import OGRException
if os.name == 'nt': if os.name == 'nt':
# Windows NT shared library # Windows NT shared library
lib_name = 'libgdal-1.dll' lib_name = 'libgdal-1.dll'
errcheck_flag = False
elif os.name == 'posix': elif os.name == 'posix':
platform = os.uname()[0] platform = os.uname()[0]
if platform == 'Darwin': if platform == 'Darwin':
@ -14,6 +15,7 @@ elif os.name == 'posix':
else: else:
# Attempting to use .so extension for all other platforms. # Attempting to use .so extension for all other platforms.
lib_name = 'libgdal.so' lib_name = 'libgdal.so'
errcheck_flag = True
else: else:
raise OGRException('Unsupported OS "%s"' % os.name) 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 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.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 \ from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, geom_output, int_output, \ const_string_output, double_output, geom_output, int_output, \
srs_output, void_output, voidptr_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 ### ### Feature Routines ###
clone_feature = voidptr_output(lgdal.OGR_F_Clone, [c_void_p]) 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]) 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_geom_ref = geom_output(lgdal.OGR_F_GetGeometryRef, [c_void_p])
get_feat_field_count = int_output(lgdal.OGR_F_GetFieldCount, [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 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.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.errcheck import check_bool, check_envelope
from django.contrib.gis.gdal.prototypes.generation import \ from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, geom_output, int_output, \ 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_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_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) 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. # Topology routines.
ogr_contains = topology_func(lgdal.OGR_G_Contains) 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 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 \ from django.contrib.gis.gdal.prototypes.generation import \
const_string_output, double_output, int_output, \ const_string_output, double_output, int_output, \
srs_output, string_output, void_output srs_output, string_output, void_output
@ -22,8 +22,9 @@ def units_func(f):
# Creation & destruction. # Creation & destruction.
clone_srs = srs_output(lgdal.OSRClone, [c_void_p]) clone_srs = srs_output(lgdal.OSRClone, [c_void_p])
new_srs = srs_output(lgdal.OSRNewSpatialReference, [c_char_p]) new_srs = srs_output(lgdal.OSRNewSpatialReference, [c_char_p])
release_srs = void_output(lgdal.OSRRelease, [c_void_p]) release_srs = void_output(lgdal.OSRRelease, [c_void_p], errcheck=errcheck_flag)
srs_validate = void_output(lgdal.OSRValidate, [c_void_p], errcheck=True) 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. # Getting the semi_major, semi_minor, and flattening functions.
semi_major = srs_double(lgdal.OSRGetSemiMajor) semi_major = srs_double(lgdal.OSRGetSemiMajor)
@ -67,4 +68,4 @@ isprojected = int_output(lgdal.OSRIsProjected, [c_void_p])
# Coordinate transformation # Coordinate transformation
new_ct= srs_output(lgdal.OCTNewCoordinateTransformation, [c_void_p, c_void_p]) 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)