示例#1
0
 def testUnitAttName(self):
     "Testing the `unit_attname` class method"
     unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'),
                   ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')]
     for nm, att in unit_tuple:
         with self.subTest(nm=nm):
             self.assertEqual(att, D.unit_attname(nm))
示例#2
0
 def testUnitAttName(self):
     "Testing the `unit_attname` class method"
     unit_tuple = [
         ("Yard", "yd"),
         ("Nautical Mile", "nm"),
         ("German legal metre", "german_m"),
         ("Indian yard", "indian_yd"),
         ("Chain (Sears)", "chain_sears"),
         ("Chain", "chain"),
     ]
     for nm, att in unit_tuple:
         self.assertEqual(att, D.unit_attname(nm))
示例#3
0
 def test_nearby_query(self):
     # Creates the available journeys with driver...
     user1 = UserFactory()
     residence1 = ResidenceFactory(user=user1,
                                   position=Point(
                                       883877.34,
                                       547084.05,
                                       srid=DEFAULT_PROJECTED_SRID))
     user2 = UserFactory()
     residence2 = ResidenceFactory(user=user2,
                                   position=Point(
                                       882823.07,
                                       545542.48,
                                       srid=DEFAULT_PROJECTED_SRID))
     campus = CampusFactory()
     user3 = UserFactory()
     residence3 = ResidenceFactory(user=user3,
                                   position=Point(
                                       865621.24,
                                       545274.90,
                                       srid=DEFAULT_PROJECTED_SRID))
     JourneyFactory(user=user1,
                    driver=user1,
                    residence=residence1,
                    campus=campus)
     JourneyFactory(user=user2,
                    driver=user2,
                    residence=residence2,
                    campus=campus)
     JourneyFactory(user=user3,
                    driver=user3,
                    residence=residence3,
                    campus=campus)
     point = Point(882532.74, 545437.43, srid=DEFAULT_PROJECTED_SRID)
     self.assertEquals(
         Journey.objects.nearby(geometry=point, distance=D(m=2500)).count(),
         2)
示例#4
0
文件: views.py 项目: SilasX/parkapp
 def get_queryset(self):
     queryset = ParkingSpot.objects.all()
     near = self.request.query_params.get('near')
     distance = self.request.query_params.get('distance')
     if near:
         # user has specified a near parameter, looking for
         # objects within a certain distance; assume distance
         # is in km
         try:
             point = fromstr(near, srid=4326)
             if distance:
                 try:
                     distance = float(distance)
                 except ValueError:
                     # Default to 2 km.
                     distance = 2
             else:
                 distance = 2
             queryset = queryset.filter(
                 location__distance_lte=(point, D(km=distance)))
         except ValueError:
             # Ignore all the above and just return queryset
             return queryset
     return queryset
示例#5
0
    def get_venue_mapping_for_places(self,
                                     places,
                                     coordinates=None,
                                     radius=None,
                                     **kwargs):
        ident_list = [p['ident'] for p in places]
        qs = VenueRequest.objects.filter(ident__in=ident_list)

        if coordinates is not None:
            point = Point(coordinates[1], coordinates[0])
            if radius:
                radius = int(radius * 0.9)
            else:
                radius = 500
            qs = qs.union(
                VenueRequest.objects.exclude(
                    ident__startswith=self.name +
                    ':').filter(geo__isnull=False).filter(
                        geo__dwithin=(point, radius)).filter(
                            geo__distance_lte=(point, D(m=radius)))[:50])

        vris = VenueRequestItem.objects.select_related('foirequest')
        qs = qs.prefetch_related(Prefetch('request_items', queryset=vris))
        return {r.ident: r for r in qs}
def run():
    # Delete previous data
    # RoadData_snapped.objects.all().delete()
    rp = RoadPothole.objects.all()

    # Seetting the nearest road api
    search_distance = 50

    for r in rp:
        input_pt = Point(r.point.x, r.point.y)

        # matched_points = RoadPoint.objects.filter(point__distance_lt=(input_pt,D(m=search_distance)))
        matched_points = RoadData_snapped.objects.filter(
            center__distance_lt=(input_pt, D(m=search_distance)))

        if len(matched_points) != 0:
            pothole = matched_points[0]
            pothole.rating = (pothole.rating * pothole.total_potholes +
                              r.rating) / (pothole.total_potholes + 1)
            pothole.total_potholes = pothole.total_potholes + 1

            pothole.save()

    print(len(RoadData_snapped.objects.all()))
