Changeset 5478
- Timestamp:
- 06/15/07 01:02:04 (1 year ago)
- Files:
-
- django/branches/gis/django/contrib/gis/gdal/DataSource.py (modified) (6 diffs)
- django/branches/gis/django/contrib/gis/gdal/Driver.py (added)
- django/branches/gis/django/contrib/gis/gdal/Feature.py (modified) (2 diffs)
- django/branches/gis/django/contrib/gis/gdal/Field.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/gdal/__init__.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/gdal/libgdal.py (modified) (2 diffs)
- django/branches/gis/django/contrib/gis/gdal/OGRGeometry.py (modified) (16 diffs)
- django/branches/gis/django/contrib/gis/gdal/SpatialReference.py (modified) (3 diffs)
- django/branches/gis/django/contrib/gis/tests/geometries.py (modified) (2 diffs)
- django/branches/gis/django/contrib/gis/tests/__init__.py (modified) (3 diffs)
- django/branches/gis/django/contrib/gis/tests/test_gdal_driver.py (added)
- django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py (modified) (3 diffs)
- django/branches/gis/django/contrib/gis/tests/test_geos.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis/django/contrib/gis/gdal/DataSource.py
r5397 r5478 7 7 from django.contrib.gis.gdal.OGRError import OGRException, check_err 8 8 from django.contrib.gis.gdal.Layer import Layer 9 from django.contrib.gis.gdal.Driver import Driver 9 10 10 11 """ … … 12 13 an interface for reading vector geometry data from many different file 13 14 formats (including ESRI shapefiles). 15 16 When instantiating a DataSource object, use the filename of a 17 GDAL-supported data source. For example, a SHP file or a 18 TIGER/Line file from the government. 19 20 The ds_driver keyword is used internally when a ctypes pointer 21 is passed in directly. 14 22 15 23 Example: … … 23 31 desc = feature['description'] 24 32 25 More documentation forthcoming. 33 # We can also increment through all of the fields 34 # attached to this feature. 35 for field in feature: 36 # Get the name of the field (e.g. 'description') 37 nm = field.name 38 39 # Get the type (integer) of the field, e.g. 0 => OFTInteger 40 t = field.type 41 42 # Returns the value the field; OFTIntegers return ints, 43 # OFTReal returns floats, all else returns string. 44 val = field.value 26 45 """ 27 46 … … 29 48 # http://www.gdal.org/ogr/ogr__api_8h.html 30 49 # 31 # The OGR_DS * routines are relevant here.50 # The OGR_DS_* routines are relevant here. 32 51 33 52 class DataSource(object): … … 37 56 38 57 #### Python 'magic' routines #### 39 def __init__(self, ds_ file):58 def __init__(self, ds_input, ds_driver=False): 40 59 41 60 # Registering all the drivers, this needs to be done 42 61 # _before_ we try to open up a data source. 43 if not lgdal.OGR RegisterAll():44 raise OGRException, 'Could not register all data source drivers!'62 if not lgdal.OGRGetDriverCount() and not lgdal.OGRRegisterAll(): 63 raise OGRException, 'Could not register all the OGR data source drivers!' 45 64 46 # The data source driver is a void pointer. 47 ds_driver = c_void_p() 65 if isinstance(ds_input, StringType): 48 66 49 # OGROpen will auto-detect the data source type. 50 ds = lgdal.OGROpen(c_char_p(ds_file), c_int(0), byref(ds_driver)) 67 # The data source driver is a void pointer. 68 ds_driver = c_void_p() 69 70 # OGROpen will auto-detect the data source type. 71 ds = lgdal.OGROpen(c_char_p(ds_input), c_int(0), byref(ds_driver)) 72 elif isinstance(ds_input, c_void_p) and isinstance(ds_driver, c_void_p): 73 ds = ds_input 74 else: 75 raise OGRException, 'Invalid data source input type: %s' % str(type(ds_input)) 51 76 52 77 # Raise an exception if the returned pointer is NULL 53 78 if not ds: 54 79 self._ds = False 55 raise OGRException, 'Invalid data source file "%s"' % ds_ file80 raise OGRException, 'Invalid data source file "%s"' % ds_input 56 81 else: 57 82 self._ds = ds 58 self._driver = ds_driver83 self._driver = Driver(ds_driver) 59 84 60 85 def __del__(self): … … 84 109 def __str__(self): 85 110 "Returns OGR GetName and Driver for the Data Source." 86 return '%s (%s)' % (self.name, s elf.driver)111 return '%s (%s)' % (self.name, str(self.driver)) 87 112 88 113 #### DataSource Properties #### 89 114 @property 90 115 def driver(self): 91 "Returns the name of the data source driver."92 return s tring_at(lgdal.OGR_Dr_GetName(self._driver))116 "Returns the Driver object for this Data Source." 117 return self._driver 93 118 94 119 @property django/branches/gis/django/contrib/gis/gdal/Feature.py
r5397 r5478 1 1 # types and ctypes 2 import types 2 from types import StringType 3 3 from ctypes import c_char_p, c_int, string_at 4 4 … … 32 32 def __getitem__(self, index): 33 33 "Gets the Field at the specified index." 34 if isinstance(index, types.StringType):34 if isinstance(index, StringType): 35 35 i = self.index(index) 36 36 else: django/branches/gis/django/contrib/gis/gdal/Field.py
r5397 r5478 9 9 # The OGR_Fld_* routines are relevant here. 10 10 class Field(object): 11 "A class that wraps an OGR Field ."11 "A class that wraps an OGR Field, needs to be instantiated from a Feature object." 12 12 13 13 _fld = 0 # Initially NULL django/branches/gis/django/contrib/gis/gdal/__init__.py
r5397 r5478 1 from Driver import Driver 1 2 from DataSource import DataSource 2 3 from SpatialReference import SpatialReference, CoordTransform django/branches/gis/django/contrib/gis/gdal/libgdal.py
r5397 r5478 1 1 import os, sys 2 2 from ctypes import CDLL 3 from django.contrib.gis.gdal.OGRError import OGRException 3 4 4 5 if os.name == 'nt': 5 # Windows NT library6 # Windows NT shared library 6 7 lib_name = 'libgdal-1.dll' 7 8 elif os.name == 'posix': … … 11 12 lib_name = 'libgdal.so' 12 13 elif platform == 'Darwin': 13 # Mac OSX Shared Library14 # Mac OSX shared library 14 15 lib_name = 'libgdal.dylib' 15 16 else: 16 raise GDALException, 'Unknown POSIX platform "%s"' % platform17 raise OGRException, 'Unknown POSIX platform "%s"' % platform 17 18 else: 18 raise GDALException, 'Unsupported OS "%s"' % os.name19 raise OGRException, 'Unsupported OS "%s"' % os.name 19 20 20 # Th e GDALC library21 # This loads the GDAL/OGR C library 21 22 lgdal = CDLL(lib_name) 22 23 django/branches/gis/django/contrib/gis/gdal/OGRGeometry.py
r5397 r5478 1 1 # types & ctypes 2 from types import StringType 3 from ctypes import \ 4 byref, string_at, create_string_buffer, POINTER, \ 5 c_char_p, c_double, c_int, c_void_p 2 from types import IntType, StringType 3 from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p 6 4 7 5 # Getting the GDAL C library and error checking facilities … … 9 7 from django.contrib.gis.gdal.OGRError import check_err, OGRException 10 8 from django.contrib.gis.gdal.SpatialReference import SpatialReference, CoordTransform 9 10 """ 11 The OGRGeometry is a wrapper for using the OGR Geometry class 12 (see http://www.gdal.org/ogr/classOGRGeometry.html). OGRGeometry 13 may be instantiated when reading geometries from OGR Data Sources 14 (e.g. SHP files), or when given OGC WKT (a string). 15 16 While the 'full' API is not present yet, the API is "pythonic" unlike 17 the traditional and "next-generation" OGR Python bindings. One major 18 advantage OGR Geometries have over their GEOS counterparts is support 19 for spatial reference systems and their transformation. 20 21 Example: 22 >>> from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, SpatialReference 23 >>> wkt1, wkt2 = 'POINT(-90 30)', 'POLYGON((0 0, 5 0, 5 5, 0 5)' 24 >>> pnt = OGRGeometry(wkt1) 25 >>> print pnt 26 POINT (-90 30) 27 >>> mpnt = OGRGeometry(OGRGeomType('MultiPoint'), SpatialReference('WGS84')) 28 >>> mpnt.add(wkt1) 29 >>> mpnt.add(wkt1) 30 >>> print mpnt 31 MULTIPOINT (-90 30,-90 30) 32 >>> print mpnt.srs.name 33 WGS 84 34 >>> print mpnt.srs.proj 35 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs 36 >>> mpnt.transform_to(SpatialReference('NAD27')) 37 >>> print mpnt.proj 38 +proj=longlat +ellps=clrk66 +datum=NAD27 +no_defs 39 >>> print mpnt 40 MULTIPOINT (-89.999930378602485 29.999797886557641,-89.999930378602485 29.999797886557641) 41 42 The OGRGeomType class is to make it easy to specify an OGR geometry type: 43 >>> from django.contrib.gis.gdal import OGRGeomType 44 >>> gt1 = OGRGeomType(3) # Using an integer for the type 45 >>> gt2 = OGRGeomType('Polygon') # Using a string 46 >>> gt3 = OGRGeomType('POLYGON') # It's case-insensitive 47 >>> print gt1 == 3, gt1 == 'Polygon' # Equivalence works w/non-OGRGeomType objects 48 True 49 """ 11 50 12 51 # For more information, see the OGR C API source code: … … 30 69 31 70 # Ordered array of acceptable strings and their corresponding OGRwkbGeometryType 32 __ogr_str = [' Unknown', 'Point', 'LineString', 'Polygon', 'MultiPoint',71 __ogr_str = ['Point', 'LineString', 'Polygon', 'MultiPoint', 33 72 'MultiLineString', 'MultiPolygon', 'GeometryCollection', 34 ' None', 'LinearRing']35 __ogr_int = [ 0, 1, 2, 3, 4, 5, 6, 7, 100, 101]73 'LinearRing'] 74 __ogr_int = [1, 2, 3, 4, 5, 6, 7, 101] 36 75 37 76 def __init__(self, input): … … 41 80 elif isinstance(input, StringType): 42 81 idx = self._has_str(self.__ogr_str, input) 43 if not idx:82 if idx == None: 44 83 raise OGRException, 'Invalid OGR String Type "%s"' % input 45 84 self._index = idx … … 62 101 elif isinstance(other, StringType): 63 102 idx = self._has_str(self.__ogr_str, other) 64 if idx: return self._index == idx103 if not (idx == None): return self._index == idx 65 104 return False 66 105 elif isinstance(other, int): … … 71 110 72 111 def _has_str(self, arr, s): 73 slow = s.lower() 112 "Case-insensitive search of the string array for the given pattern." 113 s_low = s.lower() 74 114 for i in xrange(len(arr)): 75 if s low == arr[i].lower(): return i115 if s_low == arr[i].lower(): return i 76 116 return None 77 117 … … 100 140 101 141 if isinstance(input, StringType): 142 # Getting the spatial reference 143 self._init_srs(srs) 144 102 145 # First, trying the input as WKT 103 146 buf = c_char_p(input) 104 147 g = c_void_p() 105 148 106 # Getting the spatial107 if not isinstance(srs, SpatialReference):108 s = SpatialReference() # creating an empty spatial reference109 else:110 s = srs.clone() # cloning the given spatial reference111 112 149 try: 113 check_err(lgdal.OGR_G_CreateFromWkt(byref(buf), s ._srs, byref(g)))150 check_err(lgdal.OGR_G_CreateFromWkt(byref(buf), self._s._srs, byref(g))) 114 151 except OGRException, msg: 115 152 try: … … 119 156 raise OGRException, 'Could not initialize on WKT "%s"' % input 120 157 elif isinstance(input, OGRGeomType): 158 self._init_srs(srs) 121 159 g = lgdal.OGR_G_CreateGeometry(input.num) 122 elif isinstance(input, int): 160 lgdal.OGR_G_AssignSpatialReference(g, self._s._srs) 161 elif isinstance(input, IntType): 123 162 # OGR Pointer (integer) was the input 124 163 g = input … … 134 173 self.__class__ = GEO_CLASSES[self.geom_type.num] 135 174 175 def _init_srs(self, srs): 176 # Getting the spatial 177 if not isinstance(srs, SpatialReference): 178 self._s = SpatialReference() # creating an empty spatial reference 179 else: 180 self._s = srs.clone() # cloning the given spatial reference 181 182 def __add__(self, other): 183 "Returns the union of the two geometries." 184 return self.union(other) 185 136 186 def __del__(self): 137 187 "Deletes this Geometry." … … 140 190 def __eq__(self, other): 141 191 "Is this Geometry equal to the other?" 142 return lgdal.OGR_G_Equals(self._g, other._g)192 return self.equals(other) 143 193 144 194 def __str__(self): … … 164 214 @property 165 215 def point_count(self): 166 " The number of Points in this Geometry."216 "Returns the number of Points in this Geometry." 167 217 return lgdal.OGR_G_GetPointCount(self._g) 218 219 @property 220 def num_coords(self): 221 "Returns the number of Points in this Geometry." 222 return self.point_count 168 223 169 224 @property … … 188 243 check_err(lgdal.OGR_G_ExportToWkt(self._g, byref(buf))) 189 244 return string_at(buf) 245 246 @property 247 def area(self): 248 "Returns the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise." 249 a = lgdal.OGR_G_GetArea(self._g) 250 return a.value 190 251 191 252 #### Geometry Methods #### … … 194 255 return OGRGeometry(lgdal.OGR_G_Clone(self._g)) 195 256 257 def close_rings(self): 258 """If there are any rings within this geometry that have not been 259 closed, this routine will do so by adding the starting point at the 260 end.""" 261 # Closing the open rings. 262 lgdal.OGR_G_CloseRings(self._g) 263 # This "fixes" a GDAL bug. See http://trac.osgeo.org/gdal/ticket/1673 264 foo = self.wkt 265 196 266 def transform(self, coord_trans): 197 267 "Transforms this Geometry with the given CoordTransform object." … … 205 275 raise OGRException, 'SpatialReference object required for transform_to.' 206 276 check_err(lgdal.OGR_G_TransformTo(self._g, srs._srs)) 277 278 #### Topology Methods #### 279 def _topology(self, topo_func, other): 280 """A generalized function for topology operations, takes a GDAL function and 281 the other geometry to perform the operation on.""" 282 if not isinstance(other, OGRGeometry): 283 raise OGRException, 'Must use another OGRGeometry object for topology operations!' 284 285 # Calling the passed-in topology function with the other geometry 286 status = topo_func(self._g, other._g) 287 288 # Returning based on the status code (an integer) 289 if status: return True 290 else: return False 291 292 def intersects(self, other): 293 "Returns True if this geometry intersects with the other." 294 return self._topology(lgdal.OGR_G_Intersects, other) 295 296 def equals(self, other): 297 "Returns True if this geometry is equivalent to the other." 298 return self._topology(lgdal.OGR_G_Equals, other) 299 300 def disjoint(self, other): 301 "Returns True if this geometry and the other are spatially disjoint." 302 return self._topology(lgdal.OGR_G_Disjoint, other) 303 304 def touches(self, other): 305 "Returns True if this geometry touches the other." 306 return self._topology(lgdal.OGR_G_Touches, other) 307 308 def crosses(self, other): 309 "Returns True if this geometry crosses the other." 310 return self._topology(lgdal.OGR_G_Crosses, other) 311 312 def within(self, other): 313 "Returns True if this geometry is within the other." 314 return self._topology(lgdal.OGR_G_Within, other) 315 316 def contains(self, other): 317 "Returns True if this geometry contains the other." 318 return self._topology(lgdal.OGR_G_Contains, other) 319 320 def overlaps(self, other): 321 "Returns True if this geometry overlaps the other." 322 return self._topology(lgdal.OGR_G_Overlaps, other) 323 324 #### Geometry-generation Methods #### 325 def _geomgen(self, gen_func, other): 326 if not isinstance(other, OGRGeometry): 327 raise OGRException, 'Must use another OGRGeometry object for geometry-generating operations!' 328 return OGRGeometry(gen_func(self._g, other._g)) 329 330 def union(self, other): 331 """Returns a new geometry consisting of the region which is the union of 332 this geometry and the other.""" 333 return self._geomgen(lgdal.OGR_G_Union, other) 334 335 def difference(self, other): 336 """Returns a new geometry consisting of the region which is the difference 337 of this geometry and the other.""" 338 return self._geomgen(lgdal.OGR_G_Difference, other) 339 340 def sym_difference(self, other): 341 """Returns a new geometry which is the symmetric difference of this 342 geometry and the other.""" 343 return self._geomgen(lgdal.OGR_G_SymmetricDifference, other) 344 345 def intersection(self, other): 346 """Returns a new geometry consisting of the region of intersection of this 347 geometry and the other.""" 348 return self._geomgen(lgdal.OGR_G_Intersection, other) 207 349 208 350 # The subclasses for OGR Geometry. … … 299 441 return tuple(self.__getitem__(i).tuple for i in xrange(self.geom_count)) 300 442 443 @property 444 def point_count(self): 445 "The number of Points in this Polygon." 446 # Summing up the number of points in each ring of the Polygon. 447 return sum([self.__getitem__(i).point_count for i in xrange(self.geom_count)]) 448 449 @property 450 def centroid(self): 451 "Returns the centroid (a Point) of this Polygon." 452 # The centroid is a Point, create a geometry for this. 453 p = OGRGeometry(OGRGeomType('Point')) 454 check_err(lgdal.OGR_G_Centroid(self._g, p._g)) 455 return p 456 301 457 # Geometry Collection base class. 302 458 class GeometryCollection(OGRGeometry): … … 321 477 def add(self, geom): 322 478 "Add the geometry to this Geometry Collection." 323 if not isinstance(geom, OGRGeometry): 479 if isinstance(geom, OGRGeometry): 480 ptr = geom._g 481 elif isinstance(geom, StringType): 482 tmp = OGRGeometry(geom) 483 ptr = tmp._g 484 else: 324 485 raise OGRException, 'Must add an OGRGeometry.' 325 lgdal.OGR_G_AddGeometry(self._g, geom._g) 486 lgdal.OGR_G_AddGeometry(self._g, ptr) 487 488 @property 489 def point_count(self): 490 "The number of Points in this Geometry Collection." 491 # Summing up the number of points in each geometry in this collection 492 return sum([self.__getitem__(i).point_count for i in xrange(self.geom_count)]) 493 494 @property 495 def tuple(self): 496 "Returns a tuple representation of this Geometry Collection." 497 return tuple(self.__getitem__(i).tuple for i in xrange(self.geom_count)) 326 498 327 499 # Multiple Geometry types. django/branches/gis/django/contrib/gis/gdal/SpatialReference.py
r5397 r5478 11 11 # Getting the error checking routine and exceptions 12 12 from django.contrib.gis.gdal.OGRError import check_err, OGRException, SRSException 13 14 """ 15 The Spatial Reference class, represensents OGR Spatial Reference objects. 16 17 Example: 18 >>> from django.contrib.gis.gdal import SpatialReference 19 >>> srs = SpatialReference('WGS84') 20 >>> print srs 21 GEOGCS["WGS 84", 22 DATUM["WGS_1984", 23 SPHEROID["WGS 84",6378137,298.257223563, 24 AUTHORITY["EPSG","7030"]], 25 TOWGS84[0,0,0,0,0,0,0], 26 AUTHORITY["EPSG","6326"]], 27 PRIMEM["Greenwich",0, 28 AUTHORITY["EPSG","8901"]], 29 UNIT["degree",0.01745329251994328, 30 AUTHORITY["EPSG","9122"]], 31 AUTHORITY["EPSG","4326"]] 32 >>> print srs.proj 33 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs 34 >>> print srs.ellipsoid 35 (6378137.0, 6356752.3142451793, 298.25722356300003) 36 >>> print srs.projected, srs.geographic 37 False True 38 >>> srs.import_epsg(32140) 39 >>> print srs.name 40 NAD83 / Texas South Central 41 """ 42 13 43 14 44 #### ctypes function prototypes #### … … 184 214 return self._angular_units 185 215 186 #### Spheroid/Ellipsis Properties #### 216 #### Spheroid/Ellipsoid Properties #### 217 @property 218 def ellipsoid(self): 219 """Returns a tuple of the ellipsoid parameters: 220 (semimajor axis, semiminor axis, and inverse flattening).""" 221 return (self.semi_major, self.semi_minor, self.inverse_flattening) 222 187 223 @property 188 224 def semi_major(self): … … 267 303 check_err(lgdal.OSRExportToProj4(self._srs, byref(w))) 268 304 return string_at(w) 305 306 def proj4(self): 307 "Alias for proj()." 308 return self.proj 269 309 270 310 @property django/branches/gis/django/contrib/gis/tests/geometries.py
r5395 r5478 54 54 # Polygons 55 55 polygons = (TestGeom('POLYGON ((0 0, 0 100, 100 100, 100 0, 0 0), (10 10, 10 90, 90 90, 90 10, 10 10))', 56 n_i=1, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), pc=10,56 n_i=1, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), n_p=10, area=3600.0, centroid=(50., 50.), 57 57 ), 58 58 TestGeom('POLYGON ((0 0, 0 100, 100 100, 100 0, 0 0), (10 10, 10 20, 20 20, 20 10, 10 10), (80 80, 80 90, 90 90, 90 80, 80 80))', 59 n_i=2, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), pc=15,59 n_i=2, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), n_p=15, area=9800.0, centroid=(50., 50.), 60 60 ), 61 61 TestGeom('POLYGON ((0 0, 0 100, 100 100, 100 0, 0 0))', 62 n_i=0, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), pc=10,62 n_i=0, ext_ring_cs=((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)), n_p=5, area=10000.0, centroid=(50., 50.), 63 63 ), 64 64 TestGeom('POLYGON ((-95.3848703124799471 29.7056021479768511, -95.3851905195191847 29.7046588196500281, -95.3859356966379011 29.7025053545605502, -95.3860723000647539 29.7020963367038391, -95.3871517697222089 29.6989779021280995, -95.3865578518265522 29.6990856888057202, -95.3862634205175226 29.6999471753441782, -95.3861991779541967 29.6999591988978615, -95.3856773799358137 29.6998323107113578, -95.3856209915427229 29.6998005235473741, -95.3855833545501639 29.6996619391729801, -95.3855776331865002 29.6996232659570047, -95.3850162731712885 29.6997236706530536, -95.3831047357410284 29.7000847603095082, -95.3829800724914776 29.7000676365023502, -95.3828084594470909 29.6999969684031200, -95.3828131504821499 29.6999090511531065, -95.3828022942979601 29.6998152117366025, -95.3827893930918833 29.6997790953076759, -95.3825174668099862 29.6998267772748825, -95.3823521544804862 29.7000451723151606, -95.3820491918785223 29.6999682034582335, -95.3817932841505893 29.6999640407204772, -95.3815438924600443 29.7005983712500630, -95.3807812390843424 29.7007538492921590, -95.3778578936435935 29.7012966201172048, -95.3770817300034679 29.7010555145969093, -95.3772763716395957 29.7004995005932031, -95.3769891024414420 29.7005797730360186, -95.3759855007185990 29.7007754783987821, -95.3759516423090474 29.7007305400669388, -95.3765252155960042 29.6989549173240874, -95.3766842746727832 29.6985134987163164, -95.3768510987262914 29.6980530300744938, -95.3769198676258014 29.6977137204527573, -95.3769616670751930 29.6973351617272172, -95.3770309229297766 29.6969821084304186, -95.3772352596880637 29.6959751305871613, -95.3776232419333354 29.6945439060847463, -95.3776849628727064 29.6943364710766069, -95.3779699491714723 29.6926548349458947, -95.3781945479573494 29.6920088336742545, -95.3785807118394189 29.6908279316076005, -95.3787441368896651 29.6908846275832197, -95.3787903214163890 29.6907152912461640, -95.3791765069353659 29.6893335376821526, -95.3794935959513026 29.6884781789101595, -95.3796592071232112 29.6880066681407619, -95.3799788182090111 29.6873687353035081, -95.3801545516183893 29.6868782380716993, -95.3801258908302145 29.6867756621337762, -95.3801104284899566 29.6867229678809572, -95.3803803523746154 29.6863753372986459, -95.3821028558287622 29.6837392961470421, -95.3827289584682205 29.6828097375216160, -95.3827494698109035 29.6790739156259278, -95.3826022014838486 29.6776502228345507, -95.3825047356438063 29.6765773006280753, -95.3823473035336917 29.6750405250369127, -95.3824540163482055 29.6750076408228587, -95.3838984230304305 29.6745679207378679, -95.3916547074937426 29.6722459226508377, -95.3926154662749468 29.6719609085105489, -95.3967246645118081 29.6707316485589736, -95.3974588054406780 29.6705065336410989, -95.3978523748756828 29.6703795547846845, -95.3988598162279970 29.6700874981900853, -95.3995628600665952 29.6698505300412414, -95.4134721665944170 29.6656841279906232, -95.4143262068232616 29.6654291174019278, -95.4159685142480214 29.6649750989232288, -95.4180067396277565 29.6643253024318021, -95.4185886692196590 29.6641482768691063, -95.4234155309609662 29.6626925393704788, -95.4287785503196346 29.6611023620959706, -95.4310287312749352 29.6604222580752648, -95.4320295629628959 29.6603361318136720, -95.4332899683975739 29.6600560661713608, -95.4342675748811047 29.6598454934599900, -95.4343110414310871 29.6598411486215490, -95.4345576779282538 29.6598147020668499, -95.4348823041721630 29.6597875803673112, -95.4352827715209457 29.6597762346946681, -95.4355290431309982 29.6597827926562374, -95.4359197997999331 29.6598014511782715, -95.4361907884752156 29.6598444333523368, -95.4364608955807228 29.6598901433108217, -95.4367250147512323 29.6599494499910712, -95.4364898759758091 29.6601880616540186, -95.4354501111810691 29.6616378572201107, -95.4381459623171224 29.6631265631655126, -95.4367852490863129 29.6642266600024023, -95.4370040894557263 29.6643425389568769, -95.4367078350812648 29.6645492592343238, -95.4366081749871285 29.6646291473027297, -95.4358539359938192 29.6652308742342932, -95.4350327668927889 29.6658995989314462, -95.4350580905272921 29.6678812477895271, -95.4349710541447536 29.6680054925936965, -95.4349500440473548 29.6671410080890006, -95.4341492724148850 29.6678790545191688, -95.4340248868274728 29.6680353198492135, -95.4333227845797438 29.6689245624945990, -95.4331325652123326 29.6691616138940901, -95.4321314741096955 29.6704473333237253, -95.4320435792664341 29.6702578985411982, -95.4320147929883547 29.6701800936425109, -95.4319764538662980 29.6683246590817085, -95.4317490976340679 29.6684974372577166, -95.4305958185342718 29.6694049049170374, -95.4296600735653016 29.6701723430938493, -95.4284928989940937 29.6710931793380972, -95.4274630532378580 29.6719378813640091, -95.4273056811974811 29.6720684984625791, -95.4260554084574864 29.6730668861566969, -95.4253558063699643 29.6736342467365724, -95.4249278826026028 29.6739557343648919, -95.4248648873821423 29.6745400910786152, -95.4260016131471929 29.6750987014005858, -95.4258567183010911 29.6753452063069929, -95.4260238081486847 29.6754322077221353, -95.4258707374502393 29.6756647377294307, -95.4257951755816691 29.6756407098663360, -95.4257701599566985 29.6761077719536068, -95.4257726684792260 29.6761711204603955, -95.4257980187195614 29.6770219651929423, -95.4252712669032519 29.6770161558853758, -95.4249234392992065 29.6770068683962300, -95.4249574272905789 29.6779707498635759, -95.4244725881033702 29.6779825646764159, -95.4222269476429545 29.6780711474441716, -95.4223032371999267 29.6796029391538809, -95.4239133706588945 29.6795331493690355, -95.4224579084327331 29.6813706893847780, -95.4224290108823965 29.6821953228763924, -95.4230916478977349 29.6822130268724109, -95.4222928279595521 29.6832041816675343, -95.4228763710016352 29.6832087677714505, -95.4223401691637179 29.6838987872753748, -95.4211655906087088 29.6838784024852984, -95.4201984153205558 29.6851319258758082, -95.4206156387716362 29.6851623398125319, -95.4213438084897660 29.6851763011334739, -95.4212071118618752 29.6853679931624974, -95.4202651399651245 29.6865313962980508, -95.4172061157659783 29.6865816431043932, -95.4182217951255183 29.6872251197301544, -95.4178664826439160 29.6876750901471631, -95.4180678442928780 29.6877960336377207, -95.4188763472917572 29.6882826379510938, -95.4185374500596311 29.6887137897831934, -95.4182121713132290 29.6885097429738813, -95.4179857231741551 29.6888118367840086, -95.4183106010563620 29.6890048676118212, -95.4179489865331334 29.6894546700979056, -95.4175581746284820 29.6892323606815438, -95.4173439957341571 29.6894990139807007, -95.4177411199311081 29.6897435034738422, -95.4175789200209721 29.6899207529979208, -95.4170598559864800 29.6896042165807508, -95.4166733682539814 29.6900891174451367, -95.4165941362704331 29.6900347214235047, -95.4163537218065301 29.6903529467753238, -95.4126843270708775 29.6881086357212780, -95.4126604121378392 29.6880942378803496, -95.4126672298953338 29.6885951670109982, -95.4126680884821923 29.6887052446594275, -95.4158080137241882 29.6906382377959339, -95.4152061403821961 29.6910871045531586, -95.4155842583188161 29.6917382915894308, -95.4157426793520358 29.6920726941677096, -95.4154520563662203 29.6922052332446427, -95.4151389936167078 29.6923261661269571, -95.4148649784384872 29.6924343866430256, -95.4144051352401590 29.6925623927348106, -95.4146792019416665 29.6926770338507744, -95.4148824479948985 29.6928117893696388, -95.4149851734360226 29.6929823719519774, -95.4140436551925291 29.6929626643100946, -95.4140465993023241 29.6926545917254892, -95.4137269186733334 29.6927395764256090, -95.4137372859685513 29.6935432485666624, -95.4135702836218655 29.6933186678088283, -95.4133925235973237 29.6930415229852152, -95.4133017035615580 29.6928685062036166, -95.4129588921634593 29.6929391128977862, -95.4125107395559695 29.6930481664661485, -95.4102647423187307 29.6935850183258019, -95.4081931340840157 29.6940907430947760, -95.4078783596459772 29.6941703429951609, -95.4049213975000043 29.6948723732981961, -95.4045944244127071 29.6949626434239207, -95.4045865139788134 29.6954109019001358, -95.4045953345484037 29.6956972800496963, -95.4038879332535146 29.6958296089365490, -95.4040366394459340 29.6964389004769842, -95.4032774779020798 29.6965643341263892, -95.4026066501239853 29.6966646227683881, -95.4024991226393837 29.6961389766619703, -95.4011781398631911 29.6963566063186377, -95.4011524097636112 29.6962596176762190, -95.4018184046368276 29.6961399466727336, -95.4016995838361908 29.6956442609415099, -95.4007100753964608 29.6958900524002978, -95.4008032469935188 29.6962639900781404, -95.3995660267125487 29.6965636449370329, -95.3996140564775601 29.6967877962763644, -95.3996364430014410 29.6968901984825280, -95.3984003269631842 29.6968679634805746, -95.3981442026887265 29.6983660679730335, -95.3980178461957706 29.6990890276252415, -95.3977097967130163 29.7008526152273049, -95.3962347157626027 29.7009697553607630, -95.3951949050136250 29.7004740386619019, -95.3957564950617183 29.6990281830553187, -95.3965927101519924 29.6968771129030706, -95.3957496517238184 29.6970800358387095, -95.3957720559467361 29.6972264611230727, -95.3957391586571788 29.6973548894558732, -95.3956286413405365 29.6974949857280883, -95.3955111053256957 29.6975661086270186, -95.3953215342724121 29.6976022763384790, -95.3951795558443365 29.6975846977491038, -95.3950369632041060 29.6975175779330200, -95.3949401089966500 29.6974269267953304, -95.3948740281415581 29.6972903308506346, -95.3946650813866910 29.6973397326847923, -95.3947654059391112 29.6974882560192022, -95.3949627316619768 29.6980355864961858, -95.3933200807862249 29.6984590863712796, -95.3932606497523494 29.6984464798710839, -95.3932983699113350 29.6983154306484352, -95.3933058014696655 29.6982165816983610, -95.3932946347785133 29.6981089778195759, -95.3931780601756287 29.6977068906794841, -95.3929928222970602 29.6977541771878180, -95.3930873169846478 29.6980676264932946, -95.3932743746374570 29.6981249406449663, -95.3929512584706316 29.6989526513922222, -95.3919850280655197 29.7014358632108646, -95.3918950918929056 29.7014169320765724, -95.3916928317890296 29.7019232352846423, -95.3915424614970959 29.7022988712928289, -95.3901530441668939 29.7058519502930061, -95.3899656322116698 29.7059156823562418, -95.3897628748670883 29.7059900058266777, -95.3896062677805787 29.7060738276384946, -95.3893941800512266 29.7061891695242046, -95.3892150365492455 29.7062641292949436, -95.3890502563035199 29.7063339729630940, -95.3888717930715586 29.7063896908080736, -95.3886925428988945 29.7064453871994978, -95.3885376849411983 29.7064797304524149, -95.3883284158984139 29.7065153575050189, -95.3881046767627794 29.7065368368267357, -95.3878809284696132 29.7065363048447537, -95.3876046356120924 29.7065288525102424, -95.3873060894974714 29.7064822806001452, -95.3869851943158409 29.7063993367575350, -95.3865967896568065 29.7062870572919202, -95.3861785624983156 29.7061492099008184, -95.3857375009733488 29.7059887337478798, -95.3854573290902152 29.7058683664514618, -95.3848703124799471 29.7056021479768511))', 65 n_i=0, ext_ring_cs=False 65 n_i=0, ext_ring_cs=False, n_p=264, area=0.00129917360654, centroid=(-95.403569179437341, 29.681772571690402), 66 66 ), 67 67 ) 68 68 69 69 # MultiPolygons 70 multipolygons = (TestGeom('MULTIPOLYGON (((100 20, 180 20, 180 100, 100 100, 100 20)), ((20 100, 100 100, 100 180, 20 180, 20 100)), ((100 180, 180 180, 180 260, 100 260, 100 180)), ((180 100, 260 100, 260 180, 180 180, 180 100)))', valid=True, n _p=4),70 multipolygons = (TestGeom('MULTIPOLYGON (((100 20, 180 20, 180 100, 100 100, 100 20)), ((20 100, 100 100, 100 180, 20 180, 20 100)), ((100 180, 180 180, 180 260, 100 260, 100 180)), ((180 100, 260 100, 260 180, 180 180, 180 100)))', valid=True, num_geom=4, n_p=20), 71 71 TestGeom('MULTIPOLYGON (((60 300, 320 220, 260 60, 60 100, 60 300)), ((60 300, 320 220, 260 60, 60 100, 60 300)))', valid=False), 72 TestGeom('MULTIPOLYGON (((180 60, 240 160, 300 60, 180 60)), ((80 80, 180 60, 160 140, 240 160, 360 140, 300 60, 420 100, 320 280, 120 260, 80 80)))', valid=True, n _p=2),72 TestGeom('MULTIPOLYGON (((180 60, 240 160, 300 60, 180 60)), ((80 80, 180 60, 160 140, 240 160, 360 140, 300 60, 420 100, 320 280, 120 260, 80 80)))', valid=True, num_geom=2, n_p=14), 73 73 ) 74 75 74 76 75 # Points … … 84 83 85 84 # MultiPoints 86 multipoints = (TestGeom('MULTIPOINT(10 10, 20 20 )', points=((10., 10.), (20., 20.)), centroid=(15., 15.)),85 multipoints = (TestGeom('MULTIPOINT(10 10, 20 20 )', n_p=2, points=((10., 10.), (20., 20.)), centroid=(15., 15.)), 87 86 TestGeom('MULTIPOINT(10 10, 20 20, 10 20, 20 10)', 88 points=((10., 10.), (20., 20.), (10., 20.), (20., 10.)),87 n_p=4, points=((10., 10.), (20., 20.), (10., 20.), (20., 10.)), 89 88 centroid=(15., 15.)), 90 89 ) 91 90 92 91 # LineStrings 93 linestrings = (TestGeom('LINESTRING (60 180, 120 100, 180 180)', centroid=(120, 140)), 94 # TestGeom('LINESTRING (80 0, 80 120, 120 120, 120 0))', centroid=(100, 69)), 95 TestGeom('LINESTRING (0 0, 5 5, 10 5, 10 10)', centroid=(6.1611652351681556, 4.6966991411008934)), 92 linestrings = (TestGeom('LINESTRING (60 180, 120 100, 180 180)', n_p=3, centroid=(120, 140), tup=((60, 180), (120, 100), (180, 180))), 93 TestGeom('LINESTRING (0 0, 5 5, 10 5, 10 10)', n_p=4, centroid=(6.1611652351681556, 4.6966991411008934), tup=((0, 0), (5, 5), (10, 5), (10, 10)),) 96 94 ) 97 95 98 96 # MultiLineStrings 99 multilinestrings = (TestGeom('MULTILINESTRING ((0 0, 0 100), (100 0, 100 100))', centroid=(50, 50)), 100 # TestGeom('MULTILINESTRING ((0 0, 0 200, 200 200, 200 0, 0 0), (60 180, 20 180, 20 140, 60 140, 60 180))', centroid=(90, 100)), 97 multilinestrings = (TestGeom('MULTILINESTRING ((0 0, 0 100), (100 0, 100 100))', n_p=4, centroid=(50, 50), tup=(((0, 0), (0, 100)), ((100, 0), (100, 100)))), 101 98 TestGeom('MULTILINESTRING ((20 20, 60 60), (20 -20, 60 -60), (-20 -20, -60 -60), (-20 20, -60 60), (-80 0, 0 80, 80 0, 0 -80, -80 0), (-40 20, -40 -20), (-20 40, 20 40), (40 20, 40 -20), (20 -40, -20 -40))', 102 centroid=(0, 0)),99 n_p=21, centroid=(0, 0), tup=(((20., 20.), (60., 60.)), ((20., -20.), (60., -60.)), ((-20., -20.), (-60., -60.)), ((-20., 20.), (-60., 60.)), ((-80., 0.), (0., 80.), (80., 0.), (0., -80.), (-80., 0.)), ((-40., 20.), (-40., -20.)), ((-20., 40.), (20., 40.)), ((40., 20.), (40., -20.)), ((20., -40.), (-20., -40.)))) 103 100 ) 104 101 django/branches/gis/django/contrib/gis/tests/__init__.py
r5397 r5478 1 1 from unittest import TestSuite, makeSuite, TextTestRunner 2 import test_geos, test_gdal_ds, test_gdal_ srs, test_gdal_geom, test_spatialrefsys2 import test_geos, test_gdal_ds, test_gdal_driver, test_gdal_srs, test_gdal_geom, test_spatialrefsys 3 3 4 4 def suite(): … … 6 6 s.addTest(test_geos.suite()) 7 7 s.addTest(test_gdal_ds.suite()) 8 s.addTest(test_gdal_driver.suite()) 8 9 s.addTest(test_gdal_srs.suite()) 9 10 s.addTest(test_gdal_geom.suite()) … … 11 12 return s 12 13 13 def run(verbosity= 2):14 def run(verbosity=1): 14 15 TextTestRunner(verbosity=verbosity).run(suite()) django/branches/gis/django/contrib/gis/tests/test_gdal_ds.py
r5397 r5478 41 41 42 42 # Making sure the driver name matches up 43 self.assertEqual('ESRI Shapefile', ds.driver)43 self.assertEqual('ESRI Shapefile', str(ds.driver)) 44 44 45 45 # Making sure indexing works django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py
r5397 r5478 11 11 # OGRGeomType should initialize on all these inputs. 12 12 try: 13 g = OGRGeomType(0)14 13 g = OGRGeomType(1) 15 14 g = OGRGeomType(7) 16 15 g = OGRGeomType('point') 17 16 g = OGRGeomType('GeometrycollectioN') 17 g = OGRGeomType('LINearrING') 18 18 except: 19 19 self.fail('Could not create an OGRGeomType object!') … … 43 43 if not hasattr(p, 'z'): # No 3D 44 44 pnt = OGRGeometry(p.wkt) 45 self.assertEqual(pnt.geom_type, 1) 45 self.assertEqual(1, pnt.geom_type) 46 self.assertEqual('POINT', pnt.geom_name) 46 47 self.assertEqual(p.x, pnt.x) 47 48 self.assertEqual(p.y, pnt.y) 48 49 self.assertEqual((p.x, p.y), pnt.tuple) 49 50 50 def test03_polygons(self): 51 def test03_multipoints(self): 52 "Testing MultiPoint objects." 53 54 for mp in multipoints: 55 mgeom1 = OGRGeometry(mp.wkt) # First one from WKT 56 self.assertEqual(4, mgeom1.geom_type) 57 self.assertEqual('MULTIPOINT', mgeom1.geom_name) 58 mgeom2 = OGRGeometry('MULTIPOINT') # Creating empty multipoint 59 mgeom3 = OGRGeometry('MULTIPOINT') 60 for g in mgeom1: 61 mgeom2.add(g) # adding each point from the multipoints 62 mgeom3.add(g.wkt) # should take WKT as well 63 self.assertEqual(mgeom1, mgeom2) # they should equal 64 self.assertEqual(mgeom1, mgeom3) 65 self.assertEqual(mp.points, mgeom2.tuple) 66 self.assertEqual(mp.n_p, mgeom2.point_count) 67 68 def test04_linestring(self): 69 "Testing LineString objects." 70 for ls in linestrings: 71 linestr = OGRGeometry(ls.wkt) 72 self.assertEqual(2, linestr.geom_type) 73 self.assertEqual('LINESTRING', linestr.geom_name) 74 self.assertEqual(ls.n_p, linestr.point_count) 75 self.assertEqual(ls.tup, linestr.tuple) 76 77 def test05_multilinestring(self): 78 "Testing MultiLineString objects." 79 for mls in multilinestrings: 80 mlinestr = OGRGeometry(mls.wkt) 81 self.assertEqual(5, mlinestr.geom_type) 82 self.assertEqual('MULTILINESTRING', mlinestr.geom_name) 83 self.assertEqual(mls.n_p, mlinestr.point_count) 84 self.assertEqual(mls.tup, mlinestr.tuple) 85 86 def test06_polygons(self): 51 87 "Testing Polygon objects." 52 88 for p in polygons: 53 89 poly = OGRGeometry(p.wkt) 90 self.assertEqual(3, poly.geom_type) 91 self.assertEqual('POLYGON', poly.geom_name) 92 self.assertEqual(p.n_p, poly.point_count) 54 93 first = True 55 94 for r in poly: … … 61 100 self.assertEqual(p.ext_ring_cs, r.tuple) 62 101 63 def test0 4_multipoints(self):64 "Testing MultiPointobjects."102 def test07_closepolygons(self): 103 "Testing closing Polygon objects." 65 104 66 for mp in multipoints: 67 mgeom1 = OGRGeometry(mp.wkt) # First one from WKT 68 mgeom2 = OGRGeometry('MULTIPOINT') # Creating empty multipoint 69 for g in mgeom1: 70 mgeom2.add(g) # adding each point from the multipoint 71 self.assertEqual(mgeom1, mgeom2) # they should equal 72 105 # Both rings in this geometry are not closed. 106 poly = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5), (1 1, 2 1, 2 2, 2 1))') 107 self.assertEqual(8, poly.point_count) 108 try: 109 c = poly.centroid 110 except OGRException: 111 # Should raise an OGR exception, rings are not closed 112 pass 113 else: 114 self.fail('Should have raised an OGRException!') 115 116 # Closing the rings 117 poly.close_rings() 118 self.assertEqual(10, poly.point_count) # Two closing points should've been added 119 self.assertEqual(OGRGeometry('POINT(2.5 2.5)'), poly.centroid) 120 121 def test08_multipolygons(self): 122 "Testing MultiPolygon objects." 123 for mp in multipolygons: 124 mpoly = OGRGeometry(mp.wkt) 125 self.assertEqual(6, mpoly.geom_type) 126 self.assertEqual('MULTIPOLYGON', mpoly.geom_name) 127 if mp.valid: 128 self.assertEqual(mp.n_p, mpoly.point_count) 129 self.assertEqual(mp.num_geom, len(mpoly)) 130 73 131 def suite(): 74 132 s = unittest.TestSuite() django/branches/gis/django/contrib/gis/tests/test_geos.py
r5474 r5478 116 116 117 117 if mp.valid: 118 self.assertEqual(mp.n_p, mpoly.num_geom) 119 self.assertEqual(mp.n_p, len(mpoly)) 118 self.assertEqual(mp.num_geom, mpoly.num_geom) 119 self.assertEqual(mp.n_p, mpoly.num_coords) 120
