コード例 #1
0
ファイル: views.py プロジェクト: MechanisM/mollyproject
    def get_metadata(self, request, ptypes, entity=None):
        context = NearbyDetailView.initial_context(self, request, ptypes, entity)

        if len(context['entity_types']) == 0:
            return {
                'exclude_from_search': True,
                'title': _('Things near %(title)s') % {'title': entity.title}
            }

        et_name = capfirst(context['entity_types'][0].verbose_name_plural)
        if entity is not None:
            title = _('%(entity_type)s near %(entity)s') % {
                                                        'entity_type':et_name,
                                                        'title': entity.title
                                                    }
        else:
            title = _('%(et)s nearby') % {'et': et_name}
            
        if len(context['entity_types']) > 1:
            return {
                'exclude_from_search': True,
                'title': title}
        
        number = len([e for e in context['entities']
                      if haversine(e.location, context['point']) <= 1000])
        entity_type = context['entity_types'][0].verbose_name_plural

        return {
            'title': title,
            'additional': _('<strong>%(number)d %(entity_type)s</strong> within 1km') \
                % {'number': number, 'entity_type': entity_type}
        }
コード例 #2
0
    def get_metadata(self, request, ptypes, entity=None):
        context = NearbyDetailView.initial_context(self, request, ptypes,
                                                   entity)

        if len(context['entity_types']) == 0:
            return {
                'exclude_from_search': True,
                'title': _('Things near %(title)s') % {
                    'title': entity.title
                }
            }

        et_name = capfirst(context['entity_types'][0].verbose_name_plural)
        if entity is not None:
            title = _('%(entity_type)s near %(entity)s') % {
                'entity_type': et_name,
                'title': entity.title
            }
        else:
            title = _('%(et)s nearby') % {'et': et_name}

        if len(context['entity_types']) > 1:
            return {'exclude_from_search': True, 'title': title}

        number = len([
            e for e in context['entities']
            if haversine(e.location, context['point']) <= 1000
        ])
        entity_type = context['entity_types'][0].verbose_name_plural

        return {
            'title': title,
            'additional': _('<strong>%(number)d %(entity_type)s</strong> within 1km') \
                % {'number': number, 'entity_type': entity_type}
        }
コード例 #3
0
    def set_location(self,
                     request,
                     name,
                     location,
                     accuracy,
                     method,
                     with_history=False):
        request.session['geolocation:location'] = location
        request.session['geolocation:updated'] = datetime.utcnow()
        request.session['geolocation:name'] = name
        request.session['geolocation:method'] = method
        request.session['geolocation:accuracy'] = accuracy

        if not with_history:
            return

        if isinstance(location, list):
            location = tuple(location)
        last_updated = request.session.get('geolocation:updated',
                                           datetime(1970, 1, 1))
        try:
            last_location = Point(request.session['geolocation:location'])
            distance_moved = haversine(last_location, Point(location))
        except KeyError:
            distance_moved = float('inf')

        if method in ('other', 'manual', 'geocoded', 'html5request') or \
           not 'geolocation:location' in request.session or \
           (last_updated > datetime.utcnow() - timedelta(seconds=3600) and distance_moved > 250):
            self.add_to_history(request, name, location, accuracy, method)
コード例 #4
0
        def h(*args, **kwargs):
            args = getargsfunc(*args, **kwargs)
            app = get_app('molly.geolocation', args.pop('local_name', None))
            try:
                geocode = Geocode.recent.get(local_name=app.local_name, **args)
                logger.debug('Found cached geocode')
                return geocode.results
            except Geocode.DoesNotExist:
                logger.debug('Geocode not found in cache')
                pass
            except Geocode.MultipleObjectsReturned:
                Geocode.recent.filter(local_name=app.local_name,
                                      **args).delete()
            results = f(providers=app.providers, **args)

            i = 0
            while i < len(results):
                loc, name = Point(results[i]['location']), results[i]['name']
                if any((r['name'] == name
                        and haversine(Point(r['location']), loc) < 100)
                       for r in results[:i]):
                    results[i:i + 1] = []
                else:
                    i += 1

            if hasattr(app, 'prefer_results_near'):
                point = Point(app.prefer_results_near[:2])
                distance = app.prefer_results_near[2]
                filtered_results = [
                    result for result in results
                    if haversine(Point(result['location']), point) <= distance
                ]
                if filtered_results:
                    results = filtered_results

            try:
                geocode, created = Geocode.objects.get_or_create(
                    local_name=app.local_name, **args)
            except Geocode.MultipleObjectsReturned:
                Geocode.objects.filter(local_name=app.local_name,
                                       **args).delete()
                geocode, created = Geocode.objects.get_or_create(
                    local_name=app.local_name, **args)
            geocode.results = results
            geocode.save()

            return results
