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 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."
|
||||
|
@ -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):
|
||||
|
@ -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."
|
||||
|
@ -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."
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user