Exemplo n.º 1
0
 def find_by_distance(self, election_id, search_point,
                      distance_threshold_km, limit):
     from demsausage.app.models import PollingPlaces
     return find_by_distance(
         search_point, distance_threshold_km, limit,
         PollingPlaces.objects.filter(election_id=election_id,
                                      status=PollingPlaceStatus.ACTIVE))
Exemplo n.º 2
0
    def safe_find_by_distance(self, label, *args, **kwargs):
        results = find_by_distance(*args, **kwargs)
        count = results.count()
        if count >= 2:
            self.logger.error("Find by distance [{}]: Found {} existing polling places spatially near each other. Polling places: {}".format(label, count, "; ".join(["{}/{}/{}".format(pp.name, pp.premises, pp.address) for pp in results])))

        return results
Exemplo n.º 3
0
    def filter(self, qs, value):
        if value not in (None, ""):
            from django.contrib.gis.geos import Point
            from demsausage.app.sausage.polling_places import find_by_distance

            try:
                lon, lat = [float(v) for v in value[0:1000].split(",")]
                search_point = Point(float(lon), float(lat), srid=4326)
            except Exception as e:
                raise BadRequest(e)

            polling_places_filter = find_by_distance(search_point,
                                                     distance_threshold_km=50,
                                                     limit=15,
                                                     qs=qs)
            if polling_places_filter.count() == 0:
                polling_places_filter = find_by_distance(
                    search_point, distance_threshold_km=1000, limit=15, qs=qs)
            return polling_places_filter
        return qs
Exemplo n.º 4
0
    def detect_facility_type(self):
        update_count = 0

        queryset = PollingPlaces.objects.filter(election=self.election, status=PollingPlaceStatus.ACTIVE, facility_type__isnull=True)
        facility_type_queryset = PollingPlaces.objects.filter(status=PollingPlaceStatus.ACTIVE, facility_type__isnull=False).exclude(election=self.election)

        for polling_place in queryset:
            most_recent_facility_type = find_by_distance(polling_place.geom, 0.2, limit=None, qs=facility_type_queryset).order_by("election_id").last()

            if most_recent_facility_type is not None:
                polling_place.facility_type_id = most_recent_facility_type.facility_type_id
                polling_place.save()

                update_count += 1

        self.logger.info("Facility types detected from historical data: {}".format(update_count))
Exemplo n.º 5
0
    def calculate_chance_of_sausage(self):
        def calculate_score(polling_places):
            def _is_a_positive_report(polling_place):
                return is_noms_item_true(polling_place, "bbq") or is_noms_item_true(polling_place, "cake")

            def _has_multiple_positive_reports(polling_places):
                count = 0
                for polling_place in polling_places:
                    if _is_a_positive_report(polling_place) is True:
                        count += 1

                        if count >= 2:
                            return True
                return False

            def _has_one_positive_report(polling_places):
                for polling_place in polling_places:
                    if _is_a_positive_report(polling_place) is True:
                        return True
                return False

            def _has_a_red_cross_of_shame(polling_places):
                for polling_place in polling_places:
                    if is_noms_item_true(polling_place, "nothing") is True:
                        return True
                return False

            def _has_multiple_red_crosses_of_shame(polling_places):
                count = 0
                for polling_place in polling_places:
                    if is_noms_item_true(polling_place, "nothing") is True:
                        count += 1

                        if count >= 2:
                            return True
                return False

            if _has_multiple_red_crosses_of_shame(polling_places) is True:
                if _has_one_positive_report(polling_places) is True:
                    return PollingPlaceChanceOfSausage.MIXED
                return PollingPlaceChanceOfSausage.UNLIKELY
            elif _has_multiple_positive_reports(polling_places) is True:
                if _has_a_red_cross_of_shame(polling_places) is True:
                    return PollingPlaceChanceOfSausage.MIXED
                return PollingPlaceChanceOfSausage.STRONG
            elif _has_one_positive_report(polling_places) is True:
                if _has_a_red_cross_of_shame(polling_places) is True:
                    return PollingPlaceChanceOfSausage.MIXED
                return PollingPlaceChanceOfSausage.FAIR
            else:
                return PollingPlaceChanceOfSausage.NO_IDEA

        update_count = 0
        queryset = PollingPlaces.objects.filter(election=self.election, status=PollingPlaceStatus.ACTIVE, noms__isnull=True)

        for polling_place in queryset:
            matching_polling_places = find_by_distance(polling_place.geom, 0.2, limit=None, qs=PollingPlaces.objects.filter(status=PollingPlaceStatus.ACTIVE).exclude(election=self.election)).order_by("election_id")

            if len(matching_polling_places) > 0:
                polling_place.chance_of_sausage = calculate_score(matching_polling_places)
                polling_place.save()

                update_count += 1

        self.logger.info("Chance of Sausage calculations completed: Considered = {}; Updated = {}".format(queryset.count(), update_count))