示例#7
0
def node_layer_validation(self):
    """
    1. if minimum distance is specified, ensure node is not too close to other nodes;
    2. if layer defines an area, ensure node coordinates are contained in the area
    """
    try:
        minimum_distance = self.layer.minimum_distance
        geometry = self.geometry
        layer_area = self.layer.area
    except ObjectDoesNotExist:
        # this happens if node.layer is None
        return

    # TODO - lower priority: do this check only when coordinates are changing
    if minimum_distance > 0:
        near_nodes = Node.objects.exclude(pk=self.id).filter(
            geometry__distance_lte=(geometry, D(m=minimum_distance))).count()
        if near_nodes > 0:
            raise ValidationError(
                _('Distance between nodes cannot be less than %s meters') %
                minimum_distance)

    if layer_area is not None and not layer_area.contains(geometry):
        raise ValidationError(_('Node must be inside layer area'))
示例#8
0
    def get_city(self, name, row, country):
        cols, cache = self.columns, self.cities

        iso = country.code
        if (iso, name) in cache:
            return cache[(iso, name)]

        point = Point(float(row[cols['longitude']]),
                      float(row[cols['latitude']]))
        qs = City.objects.distance(point).filter(country=country)

        try:
            c = qs.get(
                Q(name_std__iexact=name) | Q(name__iexact=name)
                | Q(alt_names__name__iexact=name))
        except (City.DoesNotExist, MultipleObjectsReturned):
            try:
                c = qs.exclude(location__distance_gte=(point, D(
                    km=50))).order_by('distance')[0]
            except IndexError:
                c = None

        cache[(iso, name)] = c
        return c
示例#9
0
    def get_queryset(self):
        user = self.request.user
        miles = self.request.GET.get('miles', 100)
        distance = D(mi=miles)

        if user.last_location:
            queryset = (User.objects.filter(
                last_location__distance_lte=(user.last_location, distance),
                ghost_mode=False) | User.objects.filter(featured=True))
            last_location = user.last_location
        else:
            queryset = User.objects.filter(featured=True)
            last_location = GEOSGeometry('POINT (0 0)', srid=4326)

        queryset = queryset.annotate(
            distance=Distance('last_location', last_location)).exclude(
                id=self.request.user.id).with_connection_percentage_for_user(
                    user)
        return queryset.extra(
            select={'picture_is_null': 'picture is NULL'},
            order_by=[
                'picture_is_null',
            ],
        )
示例#10
0
    def end(self, end_position=None):
        self.rent_end = now()
        if end_position is not None:
            self.end_position = end_position
        elif self.bike.public_geolocation():
            self.end_position = self.bike.public_geolocation().geo
        self.save()

        if self.end_position:
            # attach bike to station if location is closer than X meters
            # distance is configured in preferences
            max_distance = preferences.BikeSharePreferences.station_match_max_distance
            station_closer_than_Xm = Station.objects.filter(
                location__distance_lte=(self.end_position, D(m=max_distance)),
                status="AC",
            ).first()
            if station_closer_than_Xm:
                self.bike.current_station = station_closer_than_Xm
                self.end_station = station_closer_than_Xm
                self.save()
            else:
                self.bike.current_station = None

        # set Bike status back to available
        self.bike.availability_status = "AV"
        self.bike.save()
        try:
            # set new non static bike ID, so for GBFS observers can not track this bike
            self.bike.non_static_bike_uuid = uuid.uuid4()
            self.bike.save()
        except IntegrityError:
            # Congratulations! The 2^64 chance of uuid4 collision has happend.
            # here coul'd be the place for the famous comment: "should never happen"
            # So we catch this error here, but don't handle it.
            # because don't rotating a uuid every 18,446,744,073,709,551,615 rents is ok
            pass
示例#11
0
    def get(self, request):
        api_json = {}
        open_space_id = self.request.query_params.get('id')
        distance = self.request.query_params.get('distance')
        print(open_space_id)
        open_space = OpenSpace.objects.get(id=open_space_id)
        longitude = open_space.centroid[0]
        latitude = open_space.centroid[1]
        openspace_location = GEOSGeometry('POINT({} {})'.format(
            longitude, latitude),
                                          srid=4326)
        resource_queryset = AvailableFacility.objects \
            .filter(location__distance_lte=(openspace_location, D(km=distance))) \
            .annotate(distance=Distance('location', openspace_location)) \
            .order_by('distance')
        print(resource_queryset)
        resource_json = AvailableFacilitySerializer(
            resource_queryset, many=True, context={'request': request})
        json = JSONRenderer().render(resource_json.data)
        stream = io.BytesIO(json)
        data = JSONParser().parse(stream)
        api_json['facility'] = data

        return Response(api_json)
