mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-25 16:54:03 -04:00
Merge pull request #3845 from alphagov/refactor-broadcast-areas
Refactor BroadcastAreas to reuse common methods
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
from notifications_utils.formatters import formatted_list
|
from notifications_utils.formatters import formatted_list
|
||||||
from notifications_utils.polygons import Polygons
|
from notifications_utils.polygons import Polygons
|
||||||
@@ -34,7 +35,52 @@ class GetItemByIdMixin:
|
|||||||
raise KeyError(id)
|
raise KeyError(id)
|
||||||
|
|
||||||
|
|
||||||
class BroadcastArea(SortableMixin):
|
class BaseBroadcastArea(ABC):
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def simple_polygons(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def polygons(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abstractmethod
|
||||||
|
def count_of_phones(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def simple_polygons_with_bleed(self):
|
||||||
|
return self.simple_polygons.bleed_by(self.estimated_bleed_in_degrees)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def phone_density(self):
|
||||||
|
if not self.polygons.estimated_area:
|
||||||
|
return 0
|
||||||
|
return self.count_of_phones / self.polygons.estimated_area
|
||||||
|
|
||||||
|
@property
|
||||||
|
def estimated_bleed_in_m(self):
|
||||||
|
'''
|
||||||
|
Estimates the amount of bleed based on the population of an
|
||||||
|
area. Higher density areas tend to have short range masts, so
|
||||||
|
the bleed is low (down to 500m). Lower density areas have longer
|
||||||
|
range masts, so the typical bleed will be high (up to 5,000m).
|
||||||
|
'''
|
||||||
|
if self.phone_density < 1:
|
||||||
|
return Polygons.approx_bleed_in_degrees * Polygons.approx_metres_to_degree
|
||||||
|
estimated_bleed = 5_900 - (math.log(self.phone_density, 10) * 1_250)
|
||||||
|
return max(500, min(estimated_bleed, 5000))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def estimated_bleed_in_degrees(self):
|
||||||
|
return self.estimated_bleed_in_m / Polygons.approx_metres_to_degree
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastArea(BaseBroadcastArea, SortableMixin):
|
||||||
|
|
||||||
def __init__(self, row):
|
def __init__(self, row):
|
||||||
self.id, self.name, self._count_of_phones, self.library_id = row
|
self.id, self.name, self._count_of_phones, self.library_id = row
|
||||||
@@ -51,10 +97,6 @@ class BroadcastArea(SortableMixin):
|
|||||||
BroadcastAreasRepository().get_simple_polygons_for_area(self.id)
|
BroadcastAreasRepository().get_simple_polygons_for_area(self.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def simple_polygons_with_bleed(self):
|
|
||||||
return self.simple_polygons.bleed_by(self.estimated_bleed_in_degrees)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def sub_areas(self):
|
def sub_areas(self):
|
||||||
return [
|
return [
|
||||||
@@ -74,27 +116,6 @@ class BroadcastArea(SortableMixin):
|
|||||||
# https://www.pivotaltracker.com/story/show/174837293
|
# https://www.pivotaltracker.com/story/show/174837293
|
||||||
return self._count_of_phones or 0
|
return self._count_of_phones or 0
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def phone_density(self):
|
|
||||||
return self.count_of_phones / self.polygons.estimated_area
|
|
||||||
|
|
||||||
@property
|
|
||||||
def estimated_bleed_in_m(self):
|
|
||||||
'''
|
|
||||||
Estimates the amount of bleed based on the population of an
|
|
||||||
area. Higher density areas tend to have short range masts, so
|
|
||||||
the bleed is low (down to 500m). Lower density areas have longer
|
|
||||||
range masts, so the typical bleed will be high (up to 5,000m).
|
|
||||||
'''
|
|
||||||
if self.phone_density < 1:
|
|
||||||
return Polygons.approx_bleed_in_degrees * Polygons.approx_metres_to_degree
|
|
||||||
estimated_bleed = 5_900 - (math.log(self.phone_density, 10) * 1_250)
|
|
||||||
return max(500, min(estimated_bleed, 5000))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def estimated_bleed_in_degrees(self):
|
|
||||||
return self.estimated_bleed_in_m / Polygons.approx_metres_to_degree
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def parents(self):
|
def parents(self):
|
||||||
return list(filter(None, self._parents_iterator))
|
return list(filter(None, self._parents_iterator))
|
||||||
@@ -116,7 +137,7 @@ class BroadcastArea(SortableMixin):
|
|||||||
id = parent_broadcast_area.id
|
id = parent_broadcast_area.id
|
||||||
|
|
||||||
|
|
||||||
class CustomBroadcastArea:
|
class CustomBroadcastArea(BaseBroadcastArea):
|
||||||
|
|
||||||
# We don’t yet have a way to estimate the number of phones in a
|
# We don’t yet have a way to estimate the number of phones in a
|
||||||
# user-defined polygon
|
# user-defined polygon
|
||||||
@@ -136,13 +157,6 @@ class CustomBroadcastArea:
|
|||||||
|
|
||||||
simple_polygons = polygons
|
simple_polygons = polygons
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def simple_polygons_with_bleed(self):
|
|
||||||
# We don’t yet have a way of working out the population density
|
|
||||||
# of a custom area, so for now we have to use an average number
|
|
||||||
# to estimate the amount of bleed
|
|
||||||
return self.simple_polygons.bleed_by(Polygons.approx_bleed_in_degrees)
|
|
||||||
|
|
||||||
|
|
||||||
class CustomBroadcastAreas(SerialisedModelCollection):
|
class CustomBroadcastAreas(SerialisedModelCollection):
|
||||||
model = CustomBroadcastArea
|
model = CustomBroadcastArea
|
||||||
|
|||||||
Reference in New Issue
Block a user