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:
parent
4ffbddf92d
commit
2694fffcc0
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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.')
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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('')
|
||||
|
Loading…
x
Reference in New Issue
Block a user