示例#12
0
    def filter_queryset(self, request, queryset, view):

        location_longitude = request.query_params.get('location_longitude', None)
        location_latitude = request.query_params.get('location_latitude', None)
        distance_km = request.query_params.get('location_distance_km', None)

        if location_longitude and location_latitude and distance_km:
            pnt = GEOSGeometry(
                'POINT({0} {1})'.format(
                    location_longitude,
                    location_latitude),
                srid=4326)

            if Location is not queryset.model:
                model_prefix = 'location__'
            else:
                model_prefix = ''

            loc_ids = Location.objects.filter(
                **{'point_pos__distance_lte': (pnt, D(km=distance_km))}).values('id')

            return queryset.filter(**{"{}id__in".format(model_prefix): loc_ids})

        return queryset
示例#13
0
    def get(self, request):

        geo = request.GET['geo']
        dis = request.GET['dis']

        traj = self.q.filter(geom__distance_lte=(geo, D(m=dis)))
        count = traj.count()
        response = {}
        if (request.GET['has_time'] == 'true'):
            timeStartStr = request.GET['start_time']
            timeStart = datetime.strptime(timeStartStr, '%H:%M')
            timeEndStr = request.GET['end_time']
            timeEnd = datetime.strptime(timeEndStr, '%H:%M')
            traj = traj.filter(
                Q(start_time__range=(timeStart, timeEnd))
                | Q(end_time__range=(timeStart, timeEnd)))
            count = traj.count()

        response['lineset'] = serialize('geojson', traj)
        response['count'] = count
        return HttpResponse(
            json.dumps(response),
            content_type="application/json",
        )
示例#14
0
    def test_dwithin_gis_lookup_output_with_rasters(self):
        """
        Check the logical functionality of the dwithin lookup for different
        input parameters.
        """
        # Create test raster and geom.
        rast = GDALRaster(json.loads(JSON_RASTER))
        stx_pnt = GEOSGeometry(
            'POINT (-95.370401017314293 29.704867409475465)', 4326)
        stx_pnt.transform(3086)

        # Filter raster with different lookup raster formats.
        qs = RasterModel.objects.filter(rastprojected__dwithin=(rast, D(km=1)))
        self.assertEqual(qs.count(), 1)

        qs = RasterModel.objects.filter(
            rastprojected__dwithin=(json.loads(JSON_RASTER), D(km=1)))
        self.assertEqual(qs.count(), 1)

        qs = RasterModel.objects.filter(rastprojected__dwithin=(JSON_RASTER,
                                                                D(km=1)))
        self.assertEqual(qs.count(), 1)

        # Filter in an unprojected coordinate system.
        qs = RasterModel.objects.filter(rast__dwithin=(rast, 40))
        self.assertEqual(qs.count(), 1)

        # Filter with band index transform.
        qs = RasterModel.objects.filter(rast__1__dwithin=(rast, 1, 40))
        self.assertEqual(qs.count(), 1)
        qs = RasterModel.objects.filter(rast__1__dwithin=(rast, 40))
        self.assertEqual(qs.count(), 1)
        qs = RasterModel.objects.filter(rast__dwithin=(rast, 1, 40))
        self.assertEqual(qs.count(), 1)

        # Filter raster by geom.
        qs = RasterModel.objects.filter(rast__dwithin=(stx_pnt, 500))
        self.assertEqual(qs.count(), 1)

        qs = RasterModel.objects.filter(rastprojected__dwithin=(stx_pnt,
                                                                D(km=10000)))
        self.assertEqual(qs.count(), 1)

        qs = RasterModel.objects.filter(rast__dwithin=(stx_pnt, 5))
        self.assertEqual(qs.count(), 0)

        qs = RasterModel.objects.filter(rastprojected__dwithin=(stx_pnt,
                                                                D(km=100)))
        self.assertEqual(qs.count(), 0)

        # Filter geom by raster.
        qs = RasterModel.objects.filter(geom__dwithin=(rast, 500))
        self.assertEqual(qs.count(), 1)

        # Filter through related model.
        qs = RasterRelatedModel.objects.filter(
            rastermodel__rast__dwithin=(rast, 40))
        self.assertEqual(qs.count(), 1)

        # Filter through related model with band index transform
        qs = RasterRelatedModel.objects.filter(
            rastermodel__rast__1__dwithin=(rast, 40))
        self.assertEqual(qs.count(), 1)

        # Filter through conditional statements.
        qs = RasterModel.objects.filter(
            Q(rast__dwithin=(rast, 40))
            & Q(rastprojected__dwithin=(stx_pnt, D(km=10000))))
        self.assertEqual(qs.count(), 1)

        # Filter through different lookup.
        qs = RasterModel.objects.filter(rastprojected__bbcontains=rast)
        self.assertEqual(qs.count(), 1)
