Esempio n. 1
0
 def __cluster_events(data, cluster_threshold=None):
     if cluster_threshold:
         # clustered incidents data
         clustered_data = []
         # Consider each node as root for now
         for root in data:
             # If is clustered flag is not present
             if not root.get('isClustered', False):
                 # Loop though the points
                 for child in data:
                     # Base case
                     if child['key'] == root['key']:
                         continue
                     # If node is not clustered
                     if not child.get('isClustered', False):
                         # Calculate the distance
                         temp_distance = distance(root['lat'], root['long'],
                                                  child['lat'],
                                                  child['long'])
                         # If two points are too close on map cluster them
                         if temp_distance < cluster_threshold:
                             # Update root
                             root['isClustered'] = True
                             root['lat'] = (root['lat'] + child['lat']) / 2
                             root['long'] = (root['long'] +
                                             child['long']) / 2
                             # Mark child
                             child['isClustered'] = True
                 clustered_data.append(root)
         return clustered_data
     return data
Esempio n. 2
0
    def get_events_around(center,
                          max_distance,
                          cluster_threshold,
                          db,
                          collection_name='incidents'):
        events_around = []
        result_count = 0
        match_count = 0
        queries = Event.__get_queries_for_events_around(
            db.collection(collection_name), center, max_distance)
        # print("queries", queries)
        for query in queries:
            docs = query.get()
            for doc in docs:
                result_count += 1
                event_dict = doc.to_dict()
                # print("event_dict", event_dict)
                dist = distance(center['latitude'], center['longitude'],
                                event_dict['location']['coords'].latitude,
                                event_dict['location']['coords'].longitude)
                if dist < max_distance:
                    match_count += 1
                    temp = {
                        'key': doc.id,
                        'lat': event_dict['location']['coords'].latitude,
                        'long': event_dict['location']['coords'].longitude,
                        'category': event_dict['category'],
                        'title': event_dict['title'],
                        'datetime': event_dict['datetime']
                    }
                    events_around.append(temp)

        print("result_count", result_count)
        print("match_count", match_count)
        print("diff (result_count - match_count)", result_count - match_count)
        return Event.__cluster_events(events_around, cluster_threshold)
Esempio n. 3
0
    def get(self, request):
        """Returns events within a certain radius for a given location

        POST request parameters:
            [REQUIRED]
            lat: latitude of the location

            long: longitude of the location

            dist: maximum radius of the location

        Arguments:
            request {[type]} -- [ Contains the django request object]

        Returns:
            [HttpResponseBadRequest] -- [If  any of the required parameters is
                                        not given.]
            [JsonResponse] -- [Containing the event data]
        """

        # Should use API View here
        lat = float(request.GET.get('lat', ''))
        lng = float(request.GET.get('long', ''))
        thresold = float(request.GET.get('dist', ''))
        if lat == '' or lng == '' or thresold == '':
            return HttpResponseBadRequest("Bad request")

        incidents = DB.child('incidents').get()
        data = []

        # Find events which are inside the circle

        # This method is highly inefficient
        # In takes O(n) time for each request
        # Should use a GeoHash based solution instead of this
        for incident in incidents.each():
            event = dict(incident.val())
            temp = {}
            temp['key'] = incident.key()
            temp['lat'] = event['location']['coords']['latitude']
            temp['long'] = event['location']['coords']['longitude']
            temp['category'] = event['category']
            temp['title'] = event['title']
            temp['datetime'] = event['datetime']
            tmplat = float(event['location']['coords']['latitude'])
            tmplng = float(event['location']['coords']['longitude'])
            dist = distance(tmplat, tmplng, lat, lng)
            if dist < thresold:
                data.append(temp)

        # Cluster the events
        cluster_thresold = float(request.GET.get('min', 0))
        # This code should also be present on client side
        if cluster_thresold:
            # clustered incidents data
            clustered_data = []
            # Consider each node as root for now
            for root in data:
                # If is clustered flag is not present
                if not root.get('isClustered', False):
                    # Loop though the points
                    for child in data:
                        # Base case
                        if child['key'] == root['key']:
                            continue
                        # If node is not clustered
                        if not child.get('isClustered', False):
                            # Calculate the distance
                            temp_distance = distance(root['lat'], root['long'],
                                                     child['lat'],
                                                     child['long'])
                            # If two points are too close on map cluster them
                            if temp_distance < cluster_thresold:
                                # Update root
                                root['isClustered'] = True
                                root['lat'] = (root['lat'] + child['lat']) / 2
                                root['long'] = (root['long'] +
                                                child['long']) / 2
                                # Mark child
                                child['isClustered'] = True
                    clustered_data.append(root)
            return JsonResponse(clustered_data, safe=False)
        return JsonResponse(data, safe=False)