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

gis: gdal:

(1) Added the `field_widths` and `field_precision` properties to Layer with patch from tlp.
 (2) Field definition is now passed into the Feature from the Layer.
 (3) Fixed memory leak issue with Feature not being properly deleted.
 (4) OGR_L_GetNextFeature() now used for iteration on Layer.
 (5) Added the `gdal_version`, `gdal_full_version`, and `gdal_release_date` functions.
 (6) Made all initial pointers None instead of 0.


git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6639 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-11-04 00:48:10 +00:00
parent 4ffbddf92d
commit 2694fffcc0
8 changed files with 64 additions and 24 deletions

View File

@ -26,6 +26,7 @@
try:
from django.contrib.gis.gdal.driver import Driver
from django.contrib.gis.gdal.datasource import DataSource
from django.contrib.gis.gdal.libgdal import gdal_version, gdal_full_version, gdal_release_date
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
from django.contrib.gis.gdal.geometries import OGRGeometry
HAS_GDAL = True

View File

@ -55,7 +55,7 @@ class DataSource(object):
#### Python 'magic' routines ####
def __init__(self, ds_input, ds_driver=False):
self._ds = 0 # Initially NULL
self._ds = None # Initially NULL
# Registering all the drivers, this needs to be done
# _before_ we try to open up a data source.

View File

@ -27,7 +27,7 @@ class Driver(object):
if isinstance(input, StringType):
# If a string name of the driver was passed in
self._dr = 0 # Initially NULL
self._dr = None # Initially NULL
self._register()
# Checking the alias dictionary (case-insensitive) to see if an alias

View File

@ -17,18 +17,18 @@ class Feature(object):
"A class that wraps an OGR Feature, needs to be instantiated from a Layer object."
#### Python 'magic' routines ####
def __init__(self, f):
def __init__(self, feat, fdefn):
"Needs a C pointer (Python integer in ctypes) in order to initialize."
self._feat = 0 # Initially NULL
self._fdefn = 0
if not f:
self._feat = None # Initially NULL
self._fdefn = None
if not feat or not fdefn:
raise OGRException('Cannot create OGR Feature, invalid pointer given.')
self._feat = f
self._fdefn = lgdal.OGR_F_GetDefnRef(f)
self._feat = feat
self._fdefn = fdefn
def __del__(self):
"Releases a reference to this object."
if self._fdefn: lgdal.OGR_FD_Release(self._fdefn)
if self._feat: lgdal.OGR_F_Destroy(self._feat)
def __getitem__(self, index):
"Gets the Field at the specified index."
@ -91,7 +91,7 @@ class Feature(object):
raise OGRException('Cannot retrieve Geometry from the feature.')
# Attempting to retrieve the Spatial Reference for the geometry.
srs_ptr = lgdal.OGR_G_GetSpatialReference(geom_ptr)
srs_ptr = lgdal.OSRClone(lgdal.OGR_G_GetSpatialReference(geom_ptr))
if srs_ptr:
srs = SpatialReference(srs_ptr, 'ogr')
else:

View File

@ -12,7 +12,7 @@ class Field(object):
#### Python 'magic' routines ####
def __init__(self, fld, val=''):
"Needs a C pointer (Python integer in ctypes) in order to initialize."
self._fld = 0 # Initially NULL
self._fld = None # Initially NULL
if not fld:
raise OGRException('Cannot create OGR Field, invalid pointer given.')

View File

