diff options
author | ttt | 2017-05-13 00:29:47 +0530 |
---|---|---|
committer | ttt | 2017-05-13 00:29:47 +0530 |
commit | abf599be33b383a6a5baf9493093b2126a622ac8 (patch) | |
tree | 4c5ab6e0d935d5e65fabcf0258e4a00dd20a5afa /lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py | |
download | SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.gz SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.bz2 SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.zip |
added all server files
Diffstat (limited to 'lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py')
-rw-r--r-- | lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py b/lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py new file mode 100644 index 0000000..7f935cd --- /dev/null +++ b/lib/python2.7/site-packages/django/contrib/gis/gdal/layer.py @@ -0,0 +1,218 @@ +# Needed ctypes routines +from ctypes import c_double, byref + +# Other GDAL imports. +from django.contrib.gis.gdal.base import GDALBase +from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope +from django.contrib.gis.gdal.error import OGRException, OGRIndexError, SRSException +from django.contrib.gis.gdal.feature import Feature +from django.contrib.gis.gdal.field import OGRFieldTypes +from django.contrib.gis.gdal.geomtype import OGRGeomType +from django.contrib.gis.gdal.geometries import OGRGeometry +from django.contrib.gis.gdal.srs import SpatialReference + +# GDAL ctypes function prototypes. +from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api, srs as srs_api + +from django.utils.encoding import force_bytes, force_text +from django.utils import six +from django.utils.six.moves import xrange + +# For more information, see the OGR C API source code: +# http://www.gdal.org/ogr/ogr__api_8h.html +# +# The OGR_L_* routines are relevant here. +class Layer(GDALBase): + "A class that wraps an OGR Layer, needs to be instantiated from a DataSource object." + + #### Python 'magic' routines #### + def __init__(self, layer_ptr, ds): + """ + Initializes on an OGR C pointer to the Layer and the `DataSource` object + that owns this layer. The `DataSource` object is required so that a + reference to it is kept with this Layer. This prevents garbage + collection of the `DataSource` while this Layer is still active. + """ + if not layer_ptr: + raise OGRException('Cannot create Layer, invalid pointer given') + self.ptr = layer_ptr + self._ds = ds + self._ldefn = capi.get_layer_defn(self._ptr) + # Does the Layer support random reading? + self._random_read = self.test_capability(b'RandomRead') + + def __getitem__(self, index): + "Gets the Feature at the specified index." + if isinstance(index, six.integer_types): + # An integer index was given -- we cannot do a check based on the + # number of features because the beginning and ending feature IDs + # are not guaranteed to be 0 and len(layer)-1, respectively. + if index < 0: raise OGRIndexError('Negative indices are not allowed on OGR Layers.') + return self._make_feature(index) + elif isinstance(index, slice): + # A slice was given + start, stop, stride = index.indices(self.num_feat) + return [self._make_feature(fid) for fid in xrange(start, stop, stride)] + else: + raise TypeError('Integers and slices may only be used when indexing OGR Layers.') + + def __iter__(self): + "Iterates over each Feature in the Layer." + # ResetReading() must be called before iteration is to begin. + capi.reset_reading(self._ptr) + for i in xrange(self.num_feat): + yield Feature(capi.get_next_feature(self._ptr), self) + + def __len__(self): + "The length is the number of features." + return self.num_feat + + def __str__(self): + "The string name of the layer." + return self.name + + def _make_feature(self, feat_id): + """ + Helper routine for __getitem__ that constructs a Feature from the given + Feature ID. If the OGR Layer does not support random-access reading, + then each feature of the layer will be incremented through until the + a Feature is found matching the given feature ID. + """ + if self._random_read: + # If the Layer supports random reading, return. + try: + return Feature(capi.get_feature(self.ptr, feat_id), self) + except OGRException: + pass + else: + # Random access isn't supported, have to increment through + # each feature until the given feature ID is encountered. + for feat in self: + if feat.fid == feat_id: return feat + # Should have returned a Feature, raise an OGRIndexError. + raise OGRIndexError('Invalid feature id: %s.' % feat_id) + + #### Layer properties #### + @property + def extent(self): + "Returns the extent (an Envelope) of this layer." + env = OGREnvelope() + capi.get_extent(self.ptr, byref(env), 1) + return Envelope(env) + + @property + def name(self): + "Returns the name of this layer in the Data Source." + name = capi.get_fd_name(self._ldefn) + return force_text(name, self._ds.encoding, strings_only=True) + + @property + def num_feat(self, force=1): + "Returns the number of features in the Layer." + return capi.get_feature_count(self.ptr, force) + + @property + def num_fields(self): + "Returns the number of fields in the Layer." + return capi.get_field_count(self._ldefn) + + @property + def geom_type(self): + "Returns the geometry type (OGRGeomType) of the Layer." + return OGRGeomType(capi.get_fd_geom_type(self._ldefn)) + + @property + def srs(self): + "Returns the Spatial Reference used in this Layer." + try: + ptr = capi.get_layer_srs(self.ptr) + return SpatialReference(srs_api.clone_srs(ptr)) + except SRSException: + return None + + @property + def fields(self): + """ + Returns a list of string names corresponding to each of the Fields + available in this Layer. + """ + return [force_text(capi.get_field_name(capi.get_field_defn(self._ldefn, i)), + self._ds.encoding, strings_only=True) + for i in xrange(self.num_fields)] + + @property + def field_types(self): + """ + Returns a list of the types of fields in this Layer. For example, + the list [OFTInteger, OFTReal, OFTString] would be returned for + an OGR layer that had an integer, a floating-point, and string + fields. + """ + return [OGRFieldTypes[capi.get_field_type(capi.get_field_defn(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 [capi.get_field_width(capi.get_field_defn(self._ldefn, i)) + for i in xrange(self.num_fields)] + + @property + def field_precisions(self): + "Returns the field precisions for the features." + return [capi.get_field_precision(capi.get_field_defn(self._ldefn, i)) + for i in xrange(self.num_fields)] + + def _get_spatial_filter(self): + try: + return OGRGeometry(geom_api.clone_geom(capi.get_spatial_filter(self.ptr))) + except OGRException: + return None + + def _set_spatial_filter(self, filter): + if isinstance(filter, OGRGeometry): + capi.set_spatial_filter(self.ptr, filter.ptr) + elif isinstance(filter, (tuple, list)): + if not len(filter) == 4: + raise ValueError('Spatial filter list/tuple must have 4 elements.') + # Map c_double onto params -- if a bad type is passed in it + # will be caught here. + xmin, ymin, xmax, ymax = map(c_double, filter) + capi.set_spatial_filter_rect(self.ptr, xmin, ymin, xmax, ymax) + elif filter is None: + capi.set_spatial_filter(self.ptr, None) + else: + raise TypeError('Spatial filter must be either an OGRGeometry instance, a 4-tuple, or None.') + + spatial_filter = property(_get_spatial_filter, _set_spatial_filter) + + #### Layer Methods #### + def get_fields(self, field_name): + """ + Returns a list containing the given field name for every Feature + in the Layer. + """ + if not field_name in self.fields: + raise OGRException('invalid field name: %s' % field_name) + return [feat.get(field_name) for feat in self] + + def get_geoms(self, geos=False): + """ + Returns a list containing the OGRGeometry for every Feature in + the Layer. + """ + if geos: + from django.contrib.gis.geos import GEOSGeometry + return [GEOSGeometry(feat.geom.wkb) for feat in self] + else: + return [feat.geom for feat in self] + + def test_capability(self, capability): + """ + Returns a bool indicating whether the this Layer supports the given + capability (a string). Valid capability strings include: + 'RandomRead', 'SequentialWrite', 'RandomWrite', 'FastSpatialFilter', + 'FastFeatureCount', 'FastGetExtent', 'CreateField', 'Transactions', + 'DeleteFeature', and 'FastSetNextByIndex'. + """ + return bool(capi.test_capability(self.ptr, force_bytes(capability))) |