Changeset 6508
- Timestamp:
- 10/14/07 15:13:11 (1 year ago)
- Files:
-
- django/branches/gis/django/contrib/gis/db/backend/__init__.py (modified) (4 diffs)
- django/branches/gis/django/contrib/gis/db/backend/postgis/adaptor.py (added)
- django/branches/gis/django/contrib/gis/db/backend/postgis/field.py (modified) (9 diffs)
- django/branches/gis/django/contrib/gis/db/backend/postgis/__init__.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/db/backend/postgis/query.py (modified) (5 diffs)
- django/branches/gis/django/contrib/gis/db/backend/util.py (added)
- django/branches/gis/django/contrib/gis/db/models/fields/__init__.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/db/models/__init__.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/db/models/proxy.py (moved) (moved from django/branches/gis/django/contrib/gis/db/backend/postgis/proxy.py) (1 diff)
- django/branches/gis/django/contrib/gis/db/models/query.py (modified) (4 diffs)
- django/branches/gis/django/contrib/gis/geos/base.py (modified) (7 diffs)
- django/branches/gis/django/contrib/gis/geos/libgeos.py (modified) (1 diff)
- django/branches/gis/django/contrib/gis/tests/geoapp/sql/city.postgresql_psycopg2.sql (moved) (moved from django/branches/gis/django/contrib/gis/tests/geoapp/sql/city.sql)
- django/branches/gis/django/contrib/gis/tests/geoapp/sql/country.postgresql_psycopg2.sql (moved) (moved from django/branches/gis/django/contrib/gis/tests/geoapp/sql/country.sql)
- django/branches/gis/django/contrib/gis/tests/geoapp/sql/state.postgresql_psycopg2.sql (moved) (moved from django/branches/gis/django/contrib/gis/tests/geoapp/sql/state.sql)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis/django/contrib/gis/db/backend/__init__.py
r6467 r6508 12 12 (4) The `parse_lookup` function, used for spatial SQL construction by 13 13 the GeoQuerySet. 14 (5) The `create_spatial_db`, `geo_quotename`,and `get_geo_where_clause`15 routines (needed by `parse_lookup` .14 (5) The `create_spatial_db`, and `get_geo_where_clause` 15 routines (needed by `parse_lookup`). 16 16 17 17 Currently only PostGIS is supported, but someday backends will be added for 18 18 additional spatial databases (e.g., Oracle, DB2). 19 19 """ 20 from types import StringType, UnicodeType 20 21 from django.conf import settings 21 22 from django.db import connection … … 23 24 FieldFound, LOOKUP_SEPARATOR, QUERY_TERMS 24 25 from django.utils.datastructures import SortedDict 25 26 # These routines default to False 27 ASGML, ASKML, UNION = (False, False, False) 26 from django.contrib.gis.geos import GEOSGeometry 27 28 # These routines (needed by GeoManager), default to False. 29 ASGML, ASKML, TRANSFORM, UNION= (False, False, False, False) 28 30 29 31 if settings.DATABASE_ENGINE == 'postgresql_psycopg2': … … 32 34 from django.contrib.gis.db.backend.postgis import \ 33 35 PostGISField as GeoBackendField, POSTGIS_TERMS as GIS_TERMS, \ 34 PostGISProxy as GeometryProxy, \ 35 create_spatial_db, geo_quotename, get_geo_where_clause, \ 36 ASGML, ASKML, UNION 36 create_spatial_db, get_geo_where_clause, gqn, \ 37 ASGML, ASKML, GEOM_SELECT, TRANSFORM, UNION 37 38 else: 38 39 raise NotImplementedError('No Geographic Backend exists for %s' % settings.DATABASE_NAME) 40 41 def geo_quotename(value): 42 """ 43 Returns the quotation used on a given Geometry value using the geometry 44 quoting from the backend (the `gqn` function). 45 """ 46 if isinstance(value, (StringType, UnicodeType)): return gqn(value) 47 else: return str(value) 39 48 40 49 #### query.py overloaded functions #### … … 264 273 # with the get_geo_where_clause() 265 274 if hasattr(field, '_geom'): 266 # Do we have multiple arguments, e.g., ST_Relate, ST_DWithinlookup types267 # need more than argument.275 # Do we have multiple arguments, e.g., `relate`, `dwithin` lookup types 276 # need more than argument. 268 277 multiple_args = isinstance(value, tuple) 269 278 270 # Getting the geographic where clause. 279 # Getting the preparation SQL object from the field. 280 if multiple_args: 281 geo_prep = field.get_db_prep_lookup(lookup_type, value[0]) 282 else: 283 geo_prep = field.get_db_prep_lookup(lookup_type, value) 284 285 # Getting the adapted geometry from the field. 271 286 gwc = get_geo_where_clause(lookup_type, current_table + '.', column, value) 272 273 # Getting the geographic parameters from the field. 274 if multiple_args: 275 geo_params = field.get_db_prep_lookup(lookup_type, value[0]) 276 else: 277 geo_params = field.get_db_prep_lookup(lookup_type, value) 278 279 # If a dictionary was passed back from the field modify the where clause. 280 param_dict = isinstance(geo_params, dict) 281 if param_dict: 282 subst_list = geo_params['where'] 283 if multiple_args: subst_list += map(geo_quotename, value[1:]) 284 geo_params = geo_params['params'] 285 gwc = gwc % tuple(subst_list) 286 elif multiple_args: 287 # Modify the where clause if we have multiple arguments -- the 288 # first substitution will be for another placeholder (for the 289 # geometry) since it is already apart of geo_params. 290 subst_list = ['%s'] 291 subst_list += map(geo_quotename, value[1:]) 292 gwc = gwc % tuple(subst_list) 293 294 # Finally, appending onto the WHERE clause, and extending with any 295 # additional parameters. 287 288 # A GeoFieldSQL object is returned by `get_db_prep_lookup` -- 289 # getting the substitution list and the geographic parameters. 290 subst_list = geo_prep.where 291 if multiple_args: subst_list += map(geo_quotename, value[1:]) 292 gwc = gwc % tuple(subst_list) 293 294 # Finally, appending onto the WHERE clause, and extending with 295 # the additional parameters. 296 296 where.append(gwc) 297 params.extend(geo_p arams)297 params.extend(geo_prep.params) 298 298 else: 299 299 where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type)) django/branches/gis/django/contrib/gis/db/backend/postgis/field.py
r6467 r6508 1 from types import StringType, UnicodeType 2 from django.db import connection 1 3 from django.db.models.fields import Field # Django base Field class 2 4 from django.contrib.gis.geos import GEOSGeometry, GEOSException 3 from django.contrib.gis.db.backend.postgis.query import POSTGIS_TERMS, geo_quotename as quotename 4 from types import StringType 5 from django.contrib.gis.db.backend.util import GeoFieldSQL 6 from django.contrib.gis.db.backend.postgis.adaptor import PostGISAdaptor 7 from django.contrib.gis.db.backend.postgis.query import POSTGIS_TERMS, TRANSFORM 8 from psycopg2 import Binary 9 10 # Quotename & geographic quotename, respectively 11 qn = connection.ops.quote_name 12 def gqn(value): 13 if isinstance(value, UnicodeType): value = value.encode('ascii') 14 return "'%s'" % value 5 15 6 16 class PostGISField(Field): … … 11 21 12 22 Takes the style object (provides syntax highlighting) and the 13 database table as parameters.23 database table as parameters. 14 24 """ 15 25 sql = style.SQL_KEYWORD('SELECT ') + \ 16 26 style.SQL_TABLE('AddGeometryColumn') + '(' + \ 17 style.SQL_TABLE( quotename(db_table)) + ', ' + \18 style.SQL_FIELD( quotename(self.column)) + ', ' + \27 style.SQL_TABLE(gqn(db_table)) + ', ' + \ 28 style.SQL_FIELD(gqn(self.column)) + ', ' + \ 19 29 style.SQL_FIELD(str(self._srid)) + ', ' + \ 20 style.SQL_COLTYPE( quotename(self._geom)) + ', ' + \30 style.SQL_COLTYPE(gqn(self._geom)) + ', ' + \ 21 31 style.SQL_KEYWORD(str(self._dim)) + ');' 22 32 … … 25 35 sql += '\n' + \ 26 36 style.SQL_KEYWORD('ALTER TABLE ') + \ 27 style.SQL_TABLE(q uotename(db_table, dbl=True)) + \37 style.SQL_TABLE(qn(db_table)) + \ 28 38 style.SQL_KEYWORD(' ALTER ') + \ 29 style.SQL_FIELD(q uotename(self.column, dbl=True)) + \39 style.SQL_FIELD(qn(self.column)) + \ 30 40 style.SQL_KEYWORD(' SET NOT NULL') + ';' 31 41 return sql … … 35 45 "Creates a GiST index for this geometry field." 36 46 sql = style.SQL_KEYWORD('CREATE INDEX ') + \ 37 style.SQL_TABLE(q uotename('%s_%s_id' % (db_table, self.column), dbl=True)) + \47 style.SQL_TABLE(qn('%s_%s_id' % (db_table, self.column))) + \ 38 48 style.SQL_KEYWORD(' ON ') + \ 39 style.SQL_TABLE(q uotename(db_table, dbl=True)) + \49 style.SQL_TABLE(qn(db_table)) + \ 40 50 style.SQL_KEYWORD(' USING ') + \ 41 51 style.SQL_COLTYPE(index_type) + ' ( ' + \ 42 style.SQL_FIELD(q uotename(self.column, dbl=True)) + ' ' + \52 style.SQL_FIELD(qn(self.column)) + ' ' + \ 43 53 style.SQL_KEYWORD(index_opts) + ' );' 44 54 return sql … … 65 75 sql = style.SQL_KEYWORD('SELECT ') + \ 66 76 style.SQL_KEYWORD('DropGeometryColumn') + '(' + \ 67 style.SQL_TABLE( quotename(db_table)) + ', ' + \68 style.SQL_FIELD( quotename(self.column)) + ');'77 style.SQL_TABLE(gqn(db_table)) + ', ' + \ 78 style.SQL_FIELD(gqn(self.column)) + ');' 69 79 return sql 70 80 … … 82 92 """ 83 93 if lookup_type in POSTGIS_TERMS: 84 if lookup_type == 'isnull': return [value] # special case for NULL geometries. 85 if not bool(value): return [None] # If invalid value passed in. 94 # special case for isnull lookup 95 if lookup_type == 'isnull': 96 return GeoFieldSQL([], [value]) 97 98 # When the input is not a GEOS geometry, attempt to construct one 99 # from the given string input. 86 100 if isinstance(value, GEOSGeometry): 87 # GEOSGeometry instance passed in. 88 if value.srid != self._srid: 89 # Returning a dictionary instructs the parse_lookup() to add 90 # what's in the 'where' key to the where parameters, since we 91 # need to transform the geometry in the query. 92 return {'where' : ["ST_Transform(%s,%s)"], 93 'params' : [value, self._srid] 94 } 95 else: 96 # Just return the GEOSGeometry, it has its own psycopg2 adaptor. 97 return [value] 98 elif isinstance(value, StringType): 99 # String instance passed in, assuming WKT. 100 # TODO: Any validation needed here to prevent SQL injection? 101 return ["SRID=%d;%s" % (self._srid, value)] 101 pass 102 elif isinstance(value, (StringType, UnicodeType)): 103 try: 104 value = GEOSGeometry(value) 105 except GEOSException: 106 raise TypeError("Could not create geometry from lookup value: %s" % str(value)) 102 107 else: 103 raise TypeError("Invalid type (%s) used for field lookup value." % str(type(value))) 108 raise TypeError('Cannot use parameter of %s type as lookup parameter.' % type(value)) 109 110 # Getting the SRID of the geometry, or defaulting to that of the field if 111 # it is None. 112 if value.srid is None: srid = self._srid 113 else: srid = value.srid 114 115 # The adaptor will be used by psycopg2 for quoting the WKB. 116 adapt = PostGISAdaptor(value, srid) 117 118 if srid != self._srid: 119 # Adding the necessary string substitutions and parameters 120 # to perform a geometry transformation. 121 return GeoFieldSQL(['%s(%%s,%%s)' % TRANSFORM], 122 [adapt, self._srid]) 123 else: 124 return GeoFieldSQL(['%s'], [adapt]) 104 125 else: 105 126 raise TypeError("Field has invalid lookup: %s" % lookup_type) … … 109 130 if not bool(value): return None 110 131 if isinstance(value, GEOSGeometry): 111 return value132 return PostGISAdaptor(value, value.srid) 112 133 else: 113 134 raise TypeError('Geometry Proxy should only return GEOSGeometry objects.') … … 115 136 def get_internal_type(self): 116 137 """ 117 Returns NoField because a stored procedure is used by PostGIS to create the 138 Returns NoField because a stored procedure is used by PostGIS to create 139 the Geometry Fields. 118 140 """ 119 141 return 'NoField' … … 122 144 """ 123 145 Provides a proper substitution value for Geometries that are not in the 124 SRID of the field. Specifically, this routine will substitute in the125 ST_Transform() function call.146 SRID of the field. Specifically, this routine will substitute in the 147 ST_Transform() function call. 126 148 """ 127 149 if isinstance(value, GEOSGeometry) and value.srid != self._srid: 128 150 # Adding Transform() to the SQL placeholder. 129 return ' ST_Transform(%%s, %s)' % self._srid151 return '%s(%%s, %s)' % (TRANSFORM, self._srid) 130 152 else: 131 153 return '%s' django/branches/gis/django/contrib/gis/db/backend/postgis/__init__.py
r6467 r6508 2 2 The PostGIS spatial database backend module. 3 3 """ 4 from django.contrib.gis.db.backend.postgis.creation import create_spatial_db 5 from django.contrib.gis.db.backend.postgis.field import PostGISField, gqn 6 from django.contrib.gis.db.backend.postgis.proxy import PostGISProxy 4 7 from django.contrib.gis.db.backend.postgis.query import \ 5 get_geo_where_clause, geo_quotename, \ 6 GEOM_FUNC_PREFIX, POSTGIS_TERMS, \ 7 MAJOR_VERSION, MINOR_VERSION1, MINOR_VERSION2 8 from django.contrib.gis.db.backend.postgis.creation import create_spatial_db 9 from django.contrib.gis.db.backend.postgis.field import PostGISField 10 from django.contrib.gis.db.backend.postgis.proxy import PostGISProxy 11 12 # Functions used by GeoManager methods, and not via lookup types. 13 if MAJOR_VERSION == 1: 14 if MINOR_VERSION1 == 3: 15 ASKML = 'ST_AsKML' 16 ASGML = 'ST_AsGML' 17 UNION = 'ST_Union' 18 elif MINOR_VERSION1 == 2 and MINOR_VERSION2 >= 1: 19 ASKML = 'AsKML' 20 ASGML = 'AsGML' 21 UNION = 'GeomUnion' 22 23 24 8 get_geo_where_clause, GEOM_FUNC_PREFIX, POSTGIS_TERMS, \ 9 MAJOR_VERSION, MINOR_VERSION1, MINOR_VERSION2, \ 10 ASKML, ASGML, GEOM_FROM_TEXT, UNION, TRANSFORM, GEOM_SELECT django/branches/gis/django/contrib/gis/db/backend/postgis/query.py
r6439 r6508 1 1 """ 2 This module contains the spatial lookup types, and the get_geo_where_clause()3 routine for PostGIS.2 This module contains the spatial lookup types, and the get_geo_where_clause() 3 routine for PostGIS. 4 4 """ 5 5 from django.db import connection 6 6 from django.contrib.gis.db.backend.postgis.management import postgis_version_tuple 7 7 from types import StringType, UnicodeType 8 q uote_name= connection.ops.quote_name8 qn = connection.ops.quote_name 9 9 10 10 # Getting the PostGIS version information … … 122 122 "Returns the SQL WHERE clause for use in PostGIS SQL construction." 123 123 if table_prefix.endswith('.'): 124 table_prefix = q uote_name(table_prefix[:-1])+'.'125 field_name = q uote_name(field_name)124 table_prefix = qn(table_prefix[:-1])+'.' 125 field_name = qn(field_name) 126 126 127 127 # See if a PostGIS operator matches the lookup type first 128 try:128 if lookup_type in POSTGIS_OPERATORS: 129 129 return '%s%s %s %%s' % (table_prefix, field_name, POSTGIS_OPERATORS[lookup_type]) 130 except KeyError:131 pass132 130 133 131 # See if a PostGIS Geometry function matches the lookup type next 134 try:132 if lookup_type in POSTGIS_GEOMETRY_FUNCTIONS: 135 133 lookup_info = POSTGIS_GEOMETRY_FUNCTIONS[lookup_type] 136 except KeyError:137 pass138 else:139 134 # Lookup types that are tuples take tuple arguments, e.g., 'relate' and 140 135 # 'dwithin' lookup types. … … 146 141 # Ensuring that a tuple _value_ was passed in from the user 147 142 if not isinstance(value, tuple) or len(value) != 2: 148 raise TypeError('2-element tuple required for %slookup type.' % lookup_type)143 raise TypeError('2-element tuple required for `%s` lookup type.' % lookup_type) 149 144 150 145 # Ensuring the argument type matches what we expect. … … 155 150 else: 156 151 # Returning the SQL necessary for the geometry function call. For example: 157 # ST_Contains("geoapp_country"."poly", ST_GeomFrom Text(..))152 # ST_Contains("geoapp_country"."poly", ST_GeomFromWKB(..)) 158 153 return '%s(%s%s, %%s)' % (lookup_info, table_prefix, field_name) 159 154 … … 164 159 raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) 165 160 166 def geo_quotename(value, dbl=False): 167 "Returns the quotation used for PostGIS on a given value (uses single quotes by default)." 168 if isinstance(value, (StringType, UnicodeType)): 169 if dbl: return '"%s"' % value 170 else: return "'%s'" % value 171 else: 172 return str(value) 161 # Functions that we define manually. 162 if MAJOR_VERSION == 1: 163 if MINOR_VERSION1 == 3: 164 # PostGIS versions 1.3.x 165 ASKML = 'ST_AsKML' 166 ASGML = 'ST_AsGML' 167 GEOM_FROM_TEXT = 'ST_GeomFromText' 168 GEOM_FROM_WKB = 'ST_GeomFromWKB' 169 UNION = 'ST_Union' 170 TRANSFORM = 'ST_Transform' 171 elif MINOR_VERSION1 == 2 and MINOR_VERSION2 >= 1: 172 # PostGIS versions 1.2.x 173 ASKML = 'AsKML' 174 ASGML = 'AsGML' 175 GEOM_FROM_TEXT = 'GeomFromText' 176 GEOM_FROM_WKB = 'GeomFromWKB' 177 UNION = 'GeomUnion' 178 TRANSFORM = 'Transform' 179 elif MINOR_VERSION1 == 1 and MINOR_VERSION2 >= 0: 180 # PostGIS versions 1.1.x 181 ASKML = False 182 ASGML = 'AsGML' 183 GEOM_FROM_TEXT = 'GeomFromText' 184 GEOM_FROM_WKB = 'GeomFromWKB' 185 TRANSFORM = 'Transform' 186 UNION = 'GeomUnion' 187 188 # Custom selection not needed for PostGIS since GEOS geometries may be 189 # instantiated directly from the HEXEWKB returned by default. If 190 # WKT is needed for some reason in the future, this value may be changed, 191 # 'AsText(%s)' 192 GEOM_SELECT = None django/branches/gis/django/contrib/gis/db/models/fields/__init__.py
r6467 r6508 1 1 from django.conf import settings 2 from django.contrib.gis.db.backend import GeoBackendField, GeometryProxy # these depend on the spatial database backend. 2 from django.contrib.gis.db.backend import GeoBackendField # these depend on the spatial database backend. 3 from django.contrib.gis.db.models.proxy import GeometryProxy 3 4 from django.contrib.gis.oldforms import WKTField 4 5 from django.contrib.gis.geos import GEOSGeometry django/branches/gis/django/contrib/gis/db/models/__init__.py
r5657 r6508 8 8 from django.contrib.gis.db.models.query import GeoQ 9 9 10 # The various PostGIS/OpenGISenabled fields.10 # The geographic-enabled fields. 11 11 from django.contrib.gis.db.models.fields import \ 12 12 GeometryField, PointField, LineStringField, PolygonField, \ django/branches/gis/django/contrib/gis/db/models/proxy.py
r6467 r6508 9 9 from types import NoneType, StringType, UnicodeType 10 10 11 class PostGISProxy(object):11 class GeometryProxy(object): 12 12 def __init__(self, klass, field): 13 13 """ django/branches/gis/django/contrib/gis/db/models/query.py
r6441 r6508 7 7 from django.contrib.gis.db.models.fields import GeometryField 8 8 # parse_lookup depends on the spatial database backend. 9 from django.contrib.gis.db.backend import parse_lookup, ASGML, ASKML, UNION9 from django.contrib.gis.db.backend import parse_lookup, ASGML, ASKML, GEOM_SELECT, TRANSFORM, UNION 10 10 from django.contrib.gis.geos import GEOSGeometry 11 11 … … 29 29 # For replacement fields in the SELECT. 30 30 self._custom_select = {} 31 32 # If GEOM_SELECT is defined in the backend, then it will be used 33 # for the selection format of the geometry column. 34 if GEOM_SELECT: self._geo_fmt = GEOM_SELECT 35 else: self._geo_fmt = '%s' 31 36 32 37 def _filter_or_exclude(self, mapper, *args, **kwargs): … … 58 63 # in the SELECT, overriding their values -- this is different from using 59 64 # QuerySet.extra(select=foo) because extra() adds an an _additional_ 60 # field to be selected. Used in returning transformed geometries. 65 # field to be selected. Used in returning transformed geometries, and 66 # handling the selection of native database geometry formats. 61 67 for f in opts.fields: 62 if f.column in self._custom_select: select.append(self._custom_select[f.column]) 63 else: select.append(self._field_column(f)) 68 # Getting the selection format string. 69 if hasattr(f, '_geom'): sel_fmt = self._geo_fmt 70 else: sel_fmt = '%s' 71 72 # Getting the field selection substitution string 73 if f.column in self._custom_select: 74 fld_sel = self._custom_select[f.column] 75 else: 76 fld_sel = self._field_column(f) 77 78 # Appending the selection 79 select.append(sel_fmt % fld_sel) 64 80 65 81 tables = [quote_only_if_word(t) for t in self._tables] … … 205 221 field = self.model._meta.get_field(field_name) 206 222 if not isinstance(field, GeometryField): 207 raise TypeError('ST_Transform() only available for GeometryFields') 223 raise TypeError('%s() only available for GeometryFields' % TRANSFORM) 224 225 # If there's already custom select SQL. 226 col = self._custom_select.get(field.column, self._field_column(field)) 208 227 209 228 # Setting the key for the field's column with the custom SELECT SQL to 210 229 # override the geometry column returned from the database. 211 230 self._custom_select[field.column] = \ 212 '( ST_Transform(%s, %s)) AS %s' % (self._field_column(field), srid,213 connection.ops.quote_name(field.column))231 '(%s(%s, %s)) AS %s' % (TRANSFORM, col, srid, 232 connection.ops.quote_name(field.column)) 214 233 return self._clone() 215 234 django/branches/gis/django/contrib/gis/geos/base.py
r6465 r6508 13 13 from django.contrib.gis.geos.coordseq import GEOSCoordSeq, create_cs 14 14 from django.contrib.gis.geos.error import GEOSException, GEOSGeometryIndexError 15 from django.contrib.gis.geos.libgeos import lgeos, HAS_NUMPY , ISQLQuote15 from django.contrib.gis.geos.libgeos import lgeos, HAS_NUMPY 16 16 from django.contrib.gis.geos.pointer import GEOSPointer, NULL_GEOM 17 17 … … 48 48 The `srid` keyword is used to specify the Source Reference Identifier 49 49 (SRID) number for this Geometry. If not set, the SRID will be None. 50 """ 51 50 """ 51 from_hex = False 52 52 if isinstance(geo_input, UnicodeType): 53 53 # Encoding to ASCII, WKT or HEXEWKB doesn't need any more. … … 56 56 if hex_regex.match(geo_input): 57 57 # If the regex matches, the geometry is in HEX form. 58 from_hex = True 58 59 sz = c_size_t(len(geo_input)) 59 60 buf = create_string_buffer(geo_input) … … 63 64 g = lgeos.GEOSGeomFromWKT(c_char_p(geo_input)) 64 65 else: 65 raise GEOSException , 'given string input "%s" unrecognized as WKT or HEXEWKB.' % geo_input66 raise GEOSException('String or unicode input unrecognized as WKT or HEXEWKB.') 66 67 elif isinstance(geo_input, (IntType, GEOSPointer)): 67 68 # When the input is either a memory address (an integer), or a … … 86 87 if srid and isinstance(srid, int): self.srid = srid 87 88 89 # Exported HEX from other GEOS geometries will have -1 SRID -- 90 # set here to 0, when the SRID is not explicitly given. 91 if not srid and from_hex: self.srid = 0 92 88 93 # Setting the class type (e.g., 'Point', 'Polygon', etc.) 89 94 self.__class__ = GEOS_CLASSES[self.geom_type] … … 208 213 if isinstance(self, (Polygon, GeometryCollection)): self._populate() 209 214 210 #### Psycopg2 database adaptor routines ####211 def __conform__(self, proto):212 # Does the given protocol conform to what Psycopg2 expects?213 if proto == ISQLQuote:214 return self215 else:216 raise GEOSException, 'Error implementing psycopg2 protocol. Is psycopg2 installed?'217 218 def getquoted(self):219 "Returns a properly quoted string for use in PostgreSQL/PostGIS."220 # Using ST_GeomFromText(), corresponds to SQL/MM ISO standard.221 return "ST_GeomFromText('%s', %s)" % (self.wkt, self.srid or -1)222 223 215 #### Coordinate Sequence Routines #### 224 216 @property … … 426 418 @property 427 419 def hex(self): 428 "Returns the HEXEWKB of the Geometry." 420 """ 421 Returns the HEX of the Geometry -- please note that the SRID is not 422 included in this representation, because the GEOS C library uses 423 -1 by default, even if the SRID is set. 424 """ 429 425 sz = c_size_t() 430 426 h = lgeos.GEOSGeomToHEX_buf(self._ptr(), byref(sz)) django/branches/gis/django/contrib/gis/geos/libgeos.py
r6314 r6508 18 18 except ImportError: 19 19 HAS_NUMPY = False 20 21 # Is psycopg2 available?22 try:23 from psycopg2.extensions import ISQLQuote24 except (ImportError, EnvironmentError):25 ISQLQuote = None26 20 27 21 # Setting the appropriate name for the GEOS-C library, depending on which
