def get_prep_value(self, value): obj = super().get_prep_value(value) # When the input is not a geometry or raster, attempt to construct one # from the given string input. if isinstance(obj, Geometry): pass else: # Check if input is a candidate for conversion to raster or geometry. is_candidate = isinstance(obj, (bytes, str)) or hasattr(obj, '__geo_interface__') # Try to convert the input to raster. raster = self.get_raster_prep_value(obj, is_candidate) if raster: obj = raster elif is_candidate: try: obj = Geometry(obj) except (GeometryException, GDALException): raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) else: raise ValueError('Cannot use object with type %s for a spatial lookup parameter.' % type(obj).__name__) # Assigning the SRID value. obj.srid = self.get_srid(obj) return obj
def from_db_value(self, value, expression, connection, context): if value: if not isinstance(value, Geometry): value = Geometry(value) srid = value.srid if not srid and self.srid != -1: value.srid = self.srid return value
def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be converted to) a geometry or raster, or a sequence of lookup values that begins with a geometry or raster. This routine sets up the geometry or raster value properly and preserves any other lookup parameters. """ value = super(BaseSpatialField, self).get_prep_value(value) # For IsValid lookups, boolean values are allowed. if isinstance(value, (Expression, bool)): return value elif isinstance(value, (tuple, list)): obj = value[0] seq_value = True else: obj = value seq_value = False # When the input is not a geometry or raster, attempt to construct one # from the given string input. if isinstance(obj, Geometry): pass else: # Check if input is a candidate for conversion to raster or geometry. is_candidate = isinstance(obj, (bytes, six.string_types)) or hasattr(obj, '__geo_interface__') # With GDAL installed, try to convert the input to raster. raster = False if HAS_GDAL: raster = self.get_raster_prep_value(obj, is_candidate) if raster: obj = raster elif is_candidate: try: obj = Geometry(obj) except (GeometryException, GDALException): raise ValueError("Couldn't create spatial object from lookup value '%s'." % obj) else: raise ValueError('Cannot use object with type %s for a spatial lookup parameter.' % type(obj).__name__) # Assigning the SRID value. obj.srid = self.get_srid(obj) if seq_value: lookup_val = [obj] lookup_val.extend(value[1:]) return tuple(lookup_val) else: return obj
def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be converted to) a geometry, or a sequence of lookup values that begins with a geometry. This routine will setup the geometry value properly, and preserve any other lookup parameters before returning to the caller. """ from django.contrib.gis.gdal import GDALRaster value = super(GeometryField, self).get_prep_value(value) if isinstance(value, (Expression, bool)): return value elif isinstance(value, (tuple, list)): geom = value[0] seq_value = True else: geom = value seq_value = False # When the input is not a GEOS geometry, attempt to construct one # from the given string input. if isinstance(geom, (Geometry, GDALRaster)): pass elif isinstance(geom, (bytes, six.string_types)) or hasattr(geom, '__geo_interface__'): try: geom = Geometry(geom) except GeometryException: raise ValueError('Could not create geometry from lookup value.') else: raise ValueError('Cannot use object with type %s for a geometry lookup parameter.' % type(geom).__name__) # Assigning the SRID value. geom.srid = self.get_srid(geom) if seq_value: lookup_val = [geom] lookup_val.extend(value[1:]) return tuple(lookup_val) else: return geom
def get_prep_value(self, value): """ Spatial lookup values are either a parameter that is (or may be converted to) a geometry, or a sequence of lookup values that begins with a geometry. This routine will setup the geometry value properly, and preserve any other lookup parameters before returning to the caller. """ if isinstance(value, SQLEvaluator): return value elif isinstance(value, (tuple, list)): geom = value[0] seq_value = True else: geom = value seq_value = False # When the input is not a GEOS geometry, attempt to construct one # from the given string input. if isinstance(geom, Geometry): pass elif isinstance(geom, basestring) or hasattr(geom, '__geo_interface__'): try: geom = Geometry(geom) except GeometryException: raise ValueError('Could not create geometry from lookup value.') else: raise ValueError('Cannot use parameter of `%s` type as lookup parameter.' % type(value)) # Assigning the SRID value. geom.srid = self.get_srid(geom) if seq_value: lookup_val = [geom] lookup_val.extend(value[1:]) return tuple(lookup_val) else: return geom
from django.contrib.gis import forms
"""
def convert_geometry(self, value, expression, connection, context): if value: value = Geometry(value) if 'transformed_srid' in context: value.srid = context['transformed_srid'] return value
def from_db_value(self, value, expression, connection, context): if value is not None: value = Geometry(value) return value
def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, **kwargs): """ DRY routine for GeoQuerySet distance attribute routines. """ # Setting up the distance procedure arguments. procedure_args, geo_field = self._spatial_setup(func, field_name=kwargs.get( 'field_name', None)) # If geodetic defaulting distance attribute to meters (Oracle and # PostGIS spherical distances return meters). Otherwise, use the # units of the geometry field. connection = connections[self.db] geodetic = geo_field.geodetic(connection) geography = geo_field.geography if geodetic: dist_att = 'm' else: dist_att = Distance.unit_attname(geo_field.units_name(connection)) # Shortcut booleans for what distance function we're using and # whether the geometry field is 3D. distance = func == 'distance' length = func == 'length' perimeter = func == 'perimeter' if not (distance or length or perimeter): raise ValueError('Unknown distance function: %s' % func) geom_3d = geo_field.dim == 3 # The field's get_db_prep_lookup() is used to get any # extra distance parameters. Here we set up the # parameters that will be passed in to field's function. lookup_params = [geom or 'POINT (0 0)', 0] # Getting the spatial backend operations. backend = connection.ops # If the spheroid calculation is desired, either by the `spheroid` # keyword or when calculating the length of geodetic field, make # sure the 'spheroid' distance setting string is passed in so we # get the correct spatial stored procedure. if spheroid or (backend.postgis and geodetic and (not geography) and length): lookup_params.append('spheroid') lookup_params = geo_field.get_prep_value(lookup_params) params = geo_field.get_db_prep_lookup('distance_lte', lookup_params, connection=connection) # The `geom_args` flag is set to true if a geometry parameter was # passed in. geom_args = bool(geom) if backend.oracle: if distance: procedure_fmt = '%(geo_col)s,%(geom)s,%(tolerance)s' elif length or perimeter: procedure_fmt = '%(geo_col)s,%(tolerance)s' procedure_args['tolerance'] = tolerance else: # Getting whether this field is in units of degrees since the field may have # been transformed via the `transform` GeoQuerySet method. if self.query.transformed_srid: u, unit_name, s = get_srid_info(self.query.transformed_srid, connection) geodetic = unit_name in geo_field.geodetic_units if backend.spatialite and geodetic: raise ValueError( 'SQLite does not support linear distance calculations on geodetic coordinate systems.' ) if distance: if self.query.transformed_srid: # Setting the `geom_args` flag to false because we want to handle # transformation SQL here, rather than the way done by default # (which will transform to the original SRID of the field rather # than to what was transformed to). geom_args = False procedure_fmt = '%s(%%(geo_col)s, %s)' % ( backend.transform, self.query.transformed_srid) if geom.srid is None or geom.srid == self.query.transformed_srid: # If the geom parameter srid is None, it is assumed the coordinates # are in the transformed units. A placeholder is used for the # geometry parameter. `GeomFromText` constructor is also needed # to wrap geom placeholder for SpatiaLite. if backend.spatialite: procedure_fmt += ', %s(%%%%s, %s)' % ( backend.from_text, self.query.transformed_srid) else: procedure_fmt += ', %%s' else: # We need to transform the geom to the srid specified in `transform()`, # so wrapping the geometry placeholder in transformation SQL. # SpatiaLite also needs geometry placeholder wrapped in `GeomFromText` # constructor. if backend.spatialite: procedure_fmt += ', %s(%s(%%%%s, %s), %s)' % ( backend.transform, backend.from_text, geom.srid, self.query.transformed_srid) else: procedure_fmt += ', %s(%%%%s, %s)' % ( backend.transform, self.query.transformed_srid) else: # `transform()` was not used on this GeoQuerySet. procedure_fmt = '%(geo_col)s,%(geom)s' if not geography and geodetic: # Spherical distance calculation is needed (because the geographic # field is geodetic). However, the PostGIS ST_distance_sphere/spheroid() # procedures may only do queries from point columns to point geometries # some error checking is required. if not backend.geography: if not isinstance(geo_field, PointField): raise ValueError( 'Spherical distance calculation only supported on PointFields.' ) if not str( Geometry(memoryview( params[0].ewkb)).geom_type) == 'Point': raise ValueError( 'Spherical distance calculation only supported with Point Geometry parameters' ) # The `function` procedure argument needs to be set differently for # geodetic distance calculations. if spheroid: # Call to distance_spheroid() requires spheroid param as well. procedure_fmt += ",'%(spheroid)s'" procedure_args.update({ 'function': backend.distance_spheroid, 'spheroid': params[1] }) else: procedure_args.update( {'function': backend.distance_sphere}) elif length or perimeter: procedure_fmt = '%(geo_col)s' if not geography and geodetic and length: # There's no `length_sphere`, and `length_spheroid` also # works on 3D geometries. procedure_fmt += ",'%(spheroid)s'" procedure_args.update({ 'function': backend.length_spheroid, 'spheroid': params[1] }) elif geom_3d and backend.postgis: # Use 3D variants of perimeter and length routines on PostGIS. if perimeter: procedure_args.update( {'function': backend.perimeter3d}) elif length: procedure_args.update({'function': backend.length3d}) # Setting up the settings for `_spatial_attribute`. s = { 'select_field': DistanceField(dist_att), 'setup': False, 'geo_field': geo_field, 'procedure_args': procedure_args, 'procedure_fmt': procedure_fmt, } if geom_args: s['geom_args'] = ('geom', ) s['procedure_args']['geom'] = geom elif geom: # The geometry is passed in as a parameter because we handled # transformation conditions in this routine. s['select_params'] = [backend.Adapter(geom)] return self._spatial_attribute(func, s, **kwargs)
def from_db_value(self, value, connection): if value: value = Geometry(value) return value
def from_db_value(self, value, connection): if value and not isinstance(value, Geometry): value = Geometry(value) return value
if version < (4, 0, 0): raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 4.0.0 and above.') return version <<<<<<< HEAD def convert_extent(self, box, srid): ======= def convert_extent(self, box): >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 """ Convert the polygon data received from SpatiaLite to min/max values. """ if box is None: return None <<<<<<< HEAD shell = Geometry(box, srid).shell ======= shell = GEOSGeometry(box).shell >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 xmin, ymin = shell[0][:2] xmax, ymax = shell[2][:2] return (xmin, ymin, xmax, ymax) def geo_db_type(self, f): """ <<<<<<< HEAD Returns None because geometry columns are added via the ======= Return None because geometry columns are added via the >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 `AddGeometryColumn` stored procedure on SpatiaLite.
def convert_geom(self, clob, geo_field): if clob: return Geometry(clob.read(), geo_field.srid) else: return None
def convert_geometry(self, value, expression, context): if value: value = Geometry(value) if "transformed_srid" in context: value.srid = context["transformed_srid"] return value
'AsGeoJSON', 'AsKML', 'AsSVG', 'Azimuth', 'Envelope', 'ForceRHR', 'GeoHash', 'LineLocatePoint', 'MakeValid', 'MemSize', 'Scale', 'SnapToGrid', 'Translate', } def geo_quote_name(self, name): return super().geo_quote_name(name).upper() def convert_extent(self, clob): >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 if clob: # Generally, Oracle returns a polygon for the extent -- however, # it can return a single point if there's only one Point in the # table. <<<<<<< HEAD ext_geom = Geometry(clob.read(), srid) ======= ext_geom = GEOSGeometry(memoryview(clob.read())) >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 gtype = str(ext_geom.geom_type) if gtype == 'Polygon': # Construct the 4-tuple from the coordinates in the polygon. shell = ext_geom.shell ll, ur = shell[0][:2], shell[2][:2] elif gtype == 'Point': ll = ext_geom.coords[:2] ur = ll else: raise Exception('Unexpected geometry type returned for extent: %s' % gtype) xmin, ymin = ll xmax, ymax = ur