コード例 #5
0
 def get_distance_and_bearing_from(self, point):
     """
     Returns a distance and compass direction from current Entity to
     another point
     """
     if point is None or not self.location:
         return None, None
     return haversine(point, self.location), self.get_bearing(point)
コード例 #6
0
ファイル: models.py プロジェクト: MechanisM/mollyproject
 def get_distance_and_bearing_from(self, point):
     """
     Returns a distance and compass direction from current Entity to
     another point
     """
     if point is None or not self.location:
         return None, None
     return haversine(point, self.location), self.get_bearing(point)
コード例 #7
0
ファイル: __init__.py プロジェクト: puntofisso/mollyproject
        def h(*args, **kwargs):
            args = getargsfunc(*args, **kwargs)
            app = get_app('molly.geolocation', args.pop('local_name', None))
            try:
                geocode = Geocode.recent.get(local_name=app.local_name, **args)
                logger.debug('Found cached geocode')
                return geocode.results
            except Geocode.DoesNotExist:
                logger.debug('Geocode not found in cache')
                pass
            except Geocode.MultipleObjectsReturned:
                Geocode.recent.filter(local_name=app.local_name, **args).delete()
            results = f(providers=app.providers, **args)

            i = 0
            while i < len(results):
                loc, name = Point(results[i]['location']), results[i]['name']
                if any((r['name'] == name and haversine(Point(r['location']), loc) < 100) for r in results[:i]):
                    results[i:i+1] = []
                else:
                    i += 1
            
            if hasattr(app, 'prefer_results_near'):
                point = Point(app.prefer_results_near[:2])
                distance = app.prefer_results_near[2]
                filtered_results = [
                    result for result in results if
                        haversine(Point(result['location']), point) <= distance]
                if filtered_results:
                    results = filtered_results

            try:
                geocode, created = Geocode.objects.get_or_create(
                    local_name=app.local_name, **args)
            except Geocode.MultipleObjectsReturned:
                Geocode.objects.filter(local_name=app.local_name, **args).delete()
                geocode, created = Geocode.objects.get_or_create(
                    local_name=app.local_name, **args)
            geocode.results = results
            geocode.save()
            
            return results
コード例 #8
0
ファイル: views.py プロジェクト: cosmicraga/mollyproject
    def handle_GET(self, request, context, control_number):

        # Build a map of all the libraries that have this book, with markers
        # corresponding to colours

        user_location = request.session.get('geolocation:location')

        points = []
        point_libraries = []
        lbs = context['item'].libraries.items()

        for library, books in lbs:
            library.entity = library.get_entity()

        if user_location:
            lbs = sorted(lbs,
                         key=lambda (l, b):
                         (haversine(user_location, l.entity.location)
                          if l.entity and l.entity.location else float('inf')))

        for library, books in lbs:
            if library.entity != None and library.entity.location != None:
                colour = AVAIL_COLORS[max(b['availability'] for b in books)]
                points.append(
                    (library.entity.location[0], library.entity.location[1],
                     colour, library.entity.title))
                point_libraries.append(library)

        if len(points) > 0:
            context['map'] = Map(
                centre_point=(user_location[0], user_location[1], 'green',
                              '') if user_location != None else None,
                points=points,
                min_points=0 if context['zoom'] else len(points),
                zoom=context['zoom'],
                width=request.map_width,
                height=request.map_height,
            )

            # Yes, this is weird. fit_to_map() groups libraries with the same
            # location so here we add a marker_number to each library to display
            # in the template.
            lib_iter = iter(point_libraries)
            for i, (a, b) in enumerate(context['map'].points):
                for j in range(len(b)):
                    lib_iter.next().marker_number = i + 1

        context.update({
            'sorted_libraries': lbs,
        })

        return self.render(request, context, 'library/item_detail')
