1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

gis: got rid of CamelCase module names and made minor improvements in gdal; made srid a mutable property in geos geometries

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5749 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-07-22 05:13:22 +00:00
parent 265bb46dd9
commit 0be7b58460
14 changed files with 140 additions and 116 deletions

View File

@ -1,7 +1,8 @@
from Driver import Driver
from Envelope import Envelope
from DataSource import DataSource
from SpatialReference import SpatialReference, CoordTransform
from OGRGeometry import OGRGeometry, OGRGeomType
from OGRError import check_err, OGRException, SRSException
from driver import Driver
from envelope import Envelope
from datasource import DataSource
from srs import SpatialReference, CoordTransform
from geometries import OGRGeometry
from geomtype import OGRGeomType
from error import check_err, OGRException, SRSException

View File

@ -4,9 +4,9 @@ from ctypes import c_char_p, c_int, c_void_p, byref, string_at
# The GDAL C library, OGR exceptions, and the Layer object.
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.OGRError import OGRException, check_err
from django.contrib.gis.gdal.Layer import Layer
from django.contrib.gis.gdal.Driver import Driver
from django.contrib.gis.gdal.error import OGRException, check_err
from django.contrib.gis.gdal.layer import Layer
from django.contrib.gis.gdal.driver import Driver
"""
DataSource is a wrapper for the OGR Data Source object, which provides
@ -52,11 +52,11 @@ from django.contrib.gis.gdal.Driver import Driver
class DataSource(object):
"Wraps an OGR Data Source object."
_ds = 0 # Initially NULL
#### Python 'magic' routines ####
def __init__(self, ds_input, ds_driver=False):
self._ds = 0 # Initially NULL
# Registering all the drivers, this needs to be done
# _before_ we try to open up a data source.
if not lgdal.OGRGetDriverCount() and not lgdal.OGRRegisterAll():

View File

@ -4,7 +4,7 @@ from ctypes import c_char_p, c_int, c_void_p, byref, string_at
# The GDAL C library, OGR exceptions, and the Layer object.
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.OGRError import OGRException
from django.contrib.gis.gdal.error import OGRException
# For more information, see the OGR C API source code:
# http://www.gdal.org/ogr/ogr__api_8h.html
@ -14,8 +14,6 @@ from django.contrib.gis.gdal.OGRError import OGRException
class Driver(object):
"Wraps an OGR Data Source Driver."
_dr = 0 # Initially NULL
# Case-insensitive aliases for OGR Drivers.
_alias = {'esri' : 'ESRI Shapefile',
'shp' : 'ESRI Shapefile',
@ -29,6 +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._register()
# Checking the alias dictionary (case-insensitive) to see if an alias

View File

@ -106,7 +106,7 @@ class Envelope(object):
def wkt(self):
"Returns WKT representing a Polygon for this envelope."
# TODO: Fix significant figures.
return 'POLYGON((%f %f,%f %f,%f %f,%f %f,%f %f))' % (self.min_x, self.min_y, self.min_x, self.max_y,
return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % (self.min_x, self.min_y, self.min_x, self.max_y,
self.max_x, self.max_y, self.max_x, self.min_y,
self.min_x, self.min_y)

View File

@ -4,9 +4,9 @@ from ctypes import c_char_p, c_int, string_at
# The GDAL C library, OGR exception, and the Field object
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.OGRError import OGRException
from django.contrib.gis.gdal.Field import Field
from django.contrib.gis.gdal.OGRGeometry import OGRGeometry, OGRGeomType
from django.contrib.gis.gdal.error import OGRException
from django.contrib.gis.gdal.field import Field
from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType
# For more information, see the OGR C API source code:
# http://www.gdal.org/ogr/ogr__api_8h.html
@ -15,11 +15,11 @@ from django.contrib.gis.gdal.OGRGeometry import OGRGeometry, OGRGeomType
class Feature(object):
"A class that wraps an OGR Feature, needs to be instantiated from a Layer object."
_feat = 0 # Initially NULL
#### Python 'magic' routines ####
def __init__(self, f):
"Needs a C pointer (Python integer in ctypes) in order to initialize."
self._feat = 0 # Initially NULL
self._fdefn = 0
if not f:
raise OGRException, 'Cannot create OGR Feature, invalid pointer given.'
self._feat = f

View File

@ -1,7 +1,7 @@
from ctypes import string_at
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.OGRError import OGRException
from django.contrib.gis.gdal.error import OGRException
# For more information, see the OGR C API source code:
# http://www.gdal.org/ogr/ogr__api_8h.html

View File

@ -2,11 +2,12 @@
from types import IntType, StringType
from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p
# Getting the GDAL C library and error checking facilities
# Getting geodjango gdal prerequisites
from django.contrib.gis.gdal.libgdal import lgdal
from django.contrib.gis.gdal.Envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.OGRError import check_err, OGRException
from django.contrib.gis.gdal.SpatialReference import SpatialReference, CoordTransform
from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.error import check_err, OGRException
from django.contrib.gis.gdal.geomtype import OGRGeomType
from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
"""
The OGRGeometry is a wrapper for using the OGR Geometry class
@ -64,72 +65,6 @@ getx = pnt_func(lgdal.OGR_G_GetX)
gety = pnt_func(lgdal.OGR_G_GetY)
getz = pnt_func(lgdal.OGR_G_GetZ)
#### OGRGeomType ####
class OGRGeomType(object):
"Encapulates OGR Geometry Types."
# Ordered array of acceptable strings and their corresponding OGRwkbGeometryType
__ogr_str = ['Point', 'LineString', 'Polygon', 'MultiPoint',
'MultiLineString', 'MultiPolygon', 'GeometryCollection',
'LinearRing']
__ogr_int = [1, 2, 3, 4, 5, 6, 7, 101]
def __init__(self, input):
"Figures out the correct OGR Type based upon the input."
if isinstance(input, OGRGeomType):
self._index = input._index
elif isinstance(input, StringType):
idx = self._has_str(self.__ogr_str, input)
if idx == None:
raise OGRException, 'Invalid OGR String Type "%s"' % input
self._index = idx
elif isinstance(input, int):
if not input in self.__ogr_int:
raise OGRException, 'Invalid OGR Integer Type: %d' % input
self._index = self.__ogr_int.index(input)
else:
raise TypeError, 'Invalid OGR Input type given!'
def __str__(self):
"Returns a short-hand string form of the OGR Geometry type."
return self.__ogr_str[self._index]
def __eq__(self, other):
"""Does an equivalence test on the OGR type with the given
other OGRGeomType, the short-hand string, or the integer."""
if isinstance(other, OGRGeomType):
return self._index == other._index
elif isinstance(other, StringType):
idx = self._has_str(self.__ogr_str, other)
if not (idx == None): return self._index == idx
return False
elif isinstance(other, int):
if not other in self.__ogr_int: return False
return self.__ogr_int.index(other) == self._index
else:
raise TypeError, 'Cannot compare with type: %s' % str(type(other))
def _has_str(self, arr, s):
"Case-insensitive search of the string array for the given pattern."
s_low = s.lower()
for i in xrange(len(arr)):
if s_low == arr[i].lower(): return i
return None
@property
def django(self):
"Returns the Django GeometryField for this OGR Type."
s = self.__ogr_str[self._index]
if s in ('Unknown', 'LinearRing'):
return None
else:
return s + 'Field'
@property
def num(self):
"Returns the OGRwkbGeometryType number for the OGR Type."
return self.__ogr_int[self._index]
#### OGRGeometry Class ####
class OGRGeometryIndexError(OGRException, KeyError):
"""This exception is raised when an invalid index is encountered, and has
@ -142,11 +77,11 @@ class OGRGeometryIndexError(OGRException, KeyError):
class OGRGeometry(object):
"Generally encapsulates an OGR geometry."
_g = 0 # Initially NULL
def __init__(self, input, srs=False):
"Initializes Geometry on either WKT or an OGR pointer as input."
self._g = 0 # Initially NULL
if isinstance(input, StringType):
# Getting the spatial reference
self._init_srs(srs)
@ -181,6 +116,10 @@ class OGRGeometry(object):
# Setting the class depending upon the OGR Geometry Type
self.__class__ = GEO_CLASSES[self.geom_type.num]
def __del__(self):
"Deletes this Geometry."
if self._g: lgdal.OGR_G_DestroyGeometry(self._g)
def _init_srs(self, srs):
# Getting the spatial
if not isinstance(srs, SpatialReference):
@ -188,18 +127,35 @@ class OGRGeometry(object):
else:
self._s = srs.clone() # cloning the given spatial reference
def __add__(self, other):
### Geometry set-like operations ###
# g = g1 | g2
def __or__(self, other):
"Returns the union of the two geometries."
return self.union(other)
def __del__(self):
"Deletes this Geometry."
if self._g: lgdal.OGR_G_DestroyGeometry(self._g)
# g = g1 & g2
def __and__(self, other):
"Returns the intersection of this Geometry and the other."
return self.intersection(other)
# g = g1 - g2
def __sub__(self, other):
"Return the difference this Geometry and the other."
return self.difference(other)
# g = g1 ^ g2
def __xor__(self, other):
"Return the symmetric difference of this Geometry and the other."
return self.sym_difference(other)
def __eq__(self, other):
"Is this Geometry equal to the other?"
return self.equals(other)
def __ne__(self, other):
"Tests for inequality."
return not self.equals(other)
def __str__(self):
"WKT is used for the string representation."
return self.wkt

View File

@ -0,0 +1,67 @@
from types import StringType
#### OGRGeomType ####
class OGRGeomType(object):
"Encapulates OGR Geometry Types."
# Ordered array of acceptable strings and their corresponding OGRwkbGeometryType
__ogr_str = ['Point', 'LineString', 'Polygon', 'MultiPoint',
'MultiLineString', 'MultiPolygon', 'GeometryCollection',
'LinearRing']
__ogr_int = [1, 2, 3, 4, 5, 6, 7, 101]
def __init__(self, input):
"Figures out the correct OGR Type based upon the input."
if isinstance(input, OGRGeomType):
self._index = input._index
elif isinstance(input, StringType):
idx = self._has_str(self.__ogr_str, input)
if idx == None:
raise OGRException, 'Invalid OGR String Type "%s"' % input
self._index = idx
elif isinstance(input, int):
if not input in self.__ogr_int:
raise OGRException, 'Invalid OGR Integer Type: %d' % input
self._index = self.__ogr_int.index(input)
else:
raise TypeError, 'Invalid OGR Input type given!'
def __str__(self):
"Returns a short-hand string form of the OGR Geometry type."
return self.__ogr_str[self._index]
def __eq__(self, other):
"""Does an equivalence test on the OGR type with the given
other OGRGeomType, the short-hand string, or the integer."""
if isinstance(other, OGRGeomType):
return self._index == other._index
elif isinstance(other, StringType):
idx = self._has_str(self.__ogr_str, other)
if not (idx == None): return self._index == idx
return False
elif isinstance(other, int):
if not other in self.__ogr_int: return False
return self.__ogr_int.index(other) == self._index
else:
raise TypeError, 'Cannot compare with type: %s' % str(type(other))
def _has_str(self, arr, s):
"Case-insensitive search of the string array for the given pattern."
s_low = s.lower()
for i in xrange(len(arr)):
if s_low == arr[i].lower(): return i
return None
@property
def django(self):
"Returns the Django GeometryField for this OGR Type."
s = self.__ogr_str[self._index]
if s in ('Unknown', 'LinearRing'):
return None
else:
return s + 'Field'
@property
def num(self):
"Returns the OGRwkbGeometryType number for the OGR Type."
return self.__ogr_int[self._index]

View File

@ -5,17 +5,18 @@ from ctypes import c_int, c_long, c_void_p, byref, string_at
from django.contrib.gis.gdal.libgdal import lgdal
# Other GDAL imports.
from django.contrib.gis.gdal.Envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.Feature import Feature
from django.contrib.gis.gdal.OGRGeometry import OGRGeomType
from django.contrib.gis.gdal.OGRError import OGRException, check_err
from django.contrib.gis.gdal.SpatialReference import SpatialReference
from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
from django.contrib.gis.gdal.feature import Feature
from django.contrib.gis.gdal.geometries import OGRGeomType
from django.contrib.gis.gdal.error import OGRException, check_err
from django.contrib.gis.gdal.srs import SpatialReference
# 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.
# function prototype for obtaining the spatial reference system
get_srs = lgdal.OGR_L_GetSpatialRef
get_srs.restype = c_void_p
get_srs.argtypes = [c_void_p]
@ -23,11 +24,11 @@ get_srs.argtypes = [c_void_p]
class Layer(object):
"A class that wraps an OGR Layer, needs to be instantiated from a DataSource object."
_layer = 0 # Initially NULL
#### 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
if not l:
raise OGRException, 'Cannot create Layer, invalid pointer given'
self._layer = l

View File

@ -1,6 +1,6 @@
import os, sys
from ctypes import CDLL
from django.contrib.gis.gdal.OGRError import OGRException
from django.contrib.gis.gdal.error import OGRException
if os.name == 'nt':
# Windows NT shared library
@ -20,4 +20,4 @@ else:
# This loads the GDAL/OGR C library
lgdal = CDLL(lib_name)

View File

@ -9,7 +9,7 @@ from ctypes import \
from django.contrib.gis.gdal.libgdal import lgdal
# Getting the error checking routine and exceptions
from django.contrib.gis.gdal.OGRError import check_err, OGRException, SRSException
from django.contrib.gis.gdal.error import check_err, OGRException, SRSException
"""
The Spatial Reference class, represensents OGR Spatial Reference objects.
@ -71,8 +71,6 @@ class SpatialReference(object):
the SpatialReference object 'provide[s] services to represent coordinate systems
(projections and datums) and to transform between them.'"""
_srs = 0 # Initially NULL
# Well-Known Geographical Coordinate System Name
_well_known = {'WGS84':4326, 'WGS72':4322, 'NAD27':4267, 'NAD83':4269}
_epsg_regex = re.compile('^EPSG:(?P<epsg>\d+)$', re.I)
@ -81,6 +79,8 @@ class SpatialReference(object):
def __init__(self, input='', srs_type='wkt'):
"Creates a spatial reference object from the given OGC Well Known Text (WKT)."
self._srs = 0 # Initially NULL
# Creating an initial empty string buffer.
buf = c_char_p('')
@ -99,6 +99,7 @@ class SpatialReference(object):
else:
buf = c_char_p(input)
elif isinstance(input, int):
if srs_type == 'wkt': srs_type = 'epsg' # want to try epsg if only integer provided
if srs_type not in ('epsg', 'ogr'):
raise SRSException, 'Integer input requires SRS type of "ogr" or "epsg".'
else:
@ -317,10 +318,9 @@ class SpatialReference(object):
class CoordTransform(object):
"A coordinate system transformation object."
_ct = 0 # Initially NULL
def __init__(self, source, target):
"Initializes on a source and target SpatialReference objects."
self._ct = 0 # Initially NULL
if not isinstance(source, SpatialReference) or not isinstance(target, SpatialReference):
raise SRSException, 'source and target must be of type SpatialReference'
ct = lgdal.OCTNewCoordinateTransformation(source._srs, target._srs)

View File

@ -281,8 +281,7 @@ class GEOSGeometry(object):
return self._binary_predicate(lgeos.GEOSEqualsExact, other, tol)
#### SRID Routines ####
@property
def srid(self):
def get_srid(self):
"Gets the SRID for the geometry, returns None if no SRID is set."
s = lgeos.GEOSGetSRID(self._ptr())
if s == 0:
@ -293,7 +292,8 @@ class GEOSGeometry(object):
def set_srid(self, srid):
"Sets the SRID for the geometry."
lgeos.GEOSSetSRID(self._ptr(), c_int(srid))
srid = property(get_srid, set_srid)
#### Output Routines ####
@property
def wkt(self):

View File

@ -1,7 +1,7 @@
import os, os.path, unittest
from django.contrib.gis.gdal import DataSource, OGRException
from django.contrib.gis.gdal.Envelope import Envelope
from django.contrib.gis.gdal.Field import OFTReal, OFTInteger, OFTString
from django.contrib.gis.gdal.envelope import Envelope
from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString
# Path for SHP files
shp_path = os.path.dirname(__file__)