def import_data_into_point_model(resource_type, Model, row, dry_run=False): print("import_data_into_point_model", row) point = None location_fuzzy = False name_fields = Model.NAME_FIELD.split(",") name = ", ".join([str(row[name_field]) for name_field in name_fields]) try: point = Point(float(row[Model.LONGITUDE_FIELD]), float(row[Model.LATITUDE_FIELD]), srid=4326) closest_community = (Community.objects.annotate( distance=Distance('point', point)).order_by('distance').first()) except TypeError: # When no point is present, try the municipality name description if not row.get("MUNICIPALITY"): print( "Skipping error:", name, "has no municipality, geometry, or matching municipality name!", ) return closest_community = Community.objects.filter( place_name__icontains=_try_community_name(row)).first() if not closest_community: print( "Skipping error:", name, "in", row["MUNICIPALITY"], "has no geometry or matching municipality name!", ) return point = closest_community.point # if the point is inferred, set the location_fuzzy flag to True location_fuzzy = True try: instance = Model.objects.get(name=name, location_type=resource_type, point=point) except Model.DoesNotExist: instance = Model(name=name, location_type=resource_type, point=point) print("closest_community", closest_community) instance.closest_community = closest_community instance.location_fuzzy = location_fuzzy import_contact_fields(instance, row, Model) import_variable_fields(instance, row, Model) instance.save() calculate_distances(instance, dry_run=dry_run) return instance
def forward_geocode(address, disambiguate=True): """ Looks up geo data pertaining to `address`, but distinguish addresses with different cities. :param address: :return: """ result = OD([('geom', {}), ('parcel_id', ''), ('regions', {}), ('status', 'ERROR')]) try: # get point point = geocode_from_address_string(address, disambiguate) if disambiguate and point is None: result['status'] = "Unable to geocode this address to a single unambigous point." return result result['geom'] = {'type': 'Point', 'coordinates': list(point.coords)} result['status'] = 'WARNING: Only found point of address' # get regions regions = AdminRegion.objects.filter(geom__contains=point) result['regions'] = {region.type.id: { 'id': region.name, 'name': region.title} for region in regions} result['status'] = 'WARNING: Only found point of address and regions' # get parcel parcels = Parcel.objects.filter(geom__contains=point) if not parcels: close_parcels = Parcel.objects.filter( geom__dwithin=(point, 0.0002)) ordered_parcels = sorted(close_parcels.annotate( distance=Distance('geom', point)), key=lambda obj_: obj_.distance) parcel = ordered_parcels[0] result['status'] = 'WARNING: using closed parcel to address point.' elif len(parcels) == 1: parcel = parcels[0] result['status'] = 'OK' else: # Why are there multiple parcels here that contain the point? if not disambiguate: parcel = parcels[0] result['status'] = 'OK' else: result['status'] = "There are {} parcels that contain the point ({}, {}).".format(len(parcels), point.x, point.y) result['parcel_id'] = parcel.pin except: if not disambiguate: pass else: exc_type, exc_value, exc_traceback = sys.exc_info() print("Error: {}".format(exc_type)) lines = traceback.format_exception(exc_type, exc_value, exc_traceback) print(''.join('!!! ' + line for line in lines)) import re result['status'] = re.sub('\n', '|', ''.join('!!! ' + line for line in lines)) finally: return result
def test_distance_geodetic_spheroid(self): tol = 2 if oracle else 4 # Got the reference distances using the raw SQL statements: # SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), # 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11)); # SELECT ST_distance_sphere(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326)) # FROM distapp_australiacity WHERE (NOT (id = 11)); st_distance_sphere spheroid_distances = [ 60504.0628957201, 77023.9489850262, 49154.8867574404, 90847.4358768573, 217402.811919332, 709599.234564757, 640011.483550888, 7772.00667991925, 1047861.78619339, 1165126.55236034, ] sphere_distances = [ 60580.9693849267, 77144.0435286473, 49199.4415344719, 90804.7533823494, 217713.384600405, 709134.127242793, 639828.157159169, 7786.82949717788, 1049204.06569028, 1162623.7238134, ] # Testing with spheroid distances first. hillsdale = AustraliaCity.objects.get(name='Hillsdale') qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate( distance=Distance('point', hillsdale.point, spheroid=True)).order_by('id') for i, c in enumerate(qs): self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol) if postgis or spatialite: # PostGIS uses sphere-only distances by default, testing these as well. qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate( distance=Distance('point', hillsdale.point)).order_by('id') for i, c in enumerate(qs): self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
def handle(self, *args, **options): for airnow in AirNow.objects.filter(reference_calibrator__isnull=True): # Get the closest PurpleAir. We don't care about activity, # we're just looking to set something up and will hand-curate. purpleair = (PurpleAir.objects.annotate(distance=Distance( "position", airnow.position)).order_by('distance')).first() calibrator = Calibrator.objects.create(reference=airnow, colocated=purpleair)
def find_best_for(self, latitude: float, longitude: float): origin = Point(longitude, latitude, srid=4326) return ( self.filter( catchment_area__contains=Point(longitude, latitude), ) .annotate(distance=Distance("geocoded_point", origin)) .order_by("distance") )
def get_queryset(self, request): qs = super().get_queryset(request) user = request.user if user.profile and user.profile.city: user_city = user.profile.city qs = qs.select_related( 'city', 'country', 'model', 'generation').annotate( distance=Distance('city__point', user_city.point)) return qs
def get_hospitals(request): longitude = float(request.data['long']) latitude = float(request.data['lat']) user_location = Point(longitude, latitude, srid=4326) hospitals = serialize( 'geojson', queryset=Hospital.objects.annotate(distance=Distance( 'location', user_location)).order_by('distance')[0:10]) return Response(data={'data': json.loads(hospitals)})
def get_queryset(self): organizations = Organization.objects.all() if 'hub' in self.request.query_params: project_category = Hub.objects.get( url_slug=self.request.query_params.get( 'hub')).filter_parent_tags.all() project_category_ids = list(map(lambda c: c.id, project_category)) project_tags = ProjectTags.objects.filter( id__in=project_category_ids) project_tags_with_children = ProjectTags.objects.filter( Q(parent_tag__in=project_tags) | Q(id__in=project_tags)) organizations = organizations.filter( Q(project_parent_org__project__tag_project__project_tag__in= project_tags_with_children) | Q(field_tag_organization__field_tag__in= project_tags_with_children)).distinct() if 'organization_type' in self.request.query_params: organization_type_names = self.request.query_params.get( 'organization_type').split(',') organization_types = OrganizationTags.objects.filter( name__in=organization_type_names) organization_taggings = OrganizationTagging.objects.filter( organization_tag__in=organization_types) organizations = organizations.filter( tag_organization__in=organization_taggings).distinct('id') if 'place' in self.request.query_params and 'osm' in self.request.query_params: location_data = get_location_with_range(self.request.query_params) organizations = organizations.filter( Q(location__country=location_data['country']) & (Q(location__multi_polygon__coveredby=( location_data['location'])) | Q(location__centre_point__coveredby=( location_data['location'])))).annotate( distance=Distance( "location__centre_point", location_data['location'])).order_by('distance') if 'country' and 'city' in self.request.query_params: location_ids = Location.objects.filter( country=self.request.query_params.get('country'), city=self.request.query_params.get('city')) organizations = organizations.filter(location__in=location_ids) if 'city' in self.request.query_params and not 'country' in self.request.query_params: location_ids = Location.objects.filter( city=self.request.query_params.get('city')) organizations = organizations.filter(location__in=location_ids) if 'country' in self.request.query_params and not 'city' in self.request.query_params: location_ids = Location.objects.filter( country=self.request.query_params.get('country')) organizations = organizations.filter(location__in=location_ids) return organizations
def update_nearest_secondary_school(self, distance=1000): schools = School.objects.filter( point__dwithin=(self.geom, D(m=distance)), school_type='SECONDARY').annotate( distance=Distance('point', self.geom)).order_by('distance') if len(schools) > 0: self.nearest_secondary_school = schools[0] self.nearest_secondary_school_distance = schools[0].distance.m
def test_db_function_errors(self): """ Errors are raised when using DB functions with raster content. """ point = GEOSGeometry( "SRID=3086;POINT (-697024.9213808845 683729.1705516104)") rast = GDALRaster(json.loads(JSON_RASTER)) msg = "Please provide a geometry object." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("geom", rast)) with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("rastprojected", rast)) msg = "Geometry functions not supported for raster fields." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("rastprojected", point)).count()
def filter_radius(self, queryset, name, value: float): lat = float(self.data["lat"]) lng = float(self.data["lng"]) p = Point(lat, lng, srid=4326) queryset = queryset.filter(location__distance_lte=(p, D( m=value))).annotate(distance=Distance("location", p)) return queryset
def get_object_list(self, request): ip = request.META.get('REMOTE_ADDR') if ip: point = geo_ip2.geos(ip) else: # let's show them our favorite tacos point = geo_ip2.geos('1.1.1.1') return super().get_object_list(request).annotate(distance=Distance('location', point))
def lieux(request, latitude, longitude, distance): qs = Lieu.objects.all()\ .annotate(distance=Distance(F("position"), Point(y=latitude, x=longitude, srid=4326)))\ .filter(distance__lt=D(m=distance).m)\ .order_by("distance") return render(request, "api/lieux.json", {"lieux": qs}, content_type="text/json; charset=utf8")
def test_db_function_errors(self): """ Errors are raised when using DB functions with raster content. """ point = GEOSGeometry( "SRID=3086;POINT (-697024.9213808845 683729.1705516104)") rast = GDALRaster(json.loads(JSON_RASTER)) msg = "Distance function requires a geometric argument in position 2." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("geom", rast)) with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("rastprojected", rast)) msg = "Distance function requires a GeometryField in position 1, got RasterField." with self.assertRaisesMessage(TypeError, msg): RasterModel.objects.annotate( distance_from_point=Distance("rastprojected", point)).count()
def get_restaurants(longitude, latitude): current_point = geos.fromstr("POINT(%s %s)" % (longitude, latitude), srid=4326) distance_from_point = {'km': 100} restaurants = Restaurant.objects.filter(coordinates__distance_lte=( current_point, measure.D(**distance_from_point) )).annotate( distance=Distance('coordinates', current_point)).order_by('distance') return restaurants
def get_queryset(self): lat = self.kwargs.get('lat') long = self.kwargs.get('long') user_location = Point(float(long), float(lat), srid=4326) filtered_posts = Post.objects.annotate( distance=Distance('locat', user_location)).order_by('distance') return filtered_posts
def test_distance_function_tolerance_escaping(self): qs = Interstate.objects.annotate(d=Distance( Point(500, 500, srid=3857), Point(0, 0, srid=3857), tolerance='0.05) = 1 OR 1=1 OR (1+1', ), ).filter(d=D(m=1)).values('pk') msg = 'The tolerance parameter has the wrong type' with self.assertRaisesMessage(TypeError, msg): qs.exists()
def get_queryset(self): queryset = Service.objects.all() #Order all the services by distance to the requester user location if not self.request.user.is_anonymous(): ref_location = self.request.user.location if ref_location: queryset = queryset.annotate(distance=Distance('author__location', ref_location)).order_by('distance') return queryset
def test_distance_function(self): """ Testing Distance() support on non-point geography fields. """ ref_dists = [0, 4891.20, 8071.64, 9123.95] htown = City.objects.get(name='Houston') qs = Zipcode.objects.annotate(distance=Distance('poly', htown.point)) for z, ref in zip(qs, ref_dists): self.assertAlmostEqual(z.distance.m, ref, 2)
def test_distance_geodetic_spheroid(self): tol = 2 if oracle else 4 # Got the reference distances using the raw SQL statements: # SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), # 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11)); # SELECT ST_distance_sphere(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326)) # FROM distapp_australiacity WHERE (NOT (id = 11)); st_distance_sphere if connection.ops.postgis and connection.ops.proj_version_tuple() >= (4, 7, 0): # PROJ.4 versions 4.7+ have updated datums, and thus different # distance values. spheroid_distances = [60504.0628957201, 77023.9489850262, 49154.8867574404, 90847.4358768573, 217402.811919332, 709599.234564757, 640011.483550888, 7772.00667991925, 1047861.78619339, 1165126.55236034] sphere_distances = [60580.9693849267, 77144.0435286473, 49199.4415344719, 90804.7533823494, 217713.384600405, 709134.127242793, 639828.157159169, 7786.82949717788, 1049204.06569028, 1162623.7238134] else: spheroid_distances = [60504.0628825298, 77023.948962654, 49154.8867507115, 90847.435881812, 217402.811862568, 709599.234619957, 640011.483583758, 7772.00667666425, 1047861.7859506, 1165126.55237647] sphere_distances = [60580.7612632291, 77143.7785056615, 49199.2725132184, 90804.4414289463, 217712.63666124, 709131.691061906, 639825.959074112, 7786.80274606706, 1049200.46122281, 1162619.7297006] # Testing with spheroid distances first. hillsdale = AustraliaCity.objects.get(name='Hillsdale') qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate( distance=Distance('point', hillsdale.point, spheroid=True) ).order_by('id') for i, c in enumerate(qs): self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol) if postgis: # PostGIS uses sphere-only distances by default, testing these as well. qs = AustraliaCity.objects.exclude(id=hillsdale.id).annotate( distance=Distance('point', hillsdale.point) ).order_by('id') for i, c in enumerate(qs): self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol)
def index(request): telecoms = [] form = OperatorsForm(request.POST) message = "Vous devez remplir au préalable le formulaire pour voir des résultats." if request.method == 'POST' and form.is_valid(): telecoms = Operators.objects lat = request.POST.get("lat") longitude = request.POST.get("longitude") message = "Aucun résultat n'a été trouvé pour votre recherche" try: lat = float(lat) longitude = float(longitude) except: raise Exception("Veuillez saisir une adresse valide") if request.POST.get("operators") != OPERATORS[0] and request.POST.get( "operators") in OPERATORS: telecoms = telecoms.filter( adm_lb_nom=request.POST.get("operators")) if request.POST.get("generation") != GENERATIONS[ 0] and request.POST.get("generation") in GENERATIONS: telecoms = telecoms.filter( generation=request.POST.get("generation")) if request.POST.get("statut") != STATUT[0] and request.POST.get( "statut") in STATUT: telecoms = telecoms.filter(statut=request.POST.get("statut")) if request.POST.get("sous_operator") != S_OPERATORS[ 0] and request.POST.get("sous_operator") in S_OPERATORS: telecoms = telecoms.filter( sous_operator=request.POST.get("sous_operator")) if request.POST.get("forfait"): try: telecoms = telecoms.filter( forfait__lte=float(request.POST.get("forfait"))) except: raise Exception('Veuillez entrer un prix valide') point = fromstr(f'POINT({longitude} {lat})', srid=4326) telecoms = telecoms.filter( location__dwithin=(point, distance_to_decimal_degrees(D( km=500), lat))).annotate( distance=Distance('location', point)) telecoms = telecoms.order_by('distance')[:3] return render(request, "index.html", { 'telecoms': telecoms, 'form': form, 'message': message })
def closest_to(self, point, type=None): qs = self.filter(point__distance_lte=(point, D(mi=100))) if type: qs = qs.filter(type=type) qs = qs.annotate(distance=Distance("point", point)) qs = qs.order_by("distance") try: return qs[0] except IndexError: return None
def eventsnearme(request): if request.method == 'POST': longitude = request.POST['longitude'] latitude = request.POST['latitude'] location = Point(longitude, latitude, srid=4326) eventsnear = serialize( 'geojson', Events.objects.annotate(distance=Distance( 'position', location)).order_by('distance').first()) return HttpResponse(eventsnear, content_type='json')
def get_closest_area(self, max_distance=50): if self.location: location = self.location else: return None closest_area = ParkingArea.objects.annotate(distance=Distance( 'geom', location), ).filter( distance__lte=max_distance).order_by('distance').first() return closest_area
def get_queryset(self): search = super().get_queryset() lat = self.request.query_params.get('lat') long = self.request.query_params.get('lng') if lat and long: point = GEOSGeometry('POINT(' + str(long) + ' ' + str(lat) + ')', srid=4326) search = search.annotate(distance=Distance('coverageArea', point)).order_by('coverageArea') return search
def get_queryset(self): queryset = Restaurant.objects.are_open() try: longitude = float(self.request.query_params.get('longitude', None)) latitude = float(self.request.query_params.get('latitude', None)) except: return queryset else: user_location = Point(longitude, latitude, srid=4326) return queryset.annotate(distance=Distance('location', user_location)).order_by('distance')
def User_Adress(request): adress = "Adresss" # Use DJANGO_FORM . Under construction geolocator = Nominatim(user_agent="nominatum") location = geolocator.geocode(adress) user_location = Point(location.longitude, location.latitude, srid=4326) queryset = Agent.objects.annotate( distance=Distance('location', user_location)).order_by('distance')[0:6] context = {'adress': location, 'object_list': queryset} return render(request, 'test.html', context)
def update_nearest_broadband(self, distance=500): broadbands = Broadband.objects.filter( point__dwithin=(self.geom, D(m=distance))).annotate( distance=Distance('point', self.geom)).order_by('distance') if len(broadbands) > 0: self.nearest_broadband = broadbands[0] self.nearest_broadband_distance = broadbands[0].distance.m if broadbands[0].speed_30_mb_percentage > 0: self.nearest_broadband_fast = True
def get_nearby_stores_within(latitude: float, longitude: float, km: int=10, limit: int=None, srid: int=4326): coordinates = Point(longitude, latitude, srid=srid) point = GEOSGeometry(coordinates, srid=4326) return Store.objects.annotate( distance=Distance("location", coordinates )).filter( location__distance_lte=(point, D(km=km)) ).order_by( 'distance' )[0:limit]
def find_and_send(cls, trip): """Find and send alarms Takes a newly created trip and searches through all alarms to find matches. If any are found, send them. """ # Start by filtering the easy ones # and then filter using expensive fields alarms = cls.objects.exclude( # Alarms that already ended should not be queried Q(datetime_lte__isnull=False) & Q(datetime_lte__lte=timezone.now()) ).filter( # If the alarm defined auto_approve, filter it Q(auto_approve__isnull=True) | Q(auto_approve=trip.auto_approve) ).filter( # If the alarm defined price, filter it Q(price__isnull=True) | Q(price__gte=trip.price) ).filter( # If the alarm defined min_seats, filter it Q(min_seats__isnull=True) | Q(min_seats__lte=trip.max_seats) ).filter( # If the alarm defined datetime_gte, filter it Q(datetime_gte__isnull=True) | Q(datetime_gte__lte=trip.datetime) ).filter( # If the alarm defined datetime_lte, filter it Q(datetime_lte__isnull=True) | Q(datetime_lte__gte=trip.datetime) ).annotate( # First annotate the distances, since django can't compute # F expressions inside D functions, per # https://gis.stackexchange.com/questions/176735/geodjango-distance-filter-based-on-database-column origin_distance=Distance('origin_point', trip.origin_point), destination_distance=Distance('destination_point', trip.destination_point) ).filter( # Filter origin origin_distance__lte=F('origin_radius') * 1000 ).filter( # Filter destination destination_distance__lte=F('destination_radius') * 1000 ) alarm_webhooks.MultipleAlarmsWebhook(alarms, trip).send() # Clear selected alarms alarms.delete()