示例#15
0
 def refine(self):
     self._update()
     constraints = self.triconstraint_set.all().order_by('rtt')
     af = 4
     if re.search(':', self.ip):
         af = 6
     msm_def = {
         "definitions": [{
             "target": self.ip,
             "description": "triangulation for %s" % self.ip,
             "type": "ping",
             "af": af,
             "is_oneoff": True,
             "packets": 5,
         }],
         "probes": []
     }
     if len(constraints) == 0:  ## no previous knowledge on this IP
         ### add 5 probes from each 'area'
         for area in ('West', 'North-Central', 'South-Central',
                      'North-East', 'South-East'):
             msm_def['probes'].append({
                 'requested': 5,
                 'type': 'area',
                 'value': area
             })
     else:
         prb_set = Probe.objects.all()
         loc_set = Loc.objects.all().order_by('-pop')
         for c in constraints:
             max_dist = c.rtt * self.__class__.KM_PER_MS
             point_rep = 'POINT(%s %s)' % (c.lon, c.lat)
             prb_set = prb_set.filter(point__distance_lt=(point_rep,
                                                          D(km=max_dist)))
             loc_set = loc_set.filter(point__distance_lt=(point_rep,
                                                          D(km=max_dist)))
         print "potential locs within constraints %s" % (len(loc_set))
         ## top 5 locs within set (for now ordered by population)
         prb_ids = []
         for loc in loc_set:
             ## select 3 probes close to this loc
             prb_close_to_loc = Probe.objects.filter(
                 point__distance_lt=('POINT(%s %s)' % (loc.lon, loc.lat),
                                     D(km=100))).order_by('-id')
             for p in prb_close_to_loc[0:3]:
                 prb_ids.append(str(p.id))
                 print "added %s (%s)" % (p.id, loc)
             if len(prb_ids) > 20:
                 break
         msm_def['probes'].append({
             'requested': 20,
             'type': 'probes',
             'value': ",".join(prb_ids)
         })
     msm_json = json.dumps(msm_def)
     msm_req = JsonRequest(self.__class__.msm_create_url)
     try:
         msm_conn = urllib2.urlopen(msm_req, msm_json)
     except urllib2.HTTPError as e:
         print "HTTP error %s " % (e.read)
     msm_meta = json.load(msm_conn)
     for msm_id in msm_meta['measurements']:
         self.save()
         new_trimsm = self.trimsm_set.create(msm=msm_id)
         print "msm_id created: %s" % (msm_id)