@ -27,8 +27,8 @@ class Layer(object):
#### Python 'magic' routines ####
def __init__(self, l):
"Needs a C pointer (Python/ctypes integer) in order to initialize."
self._layer = 0 # Initially NULL
self._ldefn = 0
self._layer = None # Initially NULL
self._ldefn = None
if not l:
raise OGRException, 'Cannot create Layer, invalid pointer given'
self._layer = l
@ -36,30 +36,27 @@ class Layer(object):
def __getitem__(self, index):
"Gets the Feature at the specified index."
def make_feature(offset):
return Feature(lgdal.OGR_L_GetFeature(self._layer,
c_long(offset)))
end = self.num_feat
if not isinstance(index, (slice, int)):
raise TypeError
end = self.num_feat
if isinstance(index,int):
# An integer index was given
if index < 0:
index = end - index
if index < 0 or index >= self.num_feat:
raise OGRIndexError, 'index out of range'
return make_feature(index)
return self._make_feature(index)
else:
# A slice was given
start, stop, stride = index.indices(end)
return [make_feature(offset) for offset in range(start,stop,stride)]
return [self._make_feature(offset) for offset in range(start,stop,stride)]
def __iter__(self):
"Iterates over each Feature in the Layer."
#TODO: is OGR's GetNextFeature faster here?
# ResetReading() must be called before iteration is to begin.
lgdal.OGR_L_ResetReading(self._layer)
for i in range(self.num_feat):
yield self.__getitem__(i)
yield Feature(lgdal.OGR_L_GetNextFeature(self._layer), self._ldefn)
def __len__(self):
"The length is the number of features."
@ -69,6 +66,10 @@ class Layer(object):
"The string name of the layer."
return self.name
def _make_feature(self, offset):
"Helper routine for __getitem__ that makes a feature from an offset."
return Feature(lgdal.OGR_L_GetFeature(self._layer, c_long(offset)), self._ldefn)
#### Layer properties ####
@property
def extent(self):
@ -112,6 +113,18 @@ class Layer(object):
return [ string_at(lgdal.OGR_Fld_GetNameRef(lgdal.OGR_FD_GetFieldDefn(self._ldefn, i)))
for i in xrange(self.num_fields) ]
@property
def field_widths(self):
"Returns a list of the maximum field widths for the features."
return [ int(lgdal.OGR_Fld_GetWidth(lgdal.OGR_FD_GetFieldDefn(self._ldefn, i)))
for i in xrange(self.num_fields) ]
@property
def field_precisions(self):
"Returns the field precisions for the features."
return [ int(lgdal.OGR_Fld_GetPrecision(lgdal.OGR_FD_GetFieldDefn(self._ldefn, i)))
for i in xrange(self.num_fields) ]
#### Layer Methods ####
def get_fields(self, field_name):
"""Returns a list containing the given field name for every Feature

View File

@ -1,5 +1,5 @@
import os, sys
from ctypes import CDLL
from ctypes import CDLL, string_at
from django.contrib.gis.gdal.error import OGRException
if os.name == 'nt':
@ -21,3 +21,29 @@ else:
# This loads the GDAL/OGR C library
lgdal = CDLL(lib_name)
#### Version-information functions. ####
def _version_info(key):
"Returns GDAL library version information with the given key."
buf = lgdal.GDALVersionInfo(key)
if buf: return string_at(buf)
def gdal_version():
"Returns only the GDAL version number information."
return _version_info('RELEASE_NAME')
def gdal_full_version():
"Returns the full GDAL version information."
return _version_info('')
def gdal_release_date(date=False):
"""
Returns the release date in a string format, e.g, "2007/06/27".
If the date keyword argument is set to True, a Python datetime object
will be returned instead.
"""
from datetime import datetime
rel = _version_info('RELEASE_DATE')
yy, mm, dd = map(int, (rel[0:4], rel[4:6], rel[6:8]))
d = datetime(yy, mm, dd)
if date: return d
else: return d.strftime('%Y/%m/%d')

View File

@ -82,7 +82,7 @@ class SpatialReference(object):
def __init__(self, srs_input='', srs_type='wkt'):
"Creates a spatial reference object from the given OGC Well Known Text (WKT)."
self._srs = 0 # Initially NULL
self._srs = None # Initially NULL
# Creating an initial empty string buffer.
buf = c_char_p('')