web/lib/django/contrib/gis/geos/coordseq.py
changeset 0 0d40e90630ef
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 """
       
     2  This module houses the GEOSCoordSeq object, which is used internally
       
     3  by GEOSGeometry to house the actual coordinates of the Point,
       
     4  LineString, and LinearRing geometries.
       
     5 """
       
     6 from ctypes import c_double, c_uint, byref
       
     7 from django.contrib.gis.geos.base import GEOSBase, numpy
       
     8 from django.contrib.gis.geos.error import GEOSException, GEOSIndexError
       
     9 from django.contrib.gis.geos.libgeos import CS_PTR
       
    10 from django.contrib.gis.geos import prototypes as capi
       
    11 
       
    12 class GEOSCoordSeq(GEOSBase):
       
    13     "The internal representation of a list of coordinates inside a Geometry."
       
    14 
       
    15     ptr_type = CS_PTR
       
    16 
       
    17     #### Python 'magic' routines ####
       
    18     def __init__(self, ptr, z=False):
       
    19         "Initializes from a GEOS pointer."
       
    20         if not isinstance(ptr, CS_PTR):
       
    21             raise TypeError('Coordinate sequence should initialize with a CS_PTR.')
       
    22         self._ptr = ptr
       
    23         self._z = z
       
    24 
       
    25     def __iter__(self):
       
    26         "Iterates over each point in the coordinate sequence."
       
    27         for i in xrange(self.size):
       
    28             yield self[i]
       
    29 
       
    30     def __len__(self):
       
    31         "Returns the number of points in the coordinate sequence."
       
    32         return int(self.size)
       
    33 
       
    34     def __str__(self):
       
    35         "Returns the string representation of the coordinate sequence."
       
    36         return str(self.tuple)
       
    37 
       
    38     def __getitem__(self, index):
       
    39         "Returns the coordinate sequence value at the given index."
       
    40         coords = [self.getX(index), self.getY(index)]
       
    41         if self.dims == 3 and self._z:
       
    42             coords.append(self.getZ(index))
       
    43         return tuple(coords)
       
    44 
       
    45     def __setitem__(self, index, value):
       
    46         "Sets the coordinate sequence value at the given index."
       
    47         # Checking the input value
       
    48         if isinstance(value, (list, tuple)):
       
    49             pass
       
    50         elif numpy and isinstance(value, numpy.ndarray):
       
    51             pass
       
    52         else:
       
    53             raise TypeError('Must set coordinate with a sequence (list, tuple, or numpy array).')
       
    54         # Checking the dims of the input
       
    55         if self.dims == 3 and self._z:
       
    56             n_args = 3
       
    57             set_3d = True
       
    58         else:
       
    59             n_args = 2
       
    60             set_3d = False
       
    61         if len(value) != n_args:
       
    62             raise TypeError('Dimension of value does not match.')
       
    63         # Setting the X, Y, Z
       
    64         self.setX(index, value[0])
       
    65         self.setY(index, value[1])
       
    66         if set_3d: self.setZ(index, value[2])
       
    67 
       
    68     #### Internal Routines ####
       
    69     def _checkindex(self, index):
       
    70         "Checks the given index."
       
    71         sz = self.size
       
    72         if (sz < 1) or (index < 0) or (index >= sz):
       
    73             raise GEOSIndexError('invalid GEOS Geometry index: %s' % str(index))
       
    74 
       
    75     def _checkdim(self, dim):
       
    76         "Checks the given dimension."
       
    77         if dim < 0 or dim > 2:
       
    78             raise GEOSException('invalid ordinate dimension "%d"' % dim)
       
    79 
       
    80     #### Ordinate getting and setting routines ####
       
    81     def getOrdinate(self, dimension, index):
       
    82         "Returns the value for the given dimension and index."
       
    83         self._checkindex(index)
       
    84         self._checkdim(dimension)
       
    85         return capi.cs_getordinate(self.ptr, index, dimension, byref(c_double()))
       
    86 
       
    87     def setOrdinate(self, dimension, index, value):
       
    88         "Sets the value for the given dimension and index."
       
    89         self._checkindex(index)
       
    90         self._checkdim(dimension)
       
    91         capi.cs_setordinate(self.ptr, index, dimension, value)
       
    92 
       
    93     def getX(self, index):
       
    94         "Get the X value at the index."
       
    95         return self.getOrdinate(0, index)
       
    96 
       
    97     def setX(self, index, value):
       
    98         "Set X with the value at the given index."
       
    99         self.setOrdinate(0, index, value)
       
   100 
       
   101     def getY(self, index):
       
   102         "Get the Y value at the given index."
       
   103         return self.getOrdinate(1, index)
       
   104 
       
   105     def setY(self, index, value):
       
   106         "Set Y with the value at the given index."
       
   107         self.setOrdinate(1, index, value)
       
   108 
       
   109     def getZ(self, index):
       
   110         "Get Z with the value at the given index."
       
   111         return self.getOrdinate(2, index)
       
   112 
       
   113     def setZ(self, index, value):
       
   114         "Set Z with the value at the given index."
       
   115         self.setOrdinate(2, index, value)
       
   116 
       
   117     ### Dimensions ###
       
   118     @property
       
   119     def size(self):
       
   120         "Returns the size of this coordinate sequence."
       
   121         return capi.cs_getsize(self.ptr, byref(c_uint()))
       
   122 
       
   123     @property
       
   124     def dims(self):
       
   125         "Returns the dimensions of this coordinate sequence."
       
   126         return capi.cs_getdims(self.ptr, byref(c_uint()))
       
   127 
       
   128     @property
       
   129     def hasz(self):
       
   130         """
       
   131         Returns whether this coordinate sequence is 3D.  This property value is
       
   132         inherited from the parent Geometry.
       
   133         """
       
   134         return self._z
       
   135 
       
   136     ### Other Methods ###
       
   137     def clone(self):
       
   138         "Clones this coordinate sequence."
       
   139         return GEOSCoordSeq(capi.cs_clone(self.ptr), self.hasz)
       
   140 
       
   141     @property
       
   142     def kml(self):
       
   143         "Returns the KML representation for the coordinates."
       
   144         # Getting the substitution string depending on whether the coordinates have
       
   145         #  a Z dimension.
       
   146         if self.hasz: substr = '%s,%s,%s '
       
   147         else: substr = '%s,%s,0 '
       
   148         return '<coordinates>%s</coordinates>' % \
       
   149             ''.join([substr % self[i] for i in xrange(len(self))]).strip()
       
   150 
       
   151     @property
       
   152     def tuple(self):
       
   153         "Returns a tuple version of this coordinate sequence."
       
   154         n = self.size
       
   155         if n == 1: return self[0]
       
   156         else: return tuple([self[i] for i in xrange(n)])