def area(self, tolerance=0.05, **kwargs): """ Returns the area of the geographic field in an `area` attribute on each element of this GeoQuerySet. """ # Performing setup here rather than in `_spatial_attribute` so that # we can get the units for `AreaField`. procedure_args, geo_field = self._spatial_setup( 'area', field_name=kwargs.get('field_name')) s = {'procedure_args': procedure_args, 'geo_field': geo_field, 'setup': False, } connection = connections[self.db] backend = connection.ops if backend.oracle: s['procedure_fmt'] = '%(geo_col)s,%(tolerance)s' s['procedure_args']['tolerance'] = tolerance s['select_field'] = AreaField('sq_m') # Oracle returns area in units of meters. elif backend.postgis or backend.spatialite: if backend.geography: # Geography fields support area calculation, returns square meters. s['select_field'] = AreaField('sq_m') elif not geo_field.geodetic(connection): # Getting the area units of the geographic field. s['select_field'] = AreaField(Area.unit_attname(geo_field.units_name(connection))) else: # TODO: Do we want to support raw number areas for geodetic fields? raise Exception('Area on geodetic coordinate systems not supported.') return self._spatial_attribute('area', s, **kwargs)
def import_data_for_a_state(state): file_name = filenames_by_state.get(state, None) if file_name is None: return remote_file = f"{remote_folder}{file_name}" response = requests.get(remote_file) data = json.loads(response.text) counter = 0 for feature in data["features"]: properties = feature["properties"] if properties is None: continue counter = counter + 1 land_area = Area(sq_m=properties["ALAND10"]) water_area = Area(sq_m=properties["AWATER10"]) Zipcode.objects.update_or_create( zip_code=properties["ZCTA5CE10"], defaults=dict(state=state.upper(), geometry=feature["geometry"], lat=properties["INTPTLAT10"], lon=properties["INTPTLON10"], land_area=land_area.sq_mi, water_area=water_area.sq_mi), ) return counter
def area(self, tolerance=0.05, **kwargs): """ Returns the area of the geographic field in an `area` attribute on each element of this GeoQuerySet. """ # Peforming setup here rather than in `_spatial_attribute` so that # we can get the units for `AreaField`. procedure_args, geo_field = self._spatial_setup("area", field_name=kwargs.get("field_name", None)) s = {"procedure_args": procedure_args, "geo_field": geo_field, "setup": False} connection = connections[self.db] backend = connection.ops if backend.oracle: s["procedure_fmt"] = "%(geo_col)s,%(tolerance)s" s["procedure_args"]["tolerance"] = tolerance s["select_field"] = AreaField("sq_m") # Oracle returns area in units of meters. elif backend.postgis or backend.spatialite: if backend.geography: # Geography fields support area calculation, returns square meters. s["select_field"] = AreaField("sq_m") elif not geo_field.geodetic(connection): # Getting the area units of the geographic field. s["select_field"] = AreaField(Area.unit_attname(geo_field.units_name(connection))) else: # TODO: Do we want to support raw number areas for geodetic fields? raise Exception("Area on geodetic coordinate systems not supported.") return self._spatial_attribute("area", s, **kwargs)
def convert_values(self, value, field, connection): """ Using the same routines that Oracle does we can convert our extra selection objects into Geometry and Distance objects. TODO: Make converted objects 'lazy' for less overhead. """ if connection.ops.oracle: # Running through Oracle's first. value = super(GeoQuery, self).convert_values(value, field or GeomField(), connection) if value is None: # Output from spatial function is NULL (e.g., called # function on a geometry field with NULL value). pass elif isinstance(field, DistanceField): # Using the field's distance attribute, can instantiate # `Distance` with the right context. value = Distance(**{field.distance_att: value}) elif isinstance(field, AreaField): value = Area(**{field.area_att: value}) elif isinstance(field, (GeomField, GeometryField)) and value: value = Geometry(value) elif field is not None: return super(GeoQuery, self).convert_values(value, field, connection) return value
def from_db_value(self, value, expression, connection, context): if connection.features.interprets_empty_strings_as_nulls and value == '': value = None # If the units are known, convert value into area measure. if value is not None and self.area_att: value = Area(**{self.area_att: value}) return value
def get_area_att_for_field(self, field): if field.geodetic(self.connection): if self.connection.features.supports_area_geodetic: return 'sq_m' raise NotImplementedError('Area on geodetic coordinate systems not supported.') else: units_name = field.units_name(self.connection) if units_name: return AreaMeasure.unit_attname(units_name)
def from_db_value(self, value, expression, connection): # If the database returns a Decimal, convert it to a float as expected # by the Python geometric objects. if isinstance(value, Decimal): value = float(value) # If the units are known, convert value into area measure. if value is not None and self.area_att: value = Area(**{self.area_att: value}) return value
def clean_bounds(self, *args, **kwargs): bounds = self.cleaned_data['bounds'] limit = 50.0 # Transform the bounds to spherical mercator bounds.transform(900913) a = Area(sq_m=bounds.area) if a.sq_mi > limit: raise forms.ValidationError("Bounds cannot be more than %d square miles" % limit) return bounds
def from_db_value(self, value, expression, connection): if value is None: return # If the database returns a Decimal, convert it to a float as expected # by the Python geometric objects. if isinstance(value, Decimal): value = float(value) # If the units are known, convert value into area measure. area_att = connection.ops.get_area_att_for_field(self.geo_field) return Area(**{area_att: value}) if area_att else value
def testInit(self): "Testing initialization from valid units" a = Area(sq_m=100) self.assertEqual(a.sq_m, 100) a = A(sq_m=100) self.assertEqual(a.sq_m, 100) a = A(sq_mi=100) self.assertEqual(a.sq_m, 258998811.0336)
def test_area_lookups(self): # Create projected countries so the test works on all backends. CountryWebMercator.objects.bulk_create( CountryWebMercator(name=c.name, mpoly=c.mpoly.transform(3857, clone=True)) for c in Country.objects.all() ) qs = CountryWebMercator.objects.annotate(area=functions.Area('mpoly')) self.assertEqual(qs.get(area__lt=Area(sq_km=500000)), CountryWebMercator.objects.get(name='New Zealand')) with self.assertRaisesMessage(ValueError, 'AreaField only accepts Area measurement objects.'): qs.get(area__lt=500000)
def from_db_value(self, value, expression, connection, context): if connection.features.interprets_empty_strings_as_nulls and value == '': value = None # If the database returns a Decimal, convert it to a float as expected # by the Python geometric objects. if isinstance(value, Decimal): value = float(value) # If the units are known, convert value into area measure. if value is not None and self.area_att: value = Area(**{self.area_att: value}) return value
def as_sql(self, compiler, connection): if connection.ops.geography: # Geography fields support area calculation, returns square meters. self.output_field = AreaField("sq_m") elif not self.output_field.geodetic(connection): # Getting the area units of the geographic field. units = self.output_field.units_name(connection) if units: self.output_field = AreaField(AreaMeasure.unit_attname(self.output_field.units_name(connection))) else: self.output_field = FloatField() else: # TODO: Do we want to support raw number areas for geodetic fields? raise NotImplementedError("Area on geodetic coordinate systems not supported.") return super(Area, self).as_sql(compiler, connection)
def as_sql(self, compiler, connection): if connection.ops.geography: self.output_field.area_att = 'sq_m' else: # Getting the area units of the geographic field. source_fields = self.get_source_fields() if len(source_fields): source_field = source_fields[0] if source_field.geodetic(connection): # TODO: Do we want to support raw number areas for geodetic fields? raise NotImplementedError('Area on geodetic coordinate systems not supported.') units_name = source_field.units_name(connection) if units_name: self.output_field.area_att = AreaMeasure.unit_attname(units_name) return super(Area, self).as_sql(compiler, connection)
def as_sql(self, compiler, connection, **extra_context): if connection.ops.geography: self.output_field.area_att = 'sq_m' else: # Getting the area units of the geographic field. if self.geo_field.geodetic(connection): if connection.features.supports_area_geodetic: self.output_field.area_att = 'sq_m' else: # TODO: Do we want to support raw number areas for geodetic fields? raise NotImplementedError('Area on geodetic coordinate systems not supported.') else: units_name = self.geo_field.units_name(connection) if units_name: self.output_field.area_att = AreaMeasure.unit_attname(units_name) return super().as_sql(compiler, connection, **extra_context)
def as_sql(self, compiler, connection, **extra_context): if connection.ops.geography: self.output_field.area_att = 'sq_m' else: # Getting the area units of the geographic field. geo_field = self.geo_field if geo_field.geodetic(connection): if connection.features.supports_area_geodetic: self.output_field.area_att = 'sq_m' else: # TODO: Do we want to support raw number areas for geodetic fields? raise NotImplementedError('Area on geodetic coordinate systems not supported.') else: units_name = geo_field.units_name(connection) if units_name: self.output_field.area_att = AreaMeasure.unit_attname(units_name) return super().as_sql(compiler, connection, **extra_context)
def as_sql(self, compiler, connection): if connection.ops.geography: # Geography fields support area calculation, returns square meters. self.output_field = AreaField('sq_m') elif not self.output_field.geodetic(connection): # Getting the area units of the geographic field. units = self.output_field.units_name(connection) if units: self.output_field = AreaField( AreaMeasure.unit_attname(self.output_field.units_name(connection)) ) else: self.output_field = FloatField() else: # TODO: Do we want to support raw number areas for geodetic fields? raise NotImplementedError('Area on geodetic coordinate systems not supported.') return super(Area, self).as_sql(compiler, connection)
def convert_values(self, value, field): """ Using the same routines that Oracle does we can convert our extra selection objects into Geometry and Distance objects. TODO: Laziness. """ if SpatialBackend.oracle: # Running through Oracle's first. value = super(GeoQuery, self).convert_values(value, field) if isinstance(field, DistanceField): # Using the field's distance attribute, can instantiate # `Distance` with the right context. value = Distance(**{field.distance_att: value}) elif isinstance(field, AreaField): value = Area(**{field.area_att: value}) elif isinstance(field, GeomField): value = SpatialBackend.Geometry(value) return value
def render(self, context): report = GeographicReport.objects.get(name=self.name) area = Area(sq_m=Variable(self.area).resolve(context)) random_id = "%s-%s" % (report.name, random.randint(1, 10000)) json = { 'maxScale': report.max_scale, 'annotations': [], 'element': '#%s' % (random_id, ) } for annotation in report.annotation_set.all(): json['annotations'].append({ 'label': annotation.label, 'min': annotation.min, 'max': annotation.max, 'color': '#%s' % (annotation.color, ) }) json = simplejson.dumps(json) return """ <div id="%s" class="geographic_report"></div> <script type="text/javascript" charset="utf-8"> lingcod.onShow('%s', function(){ var persist_id = '%s'; var report = lingcod.persistentReports[persist_id]; if(report){ $('#%s').append(report.paper.canvas); }else{ report = lingcod.geographicReport(%s); if(!$.browser.msie){ lingcod.persistentReports[persist_id] = report; } } report.updateValue(%s, true); }); </script> """ % (random_id, self.tab_id, self.persist, random_id, json, area.sq_mi)
import warnings
from decimal import Decimal
def from_db_value(self, value, connection): if value is not None: value = Area(**{self.area_att: value}) return value
def from_db_value(self, value, expression, connection, context): if connection.features.interprets_empty_strings_as_nulls and value == '': value = None if value is not None: value = Area(**{self.area_att: value}) return value
def from_db_value(self, value, expression, connection, context): if value is not None: value = Area(**{self.area_att: value}) return value
return area_att = connection.ops.get_area_att_for_field(self.geo_field) return getattr(value, area_att) if area_att else value def from_db_value(self, value, expression, connection): if value is None: return >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 # If the database returns a Decimal, convert it to a float as expected # by the Python geometric objects. if isinstance(value, Decimal): value = float(value) # If the units are known, convert value into area measure. <<<<<<< HEAD if value is not None and self.area_att: value = Area(**{self.area_att: value}) return value ======= area_att = connection.ops.get_area_att_for_field(self.geo_field) return Area(**{area_att: value}) if area_att else value >>>>>>> 37c99181c9a6b95433d60f8c8ef9af5731096435 def get_internal_type(self): return 'AreaField' <<<<<<< HEAD class DistanceField(BaseField): "Wrapper for Distance values." def __init__(self, distance_att): self.distance_att = distance_att