示例#16
0
    def test05_geodetic_distance_lookups(self):
        "Testing distance lookups on geodetic coordinate systems."
        # Line is from Canberra to Sydney.  Query is for all other cities within
        # a 100km of that line (which should exclude only Hobart & Adelaide).
        line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)',
                            4326)
        dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line,
                                                                    D(km=100)))

        if oracle or connection.ops.geography:
            # Oracle and PostGIS 1.5 can do distance lookups on arbitrary geometries.
            self.assertEqual(9, dist_qs.count())
            self.assertEqual([
                'Batemans Bay', 'Canberra', 'Hillsdale', 'Melbourne',
                'Mittagong', 'Shellharbour', 'Sydney', 'Thirroul', 'Wollongong'
            ], self.get_names(dist_qs))
        else:
            # PostGIS 1.4 and below only allows geodetic distance queries (utilizing
            # ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields
            # on geometry columns.
            self.assertRaises(ValueError, dist_qs.count)

            # Ensured that a ValueError was raised, none of the rest of the test is
            # support on this backend, so bail now.
            if spatialite: return

        # Too many params (4 in this case) should raise a ValueError.
        self.assertRaises(
            ValueError, len,
            AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)',
                                                              D(km=100),
                                                              'spheroid',
                                                              '4')))

        # Not enough params should raise a ValueError.
        self.assertRaises(
            ValueError, len,
            AustraliaCity.objects.filter(
                point__distance_lte=('POINT(5 23)', )))

        # Getting all cities w/in 550 miles of Hobart.
        hobart = AustraliaCity.objects.get(name='Hobart')
        qs = AustraliaCity.objects.exclude(name='Hobart').filter(
            point__distance_lte=(hobart.point, D(mi=550)))
        cities = self.get_names(qs)
        self.assertEqual(cities, ['Batemans Bay', 'Canberra', 'Melbourne'])

        # Cities that are either really close or really far from Wollongong --
        # and using different units of distance.
        wollongong = AustraliaCity.objects.get(name='Wollongong')
        d1, d2 = D(yd=19500), D(nm=400)  # Yards (~17km) & Nautical miles.

        # Normal geodetic distance lookup (uses `distance_sphere` on PostGIS.
        gq1 = Q(point__distance_lte=(wollongong.point, d1))
        gq2 = Q(point__distance_gte=(wollongong.point, d2))
        qs1 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq1
                                                                      | gq2)

        # Geodetic distance lookup but telling GeoDjango to use `distance_spheroid`
        # instead (we should get the same results b/c accuracy variance won't matter
        # in this test case).
        if postgis:
            gq3 = Q(point__distance_lte=(wollongong.point, d1, 'spheroid'))
            gq4 = Q(point__distance_gte=(wollongong.point, d2, 'spheroid'))
            qs2 = AustraliaCity.objects.exclude(
                name='Wollongong').filter(gq3 | gq4)
            querysets = [qs1, qs2]
        else:
            querysets = [qs1]

        for qs in querysets:
            cities = self.get_names(qs)
            self.assertEqual(
                cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
示例#17
0
    def test_all_gis_lookups_with_rasters(self):
        """
        Evaluate all possible lookups for all input combinations (i.e.
        raster-raster, raster-geom, geom-raster) and for projected and
        unprojected coordinate systems. This test just checks that the lookup
        can be called, but doesn't check if the result makes logical sense.
        """
        from django.contrib.gis.db.backends.postgis.operations import PostGISOperations

        # Create test raster and geom.
        rast = GDALRaster(json.loads(JSON_RASTER))
        stx_pnt = GEOSGeometry(
            'POINT (-95.370401017314293 29.704867409475465)', 4326)
        stx_pnt.transform(3086)

        lookups = [(name, lookup)
                   for name, lookup in BaseSpatialField.get_lookups().items()
                   if issubclass(lookup, GISLookup)]
        self.assertNotEqual(lookups, [], 'No lookups found')
        # Loop through all the GIS lookups.
        for name, lookup in lookups:
            # Construct lookup filter strings.
            combo_keys = [
                field + name for field in [
                    'rast__',
                    'rast__',
                    'rastprojected__0__',
                    'rast__',
                    'rastprojected__',
                    'geom__',
                    'rast__',
                ]
            ]
            if issubclass(lookup, DistanceLookupBase):
                # Set lookup values for distance lookups.
                combo_values = [
                    (rast, 50, 'spheroid'),
                    (rast, 0, 50, 'spheroid'),
                    (rast, 0, D(km=1)),
                    (stx_pnt, 0, 500),
                    (stx_pnt, D(km=1000)),
                    (rast, 500),
                    (json.loads(JSON_RASTER), 500),
                ]
            elif name == 'relate':
                # Set lookup values for the relate lookup.
                combo_values = [
                    (rast, 'T*T***FF*'),
                    (rast, 0, 'T*T***FF*'),
                    (rast, 0, 'T*T***FF*'),
                    (stx_pnt, 0, 'T*T***FF*'),
                    (stx_pnt, 'T*T***FF*'),
                    (rast, 'T*T***FF*'),
                    (json.loads(JSON_RASTER), 'T*T***FF*'),
                ]
            elif name == 'isvalid':
                # The isvalid lookup doesn't make sense for rasters.
                continue
            elif PostGISOperations.gis_operators[name].func:
                # Set lookup values for all function based operators.
                combo_values = [
                    rast, (rast, 0), (rast, 0), (stx_pnt, 0), stx_pnt, rast,
                    json.loads(JSON_RASTER)
                ]
            else:
                # Override band lookup for these, as it's not supported.
                combo_keys[2] = 'rastprojected__' + name
                # Set lookup values for all other operators.
                combo_values = [
                    rast, None, rast, stx_pnt, stx_pnt, rast,
                    json.loads(JSON_RASTER)
                ]

            # Create query filter combinations.
            self.assertEqual(
                len(combo_keys),
                len(combo_values),
                'Number of lookup names and values should be the same',
            )
            combos = [x for x in zip(combo_keys, combo_values) if x[1]]
            self.assertEqual(
                [(n, x) for n, x in enumerate(combos) if x in combos[:n]],
                [],
                'There are repeated test lookups',
            )
            combos = [{k: v} for k, v in combos]

            for combo in combos:
                # Apply this query filter.
                qs = RasterModel.objects.filter(**combo)

                # Evaluate normal filter qs.
                self.assertIn(qs.count(), [0, 1])

            # Evaluate on conditional Q expressions.
            qs = RasterModel.objects.filter(Q(**combos[0]) & Q(**combos[1]))
            self.assertIn(qs.count(), [0, 1])
示例#18
0
 def within(self, point, distance_km):
     return self.filter(coords__dwithin=(point, D(km=distance_km)))
示例#19
0
 def formated_distance(self):
     '''
     :return: Formated distance in KM
     '''
     return D(m=self.distance).km
示例#20
0
    def get_queryset(self):
    	products = Product.objects.filter(active=1, deleted=0, company__deleted=0, company__active=1)

        company_id = self.request.GET.get('company_id')
        if company_id:
        	products = products.filter(company__id=company_id)

        name = self.request.GET.get('q')
        if name:
        	products = products.filter(name__icontains=name)

        medicament_type = self.request.GET.get('medicament_type')
        if medicament_type:
            types = medicament_type.split(',')
            products = products.filter(medicament_type__in=types)

        lat = self.request.GET.get('lat');lon = self.request.GET.get('lon');
        if lat and lon:
            point = 'POINT(%s %s)' % (lat, lon)
            pnt = GEOSGeometry(point, srid=4326)
            products = products.filter(company__address__location__distance_lte=(pnt, D(km=5)))

        order = self.request.GET.get('order') or 'distance'
        if order == 'medicament_type':
            products = products.order_by('medicament_type')
        elif order == 'lowest_price':
            products = products.order_by('price')
        elif order == 'distance' and lat and lon:
            products = products.distance(pnt, field_name='company__address__location').order_by('distance')

        limit = self.request.GET.get('limit') or 20

        return products[:limit]
示例#21
0
    def get_tags(self,
                 location,
                 num_tags=10,
                 max_dist=4000,
                 max_weight=4.0,
                 min_weight=1.0,
                 include_system=False):
        '''
        Returns an ordered list of tags based on a location, with the higher
        tags being more geographically relevant. The algorithm works as follows

        All tags within the radius of max_dist are considered. Each tag is given
        a weight based on location, which is determined linearly by the distance
        from the center, i.e. a tag directly on the given location would be given
        the maximum weight, while a tag directly on the perimiter of the circle
        would be given the minimum.

        All of the weights for a single semantic tag are aggregated into a final
        score, which is then used to order the tags returned.

        Arguments:
            
            location
                A tuple formatted as follows (lon, lat)

            num_tags
                Number of tags to return

            max_dist
                The maximum distance within which to consider tags

            max_weight
                The maximum float weight to assign tags closest to the center

            min_weight
                The float to assign tags furthest from the center, within
                the max_dist

            include_system
                Wether or not to include system tags
        '''

        center = Point(location[0], location[1])

        # max_dist is now a distance object
        max_dist = D(m=max_dist)

        # Get all contents within max_dist radius, and get them back in 'distance' format
        contents = self.content_model.objects.filter(
            location__distance_lte=(center, max_dist)).distance(center)

        # max_dist is now a float of meters
        max_dist = max_dist.m

        weighted_tags = {}

        for content in contents:

            # distance is appended to content by the distance() queryset method
            dist = content.distance.m

            # Get the weight for all tags for this content
            # Weight between 1-4 where 1 is maximum distance and 4 is 0 distance
            weight = (((max_dist - dist) / max_dist) *
                      (max_weight - min_weight)) + min_weight

            if include_system:
                tagqueryset = content.tags.all()
            else:
                tagqueryset = content.tags.filter(system_tag=False)

            for tagobj in tagqueryset:
                tag = tagobj.name
                if tag in weighted_tags:
                    weighted_tags[tag] += weight
                else:
                    weighted_tags[tag] = weight

        # Sorting dicts by value: http://www.python.org/dev/peps/pep-0265/
        recommended_tags = sorted(weighted_tags,
                                  key=weighted_tags.__getitem__,
                                  reverse=True)[:num_tags]

        return recommended_tags
示例#22
0
    def get_queryset(self):
        '''
        query_params:
            - med_ids: list of MedicaitonName ids
            - dosages: list of Dosage ids
            - localization: list of 2 coordinates (must be int or float)
            - distance: int, in miles
        '''
        med_ids = self.request.query_params.getlist('med_ids[]', None)
        dosages = self.request.query_params.getlist('dosages[]', None)
        location = self.request.query_params.get('localization')
        distance = self.request.query_params.get('distance')

        # 1 - validate location
        try:
            location = list(map(float, location.split(',')))
            location_point = Point(
                location[0],
                location[1],
                srid=4326,
            )
        except (IndexError, ValueError, AttributeError):
            raise BadRequest(
                'Location should be provided and be a list of 2 coordinates')

        # 2 - fetch ndc codes from filters: med id and dosage + support for all
        if len(med_ids) == 1 and med_ids[0] == 'all':
            med_ndc_qs = MedicationMedicationNameMedicationDosageThrough.objects.all(
            )
        else:
            med_ndc_qs = MedicationMedicationNameMedicationDosageThrough.objects.filter(
                medication_name_id__in=med_ids,
                medication_dosage_id__in=dosages)
        med_ndc_ids = med_ndc_qs.select_related(
            'medication__ndc_codes', ).distinct().values_list(
                'medication__ndc_codes', flat=True)

        # 2 - fetch provider medication entries (supply levels) for the ndc ndc_codes
        # and filter by distance
        provider_medication_ids = ProviderMedicationNdcThrough.objects.filter(
            latest=True,
            medication_ndc_id__in=med_ndc_ids,
            provider__geo_localization__distance_lte=(
                location_point,
                D(mi=distance),
            ),
        ).values_list(
            'id',
            flat=True,
        )

        # SPECIAL INSTRUCTION
        # Exclude providers from vaccine finder organization ID 4504 (4383 in medfinder)
        # vaccine finder type needs to be 4 (pharamacy), exclude all other
        # More info at https://www.pivotaltracker.com/story/show/162711148

        provider_qs = Provider.objects.filter(
            Q(organization_id=4383) | Q(vaccine_finder_type=4)
        ).filter(geo_localization__distance_lte=(
            location_point,
            D(mi=distance),
        ), ).annotate(
            distance=Distance(
                'geo_localization',
                location_point,
            ),
            total_supply=Coalesce(
                Sum(
                    'provider_medication__level',
                    filter=Q(
                        provider_medication__id__in=provider_medication_ids,
                        provider_medication__latest=True,
                        active=True,
                    ),
                ),
                0,
            ),
            amount_medications=Count(
                'provider_medication',
                filter=Q(
                    provider_medication__id__in=provider_medication_ids,
                    provider_medication__latest=True,
                    active=True,
                ),
            )).prefetch_related(
                Prefetch(
                    'provider_medication',
                    queryset=ProviderMedicationNdcThrough.objects.filter(
                        latest=True,
                        id__in=provider_medication_ids,
                    ).select_related(
                        'medication_ndc__medication',
                        'medication_ndc__medication__medication_name',
                    ).order_by(
                        '-level',
                        '-medication_ndc__medication__drug_type'))).order_by(
                            '-total_supply', '-active', '-amount_medications',
                            'distance')

        return provider_qs
 def testAccess(self):
     "Testing access in different units"
     d = D(m=100)
     self.assertEqual(d.km, 0.1)
     self.assertAlmostEqual(d.ft, 328.084, 3)
示例#24
0
 def get_nearby(self, radius, lat, lng):
     """Returns places nearby the given lat/lng within the given radius."""
     pnt = Point(float(lng), float(lat))
     places = self.get_query_set().filter(
         point__distance_lte=(pnt, D(km=radius))).distance(pnt)
     return places
示例#25
0
    def test_geodetic_distance_lookups(self):
        """
        Test distance lookups on geodetic coordinate systems.
        """
        # Line is from Canberra to Sydney.  Query is for all other cities within
        # a 100km of that line (which should exclude only Hobart & Adelaide).
        line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)',
                            4326)
        dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line,
                                                                    D(km=100)))
        expected_cities = [
            'Batemans Bay',
            'Canberra',
            'Hillsdale',
            'Melbourne',
            'Mittagong',
            'Shellharbour',
            'Sydney',
            'Thirroul',
            'Wollongong',
        ]
        if spatialite:
            # SpatiaLite is less accurate and returns 102.8km for Batemans Bay.
            expected_cities.pop(0)
        self.assertEqual(expected_cities, self.get_names(dist_qs))

        # Too many params (4 in this case) should raise a ValueError.
        queryset = AustraliaCity.objects.filter(
            point__distance_lte=('POINT(5 23)', D(km=100), 'spheroid', '4'))
        with self.assertRaises(ValueError):
            len(queryset)

        # Not enough params should raise a ValueError.
        with self.assertRaises(ValueError):
            len(
                AustraliaCity.objects.filter(
                    point__distance_lte=('POINT(5 23)', )))

        # Getting all cities w/in 550 miles of Hobart.
        hobart = AustraliaCity.objects.get(name='Hobart')
        qs = AustraliaCity.objects.exclude(name='Hobart').filter(
            point__distance_lte=(hobart.point, D(mi=550)))
        cities = self.get_names(qs)
        self.assertEqual(cities, ['Batemans Bay', 'Canberra', 'Melbourne'])

        # Cities that are either really close or really far from Wollongong --
        # and using different units of distance.
        wollongong = AustraliaCity.objects.get(name='Wollongong')
        d1, d2 = D(yd=19500), D(nm=400)  # Yards (~17km) & Nautical miles.

        # Normal geodetic distance lookup (uses `distance_sphere` on PostGIS.
        gq1 = Q(point__distance_lte=(wollongong.point, d1))
        gq2 = Q(point__distance_gte=(wollongong.point, d2))
        qs1 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq1
                                                                      | gq2)

        # Geodetic distance lookup but telling GeoDjango to use `distance_spheroid`
        # instead (we should get the same results b/c accuracy variance won't matter
        # in this test case).
        querysets = [qs1]
        if connection.features.has_DistanceSpheroid_function:
            gq3 = Q(point__distance_lte=(wollongong.point, d1, 'spheroid'))
            gq4 = Q(point__distance_gte=(wollongong.point, d2, 'spheroid'))
            qs2 = AustraliaCity.objects.exclude(
                name='Wollongong').filter(gq3 | gq4)
            querysets.append(qs2)

        for qs in querysets:
            cities = self.get_names(qs)
            self.assertEqual(
                cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul'])
示例#26
0
文件: models.py 项目: NathHense/itou
 def within(self, point, distance_km):
     return (
         self.filter(coords__distance_lte=(point, D(km=distance_km)))
         .annotate(distance=Distance("coords", point))
         .order_by("distance")
     )
 def testInitInvalid(self):
     "Testing initialization from invalid units"
     with self.assertRaises(AttributeError):
         D(banana=100)
示例#28
0
def send_mail_compatible_donors(donation_id):
    donation = Donation.objects.get(pk=donation_id)
    compatible_blood_types = donation.get_compatible_blood_types()
    compatible_donors = UserProfile.objects.filter(position__distance_lte=(donation.position, D(m=100000))).distance(
        donation.position).filter(reduce(or_, [Q(blood_type=b) for b, d in compatible_blood_types]))

    email_subject = _(u'Precisa-se de doadores %s em %s' %
                      (donation.get_compatible_blood_types_formatted(), donation.location))
    email_from = settings.DEFAULT_FROM_EMAIL
    email_body = render_to_string('donations/donation_request_email.txt', {'donation_id': donation.id, 'receiver_name': donation.receiver_name, 'compatible_blood_types': donation.get_compatible_blood_types_formatted(
    ), 'expiration_date': donation.expiration_date, 'donation_center': donation.donation_center, 'location': donation.location})
    email_messages = ()

    for donor in compatible_donors:
        email_messages += ((email_subject, email_body,
                            email_from, [donor.user.email]),)

    send_mass_mail(email_messages)
 def testAccessInvalid(self):
     "Testing access in invalid units"
     d = D(m=100)
     self.assertFalse(hasattr(d, 'banana'))
示例#30
0
 def test_mysql_geodetic_distance_error(self):
     msg = 'Only numeric values of degree units are allowed on geodetic distance queries.'
     with self.assertRaisesMessage(ValueError, msg):
         AustraliaCity.objects.filter(point__distance_lte=(Point(0, 0), D(m=100))).exists()
示例#31
0
    def get_queryset(self):
        longitude = self.request.query_params.get('longitude', None)
        latitude = self.request.query_params.get('latitude', None)

        global_tips = Tip.objects.filter(
            Q(cities=None) & Q(subregions=None) & Q(regions=None)
            & Q(countries=None)).distinct()

        if not (longitude and latitude):
            queryset = global_tips
            closest_city = None
        else:
            location = Point(float(longitude), float(latitude))
            close_cities = City.objects.filter(
                location__distance_lte=(location, D(km=50))).annotate(
                    distance=Distance('location', location))

            close_cities = close_cities.order_by('distance')[:10]
            closest_city = close_cities.first()
            close_cities = close_cities[1:]
            logger.debug("Looking tips in nearby cities %s", close_cities)
            logger.debug("Closest city is %s", closest_city)

            local_tips = Tip.objects.filter(
                Q(cities=closest_city) | Q(cities__in=close_cities)
                | Q(subregions=closest_city.subregion)
                | Q(regions=closest_city.region)
                | Q(countries=closest_city.region.country)).distinct()

            queryset = (local_tips | global_tips).distinct()

        if closest_city:
            queryset = queryset.annotate(
                closest_city_score=Case(When(cities=closest_city,
                                             then=(F('score') + 1) * 200),
                                        default=0,
                                        output_field=IntegerField()),
                close_cities_score=Case(When(cities__in=close_cities,
                                             then=(F('score') + 1) * 100),
                                        default=0,
                                        output_field=IntegerField()),
                close_subregions_score=Case(When(
                    subregions=closest_city.subregion,
                    then=(F('score') + 1) * 50),
                                            default=0,
                                            output_field=IntegerField()),
                close_regions_score=Case(When(regions=closest_city.region,
                                              then=(F('score') + 1) * 20),
                                         default=0,
                                         output_field=IntegerField()),
                close_countries_score=Case(When(
                    countries=closest_city.region.country,
                    then=(F('score') + 1) * 10),
                                           default=0,
                                           output_field=IntegerField()))

            queryset = queryset.annotate(
                boost_score=(F('score') + F('closest_city_score') +
                             F('close_cities_score') +
                             F('close_subregions_score') +
                             F('close_regions_score') +
                             F('close_countries_score')))

            return queryset.order_by('-boost_score', 'id').prefetch_related(
                'cities', 'subregions', 'regions', 'countries').distinct()
        else:
            return queryset.order_by('-score').distinct()
示例#32
0
 def test_distance_function_d_lookup(self):
     qs = Interstate.objects.annotate(
         d=Distance(Point(0, 0, srid=3857), Point(0, 1, srid=3857)),
     ).filter(d=D(m=1))
     self.assertTrue(qs.exists())