Merge pull request #3941 from alphagov/use-custom-polygon-to-estimate-phones-in-bleed-area

Use `CustomBroadcastArea` to estimate number of phones in bleed area
This commit is contained in:
Chris Hill-Scott
2021-07-05 15:51:15 +01:00
committed by GitHub
3 changed files with 50 additions and 9 deletions

View File

@@ -144,6 +144,10 @@ class CustomBroadcastArea(BaseBroadcastArea):
self.name = name
self._polygons = polygons or []
@classmethod
def from_polygon_objects(cls, polygon_objects):
return cls(name=None, polygons=polygon_objects.as_coordinate_pairs_lat_long)
@property
def polygons(self):
return Polygons(

View File

@@ -7,6 +7,7 @@ from orderedset import OrderedSet
from werkzeug.utils import cached_property
from app.broadcast_areas.models import (
CustomBroadcastArea,
CustomBroadcastAreas,
broadcast_area_libraries,
)
@@ -17,6 +18,10 @@ from app.notify_client.broadcast_message_api_client import (
broadcast_message_api_client,
)
ESTIMATED_AREA_OF_LARGEST_UK_COUNTY = broadcast_area_libraries.get_areas(
'ctyua19-E10000023' # North Yorkshire
)[0].polygons.estimated_area
class BroadcastMessage(JSONModel):
@@ -176,12 +181,25 @@ class BroadcastMessage(JSONModel):
@property
def count_of_phones_likely(self):
area_estimate = self.simple_polygons.estimated_area
bleed_area_estimate = self.simple_polygons_with_bleed.estimated_area - area_estimate
return round_to_significant_figures(
self.count_of_phones + (self.count_of_phones * bleed_area_estimate / area_estimate),
1
)
estimated_area = self.simple_polygons.estimated_area
if estimated_area > ESTIMATED_AREA_OF_LARGEST_UK_COUNTY:
# For large areas, use a naïve but computationally less
# expensive way of counting the number of phones in the
# bleed area
count = self.count_of_phones * (
self.simple_polygons_with_bleed.estimated_area / estimated_area
)
else:
# For smaller areas, where the computation can be done in
# a second or less (approximately) calculate the number of
# phones based on the ammount of overlap with areas for
# which we have population data
count = CustomBroadcastArea.from_polygon_objects(
self.simple_polygons_with_bleed
).count_of_phones
return round_to_significant_figures(count, 1)
def get_areas(self, areas):
return broadcast_area_libraries.get_areas(

View File

@@ -830,7 +830,7 @@ def test_broadcast_page(
], [
'An area of 6.3 square miles Will get the alert',
'An extra area of 22.6 square miles is Likely to get the alert',
'9,000 to 40,000 phones',
'9,000 to 10,000 phones',
]),
([
'lad20-E09000019',
@@ -839,7 +839,26 @@ def test_broadcast_page(
], [
'An area of 9.7 square miles Will get the alert',
'An extra area of 4.7 square miles is Likely to get the alert',
'200,000 to 300,000 phones',
'200,000 to 500,000 phones',
]),
([
'ctyua19-E10000019',
], [
'Lincolnshire remove',
], [
'An area of 3,986.6 square miles Will get the alert',
'An extra area of 599.4 square miles is Likely to get the alert',
'500,000 to 600,000 phones',
]),
([
'ctyua19-E10000019',
'ctyua19-E10000023'
], [
'Lincolnshire remove', 'North Yorkshire remove',
], [
'An area of 9,776.2 square miles Will get the alert',
'An extra area of 1,654.6 square miles is Likely to get the alert',
'1,000,000 phones estimated',
]),
))
def test_preview_broadcast_areas_page(
@@ -907,7 +926,7 @@ def test_preview_broadcast_areas_page(
[
'An area of 3,205.0 square miles Will get the alert',
'An extra area of 763.4 square miles is Likely to get the alert',
'4,000 to 5,000 phones',
'4,000 phones estimated',
]
),
))