コード例 #9
0
ファイル: views.py プロジェクト: MechanisM/mollyproject
 def handle_GET(self, request, context, control_number):
     
     # Build a map of all the libraries that have this book, with markers
     # corresponding to colours
     
     user_location = request.session.get('geolocation:location')
     
     points = []
     point_libraries = []
     lbs = context['item'].libraries.items()
     
     for library, books in lbs:
         library.entity = library.get_entity()
     
     if user_location:
         lbs = sorted(lbs, key=lambda (l,b): haversine(user_location,
                                                       l.entity.location))
     
     for library, books in lbs:
         if library.entity != None and library.entity.location != None:
             colour = AVAIL_COLORS[max(b['availability'] for b in books)]
             points.append((library.entity.location[0],
                            library.entity.location[1],
                            colour,
                            library.entity.title))
             point_libraries.append(library)
     
     if len(points) > 0:
         context['map'] = Map(
             centre_point = (user_location[0], user_location[1], 'green', '')
                             if user_location != None else None,
             points = points,
             min_points = 0 if context['zoom'] else len(points),
             zoom = context['zoom'],
             width = request.map_width,
             height = request.map_height,
         )
         
         # Yes, this is weird. fit_to_map() groups libraries with the same
         # location so here we add a marker_number to each library to display
         # in the template.
         lib_iter = iter(point_libraries)
         for i, (a,b) in enumerate(context['map'].points):
             for j in range(len(b)):
                 lib_iter.next().marker_number = i + 1
     
     context.update({
         'sorted_libraries': lbs,
     })
     
     return self.render(request, context, 'library/item_detail')
コード例 #10
0
ファイル: __init__.py プロジェクト: cosmicraga/mollyproject
def optimise_points(points):
    """
    This algorithm takes some points and then tries to figure out the shortest
    route between them.
    
    It uses "as the crow flies" distance, which may not necessarily be the best.
    
    Points should be a list of tuples, where the first element is the object
    and the second element is the location of that object (first element is
    ignored by this algorithm, but is useful for you to correlate the resulting
    order with your original).
    
    This assumes that the first point is always the starting point of the user
    """

    if len(points) > 10:
        raise NotImplementedError()

    distances = {}

    for e, x in points:
        for e, y in points:
            distances[(x, y)] = haversine(x, y)

    def tsp_recurse(current, remaining):
        weights = []
        for point in remaining:
            path = [point[0]]
            weight = distances[(current, point[1])]

            next = set(remaining)
            next.remove(point)
            if next:
                path_r, weight_r = tsp_recurse(point[1], next)
                weight += weight_r
                path += path_r

            weights.append((path, weight))

        return min(weights, key=itemgetter(1))

    path, weight = tsp_recurse(points[0][1], set(points[1:]))
    return [points[0][0]] + path
コード例 #11
0
ファイル: __init__.py プロジェクト: ManchesterIO/mollyproject
def optimise_points(points):
    """
    This algorithm takes some points and then tries to figure out the shortest
    route between them.
    
    It uses "as the crow flies" distance, which may not necessarily be the best.
    
    Points should be a list of tuples, where the first element is the object
    and the second element is the location of that object (first element is
    ignored by this algorithm, but is useful for you to correlate the resulting
    order with your original).
    
    This assumes that the first point is always the starting point of the user
    """
    
    if len(points) > 10:
        raise NotImplementedError()
    
    distances = {}
    
    for e, x in points:
        for e, y in points:
            distances[(x,y)] = haversine(x, y)
    
    def tsp_recurse(current, remaining):
        weights = []
        for point in remaining:
            path = [point[0]]
            weight = distances[(current, point[1])]
            
            next = set(remaining)
            next.remove(point)
            if next:
                path_r, weight_r = tsp_recurse(point[1], next)
                weight += weight_r
                path += path_r
            
            weights.append((path, weight))
        
        return min(weights, key=itemgetter(1))
    
    path, weight = tsp_recurse(points[0][1], set(points[1:]))
    return [points[0][0]] + path
コード例 #12
0
ファイル: views.py プロジェクト: ManchesterIO/mollyproject
    def set_location(self, request, name, location, accuracy, method, with_history=False):
        request.session['geolocation:location'] = location
        request.session['geolocation:updated'] = datetime.utcnow()
        request.session['geolocation:name'] = name
        request.session['geolocation:method'] = method
        request.session['geolocation:accuracy'] = accuracy

        if not with_history:
            return

        if isinstance(location, list):
            location = tuple(location)
        last_updated = request.session.get('geolocation:updated', datetime(1970, 1, 1))
        try:
            last_location = Point(request.session['geolocation:location'])
            distance_moved = haversine(last_location, Point(location))
        except KeyError:
            distance_moved = float('inf')

        if method in ('other', 'manual', 'geocoded', 'html5request') or \
           not 'geolocation:location' in request.session or \
           (last_updated > datetime.utcnow() - timedelta(seconds=3600) and distance_moved > 250):
            self.add_to_history(request, name, location, accuracy, method)