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

gis: geos: added srid keyword and added psycopg2 adaptor routines.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5760 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-07-26 01:55:37 +00:00
parent 6be9797bee
commit 1c2a08d2d7
5 changed files with 44 additions and 17 deletions

View File

@ -34,9 +34,9 @@ from geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
from collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
from error import GEOSException, GEOSGeometryIndexError
def fromstr(wkt_or_hex):
def fromstr(wkt_or_hex, **kwargs):
"Given a string value (wkt or hex), returns a GEOSGeometry object."
return GEOSGeometry(wkt_or_hex)
return GEOSGeometry(wkt_or_hex, **kwargs)
def hex_to_wkt(hex):
"Converts HEXEWKB into WKT."

View File

@ -12,7 +12,7 @@ from types import StringType, IntType, FloatType
# Python and GEOS-related dependencies.
import re
from warnings import warn
from django.contrib.gis.geos.libgeos import lgeos, GEOSPointer, HAS_NUMPY
from django.contrib.gis.geos.libgeos import lgeos, GEOSPointer, HAS_NUMPY, ISQLQuote
from django.contrib.gis.geos.error import GEOSException, GEOSGeometryIndexError
from django.contrib.gis.geos.coordseq import GEOSCoordSeq, create_cs
if HAS_NUMPY: from numpy import ndarray, array
@ -24,7 +24,7 @@ class GEOSGeometry(object):
"A class that, generally, encapsulates a GEOS geometry."
#### Python 'magic' routines ####
def __init__(self, geo_input, input_type=False, parent=False):
def __init__(self, geo_input, input_type=False, parent=None, srid=None):
"""The constructor for GEOS geometry objects. May take the following
strings as inputs, WKT ("wkt"), HEXEWKB ("hex", PostGIS-specific canonical form).
@ -72,6 +72,9 @@ class GEOSGeometry(object):
else:
self._parent = GEOSPointer(0)
# Setting the SRID, if given.
if srid and isinstance(srid, int): self.srid = srid
# Setting the class type (e.g., 'Point', 'Polygon', etc.)
self.__class__ = GEOS_CLASSES[self.geom_type]
@ -127,6 +130,18 @@ class GEOSGeometry(object):
"Return the symmetric difference of this Geometry and the other."
return self.sym_difference(other)
#### Psycopg2 database adaptor routines ####
def __conform__(self, proto):
# Does the given protocol conform to what Psycopg2 expects?
if proto == ISQLQuote:
return self
else:
raise GEOSException, 'Error implementing psycopg2 protocol. Is psycopg2 installed?'
def getquoted(self):
"Returns a properly quoted string for use in PostgresSQL/PostGIS."
return "GeometryFromText('%s', %s)" % (self.wkt, self.srid or -1)
#### Coordinate Sequence Routines ####
@property
def has_cs(self):

View File

@ -28,7 +28,7 @@ class GeometryCollection(GEOSGeometry):
_allowed = (Point, LineString, LinearRing, Polygon)
_typeid = 7
def __init__(self, *args):
def __init__(self, *args, **kwargs):
self._ptr = GEOSPointer(0) # Initially NULL
self._geoms = {}
self._parent = False
@ -61,7 +61,7 @@ class GeometryCollection(GEOSGeometry):
geoms[i] = cast(init_from_geom(init_geoms[i]), GEOM_PTR)
# Calling the parent class, using the pointer returned from GEOS createCollection()
super(GeometryCollection, self).__init__(lgeos.GEOSGeom_createCollection(c_int(self._typeid), byref(geoms), c_uint(ngeom)))
super(GeometryCollection, self).__init__(lgeos.GEOSGeom_createCollection(c_int(self._typeid), byref(geoms), c_uint(ngeom)), **kwargs)
def __del__(self):
"Overloaded deletion method for Geometry Collections."
@ -85,7 +85,7 @@ class GeometryCollection(GEOSGeometry):
"For indexing on the multiple geometries."
# Checking the index and returning the corresponding GEOS geometry.
self._checkindex(index)
return GEOSGeometry(self._geoms[index], parent=self._ptr)
return GEOSGeometry(self._geoms[index], parent=self._ptr, srid=self.srid)
def __iter__(self):
"For iteration on the multiple geometries."

View File

@ -14,7 +14,7 @@ if HAS_NUMPY: from numpy import ndarray, array
class Point(GEOSGeometry):
def __init__(self, x, y=None, z=None):
def __init__(self, x, y=None, z=None, srid=None):
"""The Point object may be initialized with either a tuple, or individual
parameters. For example:
>>> p = Point((5, 23)) # 2D point, passed in as a tuple
@ -56,7 +56,7 @@ class Point(GEOSGeometry):
status = lgeos.GEOSCoordSeq_setZ(cs, c_uint(0), c_double(coords[2]))
# Initializing from the geometry, and getting a Python object
super(Point, self).__init__(lgeos.GEOSGeom_createPoint(cs))
super(Point, self).__init__(lgeos.GEOSGeom_createPoint(cs), srid=srid)
def __len__(self):
"Returns the number of dimensions for this Point (either 2 or 3)."
@ -176,8 +176,11 @@ class LineString(GEOSGeometry):
else:
func = lgeos.GEOSGeom_createLineString
# If SRID was passed in with the keyword arguments
srid = kwargs.get('srid', None)
# Calling the base geometry initialization with the returned pointer from the function.
super(LineString, self).__init__(func(cs._ptr.coordseq()))
super(LineString, self).__init__(func(cs._ptr.coordseq()), srid=srid)
def __getitem__(self, index):
"Gets the point at the specified index."
@ -235,14 +238,14 @@ class LineString(GEOSGeometry):
# LinearRings are LineStrings used within Polygons.
class LinearRing(LineString):
def __init__(self, *args):
def __init__(self, *args, **kwargs):
"Overriding the initialization function to set the ring keyword."
kwargs = {'ring' : True}
kwargs['ring'] = True # Setting the ring keyword argument to True
super(LinearRing, self).__init__(*args, **kwargs)
class Polygon(GEOSGeometry):
def __init__(self, *args):
def __init__(self, *args, **kwargs):
"""Initializes on an exterior ring and a sequence of holes (both instances of LinearRings.
All LinearRing instances used for creation will become owned by this Polygon.
@ -280,7 +283,7 @@ class Polygon(GEOSGeometry):
shell = init_from_geom(ext_ring)
# Calling with the GEOS createPolygon factory.
super(Polygon, self).__init__(lgeos.GEOSGeom_createPolygon(shell, byref(holes), c_uint(nholes)))
super(Polygon, self).__init__(lgeos.GEOSGeom_createPolygon(shell, byref(holes), c_uint(nholes)), **kwargs)
def __del__(self):
"Overloaded deletion method for Polygons."
@ -340,7 +343,7 @@ class Polygon(GEOSGeometry):
# Returning the ring from the internal ring dictionary (have to
# add one to the index)
return GEOSGeometry(self._rings[ring_i+1], parent=self._ptr)
return GEOSGeometry(self._rings[ring_i+1], parent=self._ptr, srid=self.srid)
#### Polygon Properties ####
@property
@ -356,7 +359,7 @@ class Polygon(GEOSGeometry):
def get_ext_ring(self):
"Gets the exterior ring of the Polygon."
return GEOSGeometry(self._rings[0], parent=self._ptr)
return GEOSGeometry(self._rings[0], parent=self._ptr, srid=self.srid)
def set_ext_ring(self):
"Sets the exterior ring of the Polygon."

View File

@ -2,6 +2,9 @@
This module houses the ctypes initialization procedures, as well
as the notice and error handler function callbacks (get called
when an error occurs in GEOS).
This module also houses GEOS Pointer utilities, including the
GEOSPointer class, get_pointer_arr(), GEOM_PTR, and init_from_geom().
"""
from django.contrib.gis.geos.error import GEOSException
@ -15,6 +18,12 @@ try:
except ImportError:
HAS_NUMPY = False
# Psycopg2 supported?
try:
from psycopg2.extensions import ISQLQuote
except ImportError:
ISQLQuote = None
# Setting the appropriate name for the GEOS-C library, depending on which
# OS and POSIX platform we're running.
if os.name == 'nt':
@ -118,7 +127,7 @@ class GEOSPointer(object):
if bool(self.address): return True
else: return False
### Coordinate Sequence properties ###
### Coordinate Sequence routines and properties ###
def coordseq(self):
"If the coordinate sequence pointer is NULL (0), an exception will be raised."
if self.coordseq_valid: return self.coordseq_address