def _request_search( **kwargs ): ''' Searches for RideRequests that meet the criteria specified in **kargs. The criteria are: REQUIRED: polygon : a list of coordinates giving the route of the offer date : a datetime object giving the departure date and time fuzziness : the time fuzziness to search within NOT REQUIRED: other_filters : a dictionary containing other filters to apply in the query Returns a list of RideOffers that match ''' polygon = kwargs['polygon'] offer_start_time = kwargs['date'] offer_fuzziness = kwargs['fuzziness'] # RideRequests within the bounds if not 'other_filters' in kwargs: requests_within_start = RideRequest.objects.filter( start__position__within_polygon=polygon ) else: requests_within_start = RideRequest.objects.filter( start__position__within_polygon=polygon, **kwargs['other_filters'] ) # Filter by date def in_date( req ): return _dates_match( req.date, req.fuzziness, offer_start_time, offer_fuzziness ) requests_within_start = [req for req in requests_within_start if in_date(req)] # Can't do two geospatial queries at once :( bboxArea = Polygon( polygon ) requests_on_route = [r for r in requests_within_start if bboxArea.isInside(*r.end.position)] return requests_on_route
def _offer_search( **kwargs ): ''' Searches for RideOffers that meet the criteria specified in **kargs. The criteria are: REQUIRED: start_lat : the starting latitude of the request start_lng : the starting longitude of the request end_lat end_lng date : a datetime object giving the departure date and time fuzziness : the fuzziness (time range) to search with NOT REQUIRED: other_filters : a dictionary containing other filters to apply in the query Returns a list of RideOffers that match ''' # Find all offers that match our time constraints request_date = kwargs['date'] request_fuzzy = kwargs['fuzziness'] if '-' in request_fuzzy: delta = timedelta(hours=int(request_fuzzy.split('-')[0])) earliest_offer = request_date - delta latest_offer = request_date + delta elif request_fuzzy == 'day': earliest_offer = datetime(request_date.year, request_date.month, request_date.day) next_day = request_date + timedelta(days=1) latest_offer = datetime(next_day.year, next_day.month, next_day.day) elif request_fuzzy == 'week': delta = timedelta(days=3, hours=12) earliest_offer = request_date - delta latest_offer = request_date + delta if 'other_filters' in kwargs: if request_fuzzy == 'anytime': offers = RideOffer.objects.filter( **kwargs['other_filters'] ) else: offers = RideOffer.objects.filter( date__gte=earliest_offer, date__lte=latest_offer, **kwargs['other_filters'] ) else: if request_fuzzy == 'anytime': offers = RideOffer.objects.all() else: offers = RideOffer.objects.filter( date__gte=earliest_offer, date__lte=latest_offer ) # Filter offers further: # 1. Must have start point near req. start and end point near req. end --OR-- # 2. Must have polygon field that overlays start & end of this request filtered_offers = [] for offer in offers: # Results might be less fuzzy than we are, so do some checking here if not _dates_match( offer.date, offer.fuzziness, request_date, request_fuzzy ): continue # Geographical constraints req_start = (float(kwargs['start_lat']), float(kwargs['start_lng'])) req_end = (float(kwargs['end_lat']), float(kwargs['end_lng'])) start_dist = geospatial_distance( offer.start.position, req_start ) end_dist = geospatial_distance( offer.end.position, req_end ) if start_dist < 5 and end_dist < 5: filtered_offers.append( offer ) elif len(offer.polygon) > 0: polygon = Polygon( offer.polygon ) if polygon.isInside( *req_start ) and polygon.isInside( *req_end ): filtered_offers.append( offer ) return filtered_offers