mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +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:
parent
6be9797bee
commit
1c2a08d2d7
@ -34,9 +34,9 @@ from geometries import Point, LineString, LinearRing, Polygon, HAS_NUMPY
|
|||||||
from collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
|
from collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon
|
||||||
from error import GEOSException, GEOSGeometryIndexError
|
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."
|
"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):
|
def hex_to_wkt(hex):
|
||||||
"Converts HEXEWKB into WKT."
|
"Converts HEXEWKB into WKT."
|
||||||
|
@ -12,7 +12,7 @@ from types import StringType, IntType, FloatType
|
|||||||
# Python and GEOS-related dependencies.
|
# Python and GEOS-related dependencies.
|
||||||
import re
|
import re
|
||||||
from warnings import warn
|
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.error import GEOSException, GEOSGeometryIndexError
|
||||||
from django.contrib.gis.geos.coordseq import GEOSCoordSeq, create_cs
|
from django.contrib.gis.geos.coordseq import GEOSCoordSeq, create_cs
|
||||||
if HAS_NUMPY: from numpy import ndarray, array
|
if HAS_NUMPY: from numpy import ndarray, array
|
||||||
@ -24,7 +24,7 @@ class GEOSGeometry(object):
|
|||||||
"A class that, generally, encapsulates a GEOS geometry."
|
"A class that, generally, encapsulates a GEOS geometry."
|
||||||
|
|
||||||
#### Python 'magic' routines ####
|
#### 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
|
"""The constructor for GEOS geometry objects. May take the following
|
||||||
strings as inputs, WKT ("wkt"), HEXEWKB ("hex", PostGIS-specific canonical form).
|
strings as inputs, WKT ("wkt"), HEXEWKB ("hex", PostGIS-specific canonical form).
|
||||||
|
|
||||||
@ -72,6 +72,9 @@ class GEOSGeometry(object):
|
|||||||
else:
|
else:
|
||||||
self._parent = GEOSPointer(0)
|
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.)
|
# Setting the class type (e.g., 'Point', 'Polygon', etc.)
|
||||||
self.__class__ = GEOS_CLASSES[self.geom_type]
|
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 the symmetric difference of this Geometry and the other."
|
||||||
return self.sym_difference(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 ####
|
#### Coordinate Sequence Routines ####
|
||||||
@property
|
@property
|
||||||
def has_cs(self):
|
def has_cs(self):
|
||||||
|
@ -28,7 +28,7 @@ class GeometryCollection(GEOSGeometry):
|
|||||||
_allowed = (Point, LineString, LinearRing, Polygon)
|
_allowed = (Point, LineString, LinearRing, Polygon)
|
||||||
_typeid = 7
|
_typeid = 7
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args, **kwargs):
|
||||||
self._ptr = GEOSPointer(0) # Initially NULL
|
self._ptr = GEOSPointer(0) # Initially NULL
|
||||||
self._geoms = {}
|
self._geoms = {}
|
||||||
self._parent = False
|
self._parent = False
|
||||||
@ -61,7 +61,7 @@ class GeometryCollection(GEOSGeometry):
|
|||||||
geoms[i] = cast(init_from_geom(init_geoms[i]), GEOM_PTR)
|
geoms[i] = cast(init_from_geom(init_geoms[i]), GEOM_PTR)
|
||||||
|
|
||||||
# Calling the parent class, using the pointer returned from GEOS createCollection()
|
# 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):
|
def __del__(self):
|
||||||
"Overloaded deletion method for Geometry Collections."
|
"Overloaded deletion method for Geometry Collections."
|
||||||
@ -85,7 +85,7 @@ class GeometryCollection(GEOSGeometry):
|
|||||||
"For indexing on the multiple geometries."
|
"For indexing on the multiple geometries."
|
||||||
# Checking the index and returning the corresponding GEOS geometry.
|
# Checking the index and returning the corresponding GEOS geometry.
|
||||||
self._checkindex(index)
|
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):
|
def __iter__(self):
|
||||||
"For iteration on the multiple geometries."
|
"For iteration on the multiple geometries."
|
||||||
|
@ -14,7 +14,7 @@ if HAS_NUMPY: from numpy import ndarray, array
|
|||||||
|
|
||||||
class Point(GEOSGeometry):
|
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
|
"""The Point object may be initialized with either a tuple, or individual
|
||||||
parameters. For example:
|
parameters. For example:
|
||||||
>>> p = Point((5, 23)) # 2D point, passed in as a tuple
|
>>> 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]))
|
status = lgeos.GEOSCoordSeq_setZ(cs, c_uint(0), c_double(coords[2]))
|
||||||
|
|
||||||
# Initializing from the geometry, and getting a Python object
|
# 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):
|
def __len__(self):
|
||||||
"Returns the number of dimensions for this Point (either 2 or 3)."
|
"Returns the number of dimensions for this Point (either 2 or 3)."
|
||||||
@ -176,8 +176,11 @@ class LineString(GEOSGeometry):
|
|||||||
else:
|
else:
|
||||||
func = lgeos.GEOSGeom_createLineString
|
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.
|
# 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):
|
def __getitem__(self, index):
|
||||||
"Gets the point at the specified index."
|
"Gets the point at the specified index."
|
||||||
@ -235,14 +238,14 @@ class LineString(GEOSGeometry):
|
|||||||
|
|
||||||
# LinearRings are LineStrings used within Polygons.
|
# LinearRings are LineStrings used within Polygons.
|
||||||
class LinearRing(LineString):
|
class LinearRing(LineString):
|
||||||
def __init__(self, *args):
|
def __init__(self, *args, **kwargs):
|
||||||
"Overriding the initialization function to set the ring keyword."
|
"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)
|
super(LinearRing, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Polygon(GEOSGeometry):
|
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.
|
"""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.
|
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)
|
shell = init_from_geom(ext_ring)
|
||||||
|
|
||||||
# Calling with the GEOS createPolygon factory.
|
# 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):
|
def __del__(self):
|
||||||
"Overloaded deletion method for Polygons."
|
"Overloaded deletion method for Polygons."
|
||||||
@ -340,7 +343,7 @@ class Polygon(GEOSGeometry):
|
|||||||
|
|
||||||
# Returning the ring from the internal ring dictionary (have to
|
# Returning the ring from the internal ring dictionary (have to
|
||||||
# add one to the index)
|
# 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 ####
|
#### Polygon Properties ####
|
||||||
@property
|
@property
|
||||||
@ -356,7 +359,7 @@ class Polygon(GEOSGeometry):
|
|||||||
|
|
||||||
def get_ext_ring(self):
|
def get_ext_ring(self):
|
||||||
"Gets the exterior ring of the Polygon."
|
"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):
|
def set_ext_ring(self):
|
||||||
"Sets the exterior ring of the Polygon."
|
"Sets the exterior ring of the Polygon."
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
This module houses the ctypes initialization procedures, as well
|
This module houses the ctypes initialization procedures, as well
|
||||||
as the notice and error handler function callbacks (get called
|
as the notice and error handler function callbacks (get called
|
||||||
when an error occurs in GEOS).
|
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
|
from django.contrib.gis.geos.error import GEOSException
|
||||||
@ -15,6 +18,12 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_NUMPY = False
|
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
|
# Setting the appropriate name for the GEOS-C library, depending on which
|
||||||
# OS and POSIX platform we're running.
|
# OS and POSIX platform we're running.
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
@ -118,7 +127,7 @@ class GEOSPointer(object):
|
|||||||
if bool(self.address): return True
|
if bool(self.address): return True
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
### Coordinate Sequence properties ###
|
### Coordinate Sequence routines and properties ###
|
||||||
def coordseq(self):
|
def coordseq(self):
|
||||||
"If the coordinate sequence pointer is NULL (0), an exception will be raised."
|
"If the coordinate sequence pointer is NULL (0), an exception will be raised."
|
||||||
if self.coordseq_valid: return self.coordseq_address
|
if self.coordseq_valid: return self.coordseq_address
|
||||||
|
Loading…
x
Reference in New Issue
Block a user