diff --git a/app/__init__.py b/app/__init__.py
index ff1880710..f6a137446 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -76,6 +76,7 @@ from app.formatters import (
recipient_count,
recipient_count_label,
round_to_significant_figures,
+ square_metres_to_square_miles,
valid_phone_number,
)
from app.models.organisation import Organisation
@@ -572,6 +573,7 @@ def add_template_filters(application):
message_count_noun,
format_mobile_network,
format_yes_no,
+ square_metres_to_square_miles,
]:
application.add_template_filter(fn)
diff --git a/app/broadcast_areas/broadcast-areas.sqlite3 b/app/broadcast_areas/broadcast-areas.sqlite3
index c991753f1..eab6b281b 100644
Binary files a/app/broadcast_areas/broadcast-areas.sqlite3 and b/app/broadcast_areas/broadcast-areas.sqlite3 differ
diff --git a/app/broadcast_areas/create-broadcast-areas-db.py b/app/broadcast_areas/create-broadcast-areas-db.py
index 3a9c39ee0..fbcc143df 100755
--- a/app/broadcast_areas/create-broadcast-areas-db.py
+++ b/app/broadcast_areas/create-broadcast-areas-db.py
@@ -44,14 +44,30 @@ def simplify_geometry(feature):
def clean_up_invalid_polygons(polygons, indent=" "):
+ """
+ This function expects a list of lists of coordinates defined in degrees
+ """
for index, polygon in enumerate(polygons):
shapely_polygon = Polygon(polygon)
- if shapely_polygon.is_valid:
+ # Some of our data has points which are incredibly close
+ # together. In some cases they are close enough to be duplicates
+ # at a given precision, which makes an invalid topology. In
+ # other cases they are close enough that, when converting from
+ # one coordinate system to another, they shift about enough to
+ # create self-intersection. The fix in both cases is to reduce
+ # the precision of the coordinates and then apply simplification
+ # with a tolerance of 0.
+ simplified_polygon = wkt.loads(wkt.dumps(
+ shapely_polygon,
+ rounding_precision=Polygons.output_precision_in_decimal_places - 1
+ )).simplify(0)
+
+ if simplified_polygon.is_valid:
print( # noqa: T001
f"{indent}Polygon {index + 1}/{len(polygons)} is valid"
)
- yield polygon
+ yield simplified_polygon
else:
invalid_polygons.append(shapely_polygon)
@@ -59,7 +75,7 @@ def clean_up_invalid_polygons(polygons, indent=" "):
# We’ve found polygons where all the points line up, so they
# don’t have an area. They wouldn’t contribute to a broadcast
# so we can ignore them.
- if shapely_polygon.area == 0:
+ if simplified_polygon.area == 0:
print( # noqa: T001
f"{indent}Polygon {index + 1}/{len(polygons)} has 0 area, skipping"
)
@@ -69,18 +85,6 @@ def clean_up_invalid_polygons(polygons, indent=" "):
f"{indent}Polygon {index + 1}/{len(polygons)} needs fixing..."
)
- # The simplest kind of invalid polygon is one that has two
- # duplicate points in a row at a given precision, so the
- # first thing to try is removing those points using
- # simplification with a tolerance of 0
- polygon_with_duplicate_points_removed = wkt.loads(
- wkt.dumps(shapely_polygon, rounding_precision=5)
- ).simplify(0)
-
- if polygon_with_duplicate_points_removed.is_valid:
- yield polygon_with_duplicate_points_removed
- continue
-
# Buffering with a size of 0 is a trick to make valid
# geometries from polygons that self intersect
buffered = shapely_polygon.buffer(0)
@@ -101,7 +105,7 @@ def clean_up_invalid_polygons(polygons, indent=" "):
# Make sure the polygon is now valid, and that we haven’t
# drastically transformed the polygon by ‘fixing’ it
assert fixed_polygon.is_valid
- assert isclose(fixed_polygon.area, polygon.area, rel_tol=0.001)
+ assert isclose(fixed_polygon.area, shapely_polygon.area, rel_tol=0.001)
print( # noqa: T001
f"{indent}Polygon {index + 1}/{len(polygons)} fixed!"
@@ -115,14 +119,22 @@ def polygons_and_simplified_polygons(feature):
# cheat and shortcut out
return [], []
- polygons = Polygons(simplify_geometry(feature))
- polygons = list(clean_up_invalid_polygons(polygons))
- polygons = Polygons(polygons)
+ raw_polygons = simplify_geometry(feature)
+ clean_raw_polygons = [
+ [[x, y] for x, y in polygon.exterior.coords]
+ for polygon in clean_up_invalid_polygons(raw_polygons)
+ ]
+ polygons = Polygons(clean_raw_polygons)
full_resolution = polygons.remove_too_small
smoothed = full_resolution.smooth
simplified = smoothed.simplify
+ if not (len(full_resolution) or len(simplified)):
+ raise RuntimeError(
+ 'Polygon of 0 size found'
+ )
+
print( # noqa: T001
f' Original:{full_resolution.point_count: >5} points'
f' Smoothed:{smoothed.point_count: >5} points'
@@ -138,17 +150,17 @@ def polygons_and_simplified_polygons(feature):
'Polygons.perimeter_to_buffer_ratio)'
)
- output = (
+ output = [
full_resolution.as_coordinate_pairs_long_lat,
simplified.as_coordinate_pairs_long_lat,
- )
+ ]
# Check that the simplification process hasn’t introduced bad data
for dataset in output:
for polygon in dataset:
assert Polygon(polygon).is_valid
- return output
+ return output + [simplified.utm_crs]
def estimate_number_of_smartphones_in_area(country_or_ward_code):
@@ -256,13 +268,14 @@ def add_test_areas():
print() # noqa: T001
print(f_name) # noqa: T001
- feature, _ = polygons_and_simplified_polygons(
+ feature, _, utm_crs = polygons_and_simplified_polygons(
feature["geometry"]
)
areas_to_add.append([
f'{dataset_id}-{f_id}', f_name,
dataset_id, None,
feature, feature,
+ utm_crs,
0,
])
@@ -288,7 +301,7 @@ def add_demo_areas():
print() # noqa: T001
print(f_name) # noqa: T001
- feature, _ = polygons_and_simplified_polygons(
+ feature, _, utm_crs = polygons_and_simplified_polygons(
feature["geometry"]
)
@@ -298,6 +311,7 @@ def add_demo_areas():
f'{dataset_id}-{f_id}', f_name,
dataset_id, None,
feature, feature,
+ utm_crs,
f_count_of_phones,
])
@@ -322,13 +336,14 @@ def add_countries():
print() # noqa: T001
print(f_name) # noqa: T001
- feature, simple_feature = (
+ feature, simple_feature, utm_crs = (
polygons_and_simplified_polygons(feature["geometry"])
)
areas_to_add.append([
f'ctry19-{f_id}', f_name,
dataset_id, None,
feature, simple_feature,
+ utm_crs,
estimate_number_of_smartphones_in_area(f_id),
])
@@ -364,7 +379,7 @@ def _add_electoral_wards(dataset_id):
try:
la_id = "lad20-" + ward_code_to_la_id_mapping[ward_code]
- feature, simple_feature = (
+ feature, simple_feature, utm_crs = (
polygons_and_simplified_polygons(feature["geometry"])
)
@@ -375,6 +390,7 @@ def _add_electoral_wards(dataset_id):
ward_id, ward_name,
dataset_id, la_id,
feature, simple_feature,
+ utm_crs,
estimate_number_of_smartphones_in_area(ward_code),
])
@@ -397,7 +413,7 @@ def _add_local_authorities(dataset_id):
group_id = "lad20-" + la_id
- feature, simple_feature = (
+ feature, simple_feature, utm_crs = (
polygons_and_simplified_polygons(feature["geometry"])
)
@@ -409,6 +425,7 @@ def _add_local_authorities(dataset_id):
'ctyua19-' + ctyua_id if ctyua_id else None,
feature,
simple_feature,
+ utm_crs,
None,
])
repo.insert_broadcast_areas(areas_to_add, keep_old_polygons)
@@ -427,7 +444,7 @@ def _add_counties_and_unitary_authorities(dataset_id):
group_id = "ctyua19-" + ctyua_id
- feature, simple_feature = (
+ feature, simple_feature, utm_crs = (
polygons_and_simplified_polygons(feature["geometry"])
)
@@ -435,6 +452,7 @@ def _add_counties_and_unitary_authorities(dataset_id):
group_id, group_name,
dataset_id, None,
feature, simple_feature,
+ utm_crs,
None,
])
diff --git a/app/broadcast_areas/models.py b/app/broadcast_areas/models.py
index ddd163a53..d9286988a 100644
--- a/app/broadcast_areas/models.py
+++ b/app/broadcast_areas/models.py
@@ -7,6 +7,8 @@ from notifications_utils.serialised_model import SerialisedModelCollection
from rtreelib import Rect
from werkzeug.utils import cached_property
+from app.formatters import square_metres_to_square_miles
+
from .populations import CITY_OF_LONDON
from .repo import BroadcastAreasRepository, rtree_index
@@ -55,13 +57,13 @@ class BaseBroadcastArea(ABC):
@cached_property
def simple_polygons_with_bleed(self):
- return self.simple_polygons.bleed_by(self.estimated_bleed_in_degrees)
+ return self.simple_polygons.bleed_by(self.estimated_bleed_in_m)
@cached_property
def phone_density(self):
- if not self.polygons.estimated_area:
+ if not self.simple_polygons.estimated_area:
return 0
- return self.count_of_phones / self.polygons.estimated_area
+ return self.count_of_phones / square_metres_to_square_miles(self.simple_polygons.estimated_area)
@property
def estimated_bleed_in_m(self):
@@ -72,14 +74,10 @@ class BaseBroadcastArea(ABC):
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
+ return Polygons.approx_bleed_in_m
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):
@@ -97,20 +95,27 @@ class BroadcastArea(BaseBroadcastArea, SortableMixin):
@classmethod
def from_row_with_simple_polygons(cls, row):
instance = cls(row[:4])
- instance.simple_polygons = Polygons(row[4])
+ instance.simple_polygons = Polygons(
+ row[4],
+ utm_crs=row[5],
+ )
return instance
@cached_property
def polygons(self):
+ polygons, utm_crs = BroadcastAreasRepository().get_polygons_for_area(self.id)
return Polygons(
- BroadcastAreasRepository().get_polygons_for_area(self.id)
+ polygons, utm_crs=utm_crs
)
@cached_property
def simple_polygons(self):
- return Polygons(
+ simple_polygons, utm_crs = (
BroadcastAreasRepository().get_simple_polygons_for_area(self.id)
)
+ return Polygons(
+ simple_polygons, utm_crs=utm_crs
+ ).utm_polygons
@cached_property
def sub_areas(self):
@@ -123,7 +128,7 @@ class BroadcastArea(BaseBroadcastArea, SortableMixin):
def count_of_phones(self):
if self.id.endswith(CITY_OF_LONDON.WARDS):
return CITY_OF_LONDON.DAYTIME_POPULATION * (
- self.polygons.estimated_area / CITY_OF_LONDON.AREA_SQUARE_MILES
+ self.polygons.estimated_area / CITY_OF_LONDON.AREA_SQUARE_METRES
)
if self.sub_areas:
return sum(area.count_of_phones for area in self.sub_areas)
@@ -162,14 +167,19 @@ class CustomBroadcastArea(BaseBroadcastArea):
@classmethod
def from_polygon_objects(cls, polygon_objects):
- return cls(name=None, polygons=polygon_objects.as_coordinate_pairs_lat_long)
+ instance = cls(name=None)
+ instance.polygons = polygon_objects
+ return instance
- @property
+ @cached_property
def polygons(self):
return Polygons(
# Polygons in the DB are stored with the coordinate pair
# order flipped – this flips them back again
- Polygons(self._polygons).as_coordinate_pairs_lat_long
+ [
+ [[lat, long] for long, lat in polygon]
+ for polygon in self._polygons
+ ]
)
simple_polygons = polygons
@@ -188,7 +198,7 @@ class CustomBroadcastArea(BaseBroadcastArea):
return broadcast_area_libraries.get_areas_with_simple_polygons([
# We only index electoral wards in the RTree
overlap.data for overlap in rtree_index.query(
- Rect(*self.polygons.bounds)
+ Rect(*self.simple_polygons.bounds)
)
])
diff --git a/app/broadcast_areas/populations.py b/app/broadcast_areas/populations.py
index d10b2d8f1..39db91786 100644
--- a/app/broadcast_areas/populations.py
+++ b/app/broadcast_areas/populations.py
@@ -31,8 +31,9 @@ class CITY_OF_LONDON:
)
# https://data.london.gov.uk/blog/daytime-population-of-london-2014/
DAYTIME_POPULATION = 553_000
- # Approx area of the polygons we’re storing, not the actual area
- AREA_SQUARE_MILES = 1.78
+ # Exact area of the polygons we’re storing, which matches the 2.9km²
+ # given by https://en.wikipedia.org/wiki/City_of_London
+ AREA_SQUARE_METRES = 2_885_598
class BRYHER:
diff --git a/app/broadcast_areas/repo.py b/app/broadcast_areas/repo.py
index b18a46456..155004805 100644
--- a/app/broadcast_areas/repo.py
+++ b/app/broadcast_areas/repo.py
@@ -54,7 +54,8 @@ class BroadcastAreasRepository(object):
CREATE TABLE broadcast_area_polygons (
id TEXT PRIMARY KEY,
polygons TEXT NOT NULL,
- simple_polygons TEXT NOT NULL
+ simple_polygons TEXT NOT NULL,
+ utm_crs TEXT NOT NULL
)""")
conn.execute("""
@@ -98,19 +99,19 @@ class BroadcastAreasRepository(object):
features_q = """
INSERT INTO broadcast_area_polygons (
id,
- polygons, simple_polygons
+ polygons, simple_polygons, utm_crs
)
- VALUES (?, ?, ?)
+ VALUES (?, ?, ?, ?)
"""
with self.conn() as conn:
- for id, name, area_id, group, polygons, simple_polygons, count_of_phones in areas:
+ for id, name, area_id, group, polygons, simple_polygons, utm_crs, count_of_phones in areas:
conn.execute(areas_q, (
id, name, area_id, group, count_of_phones
))
if not keep_old_features:
conn.execute(features_q, (
- id, json.dumps(polygons), json.dumps(simple_polygons),
+ id, json.dumps(polygons), json.dumps(simple_polygons), utm_crs
))
def query(self, sql, *args):
@@ -143,7 +144,7 @@ class BroadcastAreasRepository(object):
def get_areas_with_simple_polygons(self, area_ids):
q = """
- SELECT broadcast_areas.id, name, count_of_phones, broadcast_area_library_id, simple_polygons
+ SELECT broadcast_areas.id, name, count_of_phones, broadcast_area_library_id, simple_polygons, utm_crs
FROM broadcast_areas
JOIN broadcast_area_polygons on broadcast_area_polygons.id = broadcast_areas.id
WHERE broadcast_areas.id IN ({})
@@ -152,7 +153,7 @@ class BroadcastAreasRepository(object):
results = self.query(q, *area_ids)
areas = [
- (row[0], row[1], row[2], row[3], json.loads(row[4]))
+ (row[0], row[1], row[2], row[3], json.loads(row[4]), row[5])
for row in results
]
@@ -231,22 +232,22 @@ class BroadcastAreasRepository(object):
def get_polygons_for_area(self, area_id):
q = """
- SELECT polygons
+ SELECT polygons, utm_crs
FROM broadcast_area_polygons
WHERE id = ?
"""
results = self.query(q, area_id)
- return json.loads(results[0][0])
+ return json.loads(results[0][0]), results[0][1]
def get_simple_polygons_for_area(self, area_id):
q = """
- SELECT simple_polygons
+ SELECT simple_polygons, utm_crs
FROM broadcast_area_polygons
WHERE id = ?
"""
results = self.query(q, area_id)
- return json.loads(results[0][0])
+ return json.loads(results[0][0]), results[0][1]
diff --git a/app/broadcast_areas/rtree.pickle b/app/broadcast_areas/rtree.pickle
index 1b547e04b..58dc22f9e 100644
Binary files a/app/broadcast_areas/rtree.pickle and b/app/broadcast_areas/rtree.pickle differ
diff --git a/app/formatters.py b/app/formatters.py
index aa8d42663..c0dda4738 100644
--- a/app/formatters.py
+++ b/app/formatters.py
@@ -524,3 +524,7 @@ def format_yes_no(value, yes='Yes', no='No', none='No'):
if value is None:
return none
return yes if value else no
+
+
+def square_metres_to_square_miles(area):
+ return area * 3.86e-7
diff --git a/app/models/broadcast_message.py b/app/models/broadcast_message.py
index e6d8be55b..4a2e2544b 100644
--- a/app/models/broadcast_message.py
+++ b/app/models/broadcast_message.py
@@ -88,7 +88,7 @@ class BroadcastMessage(JSONModel):
broadcast_message_id=broadcast_message_id,
))
- @property
+ @cached_property
def areas(self):
if 'ids' in self._dict['areas']:
library_areas = self.get_areas(self.area_ids)
@@ -221,7 +221,8 @@ class BroadcastMessage(JSONModel):
polygons = Polygons(
list(itertools.chain(*(
getattr(area, area_attribute) for area in self.areas
- )))
+ ))),
+ utm_crs=self.areas[0].simple_polygons.utm_polygons.utm_crs,
)
if area_attribute != 'polygons' and len(self.areas) > 1:
# We’re combining simplified polygons from multiple areas so we
diff --git a/app/templates/views/broadcast/macros/area-map.html b/app/templates/views/broadcast/macros/area-map.html
index ceef09776..6fdd9c1dd 100644
--- a/app/templates/views/broadcast/macros/area-map.html
+++ b/app/templates/views/broadcast/macros/area-map.html
@@ -6,7 +6,7 @@
- An area of {{ (broadcast_message.simple_polygons.estimated_area)|round_to_significant_figures(1)|format_thousands }} square miles
+ An area of {{ (broadcast_message.simple_polygons.estimated_area)|square_metres_to_square_miles|round_to_significant_figures(1)|format_thousands }} square miles
Will get
@@ -20,7 +20,7 @@
- An extra area of {{ (broadcast_message.simple_polygons_with_bleed.estimated_area - broadcast_message.simple_polygons.estimated_area)|round_to_significant_figures(1)|format_thousands }} square miles is
+ An extra area of {{ (broadcast_message.simple_polygons_with_bleed.estimated_area - broadcast_message.simple_polygons.estimated_area)|square_metres_to_square_miles|round_to_significant_figures(1)|format_thousands }} square miles is
Likely to get
diff --git a/requirements.in b/requirements.in
index 7fea7cd4a..138d8d730 100644
--- a/requirements.in
+++ b/requirements.in
@@ -31,7 +31,7 @@ pyproj==3.2.1
awscli-cwlogs>=1.4,<1.5
itsdangerous==1.1.0 # pyup: <2
-notifications-utils @ git+https://github.com/alphagov/notifications-utils.git@48.0.0
+notifications-utils @ git+https://github.com/alphagov/notifications-utils.git@49.0.0
govuk-frontend-jinja @ git+https://github.com/alphagov/govuk-frontend-jinja.git@v0.5.8-alpha
# cryptography 3.4+ incorporates Rust code, which isn't supported on PaaS
diff --git a/requirements.txt b/requirements.txt
index 44cb309fb..23c0b431d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -123,7 +123,7 @@ mistune==0.8.4
# via notifications-utils
notifications-python-client==6.3.0
# via -r requirements.in
-notifications-utils @ git+https://github.com/alphagov/notifications-utils.git@48.0.0
+notifications-utils @ git+https://github.com/alphagov/notifications-utils.git@49.0.0
# via -r requirements.in
openpyxl==3.0.7
# via pyexcel-xlsx
@@ -165,7 +165,9 @@ pyparsing==2.4.7
pypdf2==1.26.0
# via notifications-utils
pyproj==3.2.1
- # via -r requirements.in
+ # via
+ # -r requirements.in
+ # notifications-utils
python-dateutil==2.8.1
# via
# awscli-cwlogs
diff --git a/tests/app/broadcast_areas/custom_polygons.py b/tests/app/broadcast_areas/custom_polygons.py
index e79360649..0ef23bd08 100644
--- a/tests/app/broadcast_areas/custom_polygons.py
+++ b/tests/app/broadcast_areas/custom_polygons.py
@@ -15,11 +15,11 @@ SKYE = [
]
SANTA_A = [
- [25.8890, 66.5500],
- [25.8890, 66.551],
- [25.8910, 66.551],
- [25.8910, 66.5500],
- [25.889, 66.55000],
+ [66.5500, 25.8890],
+ [66.551, 25.8890],
+ [66.551, 25.8910],
+ [66.5500, 25.8910],
+ [66.55000, 25.889],
]
BURFORD = [
diff --git a/tests/app/broadcast_areas/test_broadcast_area.py b/tests/app/broadcast_areas/test_broadcast_area.py
index ef862f10d..a5d5090b5 100644
--- a/tests/app/broadcast_areas/test_broadcast_area.py
+++ b/tests/app/broadcast_areas/test_broadcast_area.py
@@ -101,7 +101,7 @@ def test_has_polygons():
assert len(scotland.polygons) == 195
assert england.polygons.as_coordinate_pairs_lat_long[0][0] == [
- 55.811085, -2.034358 # https://goo.gl/maps/wsf2LUWzYinwydMk8
+ 55.81108, -2.03436 # https://goo.gl/maps/HMFHGogohXdh9ggo8
]
@@ -276,24 +276,24 @@ def test_estimate_number_of_smartphones_for_population(
@pytest.mark.parametrize('area, expected_phones_per_square_mile', (
(
# Islington (most dense in UK)
- 'lad20-E09000019', 21_348
+ 'lad20-E09000019', 32_662
),
(
# Cordwainer Ward (City of London)
# This is higher than Islington because we inflate the
# popualtion to account for daytime workers
- 'wd20-E05009300', 310_674
+ 'wd20-E05009300', 392_870
),
(
# Crewe East
- 'wd20-E05008621', 2_078),
+ 'wd20-E05008621', 3_289),
(
# Eden (Cumbria, least dense in England)
- 'lad20-E07000030', 25.57
+ 'lad20-E07000030', 43.41
),
(
# Highland (least dense in UK)
- 'lad20-S12000017', 4.40
+ 'lad20-S12000017', 6.97
),
))
def test_phone_density(
@@ -305,44 +305,40 @@ def test_phone_density(
)
-@pytest.mark.parametrize('area, expected_bleed_in_m, expected_bleed_in_degrees', (
+@pytest.mark.parametrize('area, expected_bleed_in_m', (
(
# Islington (most dense in UK)
- 'lad20-E09000019', 500, 0.00449
+ 'lad20-E09000019', 500
),
(
# Cordwainer Ward (City of London)
# Special case because of inflated daytime population
- 'wd20-E05009300', 500, 0.00449
+ 'wd20-E05009300', 500
),
(
# Crewe East
- 'wd20-E05008621', 1_752, 0.01574
+ 'wd20-E05008621', 1_504
),
(
# Eden (Cumbria, least dense in England)
- 'lad20-E07000030', 4_140, 0.0372
+ 'lad20-E07000030', 3_852
),
(
# Highland (least dense in UK)
- 'lad20-S12000017', 5_000, 0.0449
+ 'lad20-S12000017', 4_846
),
(
# No population data available
- 'test-santa-claus-village-rovaniemi-a', 1_500, 0.01347
+ 'test-santa-claus-village-rovaniemi-a', 1_500
)
))
def test_estimated_bleed(
- area, expected_bleed_in_m, expected_bleed_in_degrees,
+ area, expected_bleed_in_m
):
assert close_enough(
broadcast_area_libraries.get_areas([area])[0].estimated_bleed_in_m,
expected_bleed_in_m,
)
- assert close_enough(
- broadcast_area_libraries.get_areas([area])[0].estimated_bleed_in_degrees,
- expected_bleed_in_degrees,
- )
@pytest.mark.parametrize('polygon, expected_possible_overlaps, expected_count_of_phones', (
@@ -362,7 +358,7 @@ def test_estimated_bleed(
'Stoke Bishop',
'Windmill Hill',
],
- 73_119,
+ 72_817,
),
(
SKYE,
@@ -372,7 +368,7 @@ def test_estimated_bleed(
'Na Hearadh agus Ceann a Deas nan Loch',
'Wester Ross, Strathpeffer and Lochalsh',
],
- 3_534,
+ 3_413,
),
))
def test_count_of_phones_for_custom_area(
diff --git a/tests/app/broadcast_areas/test_models.py b/tests/app/broadcast_areas/test_models.py
index 23b9933d2..0437ac561 100644
--- a/tests/app/broadcast_areas/test_models.py
+++ b/tests/app/broadcast_areas/test_models.py
@@ -5,7 +5,7 @@ from tests.app.broadcast_areas.custom_polygons import BRISTOL, SANTA_A, SKYE
@pytest.mark.parametrize(('simple_polygon', 'expected_wards_length'), [
- (SKYE, 2),
+ (SKYE, 1),
(BRISTOL, 12),
(SANTA_A, 0) # does not overlap with UK
])
diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py
index dcdec0f9c..21e2f815d 100644
--- a/tests/app/main/views/test_broadcast.py
+++ b/tests/app/main/views/test_broadcast.py
@@ -837,8 +837,8 @@ def test_broadcast_page(
'England Remove England',
'Scotland Remove Scotland',
], [
- 'An area of 200,000 square miles Will get the alert',
- 'An extra area of 8,000 square miles is Likely to get the alert',
+ 'An area of 100,000 square miles Will get the alert',
+ 'An extra area of 6,000 square miles is Likely to get the alert',
'40,000,000 phones estimated',
]),
([
@@ -854,8 +854,8 @@ def test_broadcast_page(
'Penrith South Remove Penrith South',
'Penrith West Remove Penrith West',
], [
- 'An area of 6 square miles Will get the alert',
- 'An extra area of 20 square miles is Likely to get the alert',
+ 'An area of 4 square miles Will get the alert',
+ 'An extra area of 10 square miles is Likely to get the alert',
'9,000 to 10,000 phones',
]),
([
@@ -863,17 +863,17 @@ def test_broadcast_page(
], [
'Islington Remove Islington',
], [
- 'An area of 10 square miles Will get the alert',
- 'An extra area of 5 square miles is Likely to get the alert',
- '200,000 to 500,000 phones',
+ 'An area of 6 square miles Will get the alert',
+ 'An extra area of 4 square miles is Likely to get the alert',
+ '200,000 to 600,000 phones',
]),
([
'ctyua19-E10000019',
], [
'Lincolnshire Remove Lincolnshire',
], [
- 'An area of 4,000 square miles Will get the alert',
- 'An extra area of 700 square miles is Likely to get the alert',
+ 'An area of 2,000 square miles Will get the alert',
+ 'An extra area of 500 square miles is Likely to get the alert',
'500,000 to 600,000 phones',
]),
([
@@ -882,8 +882,8 @@ def test_broadcast_page(
], [
'Lincolnshire Remove Lincolnshire', 'North Yorkshire Remove North Yorkshire',
], [
- 'An area of 10,000 square miles Will get the alert',
- 'An extra area of 2,000 square miles is Likely to get the alert',
+ 'An area of 6,000 square miles Will get the alert',
+ 'An extra area of 1,000 square miles is Likely to get the alert',
'1,000,000 phones estimated',
]),
))
@@ -936,7 +936,7 @@ def test_preview_broadcast_areas_page(
[[7, 8], [9, 10], [11, 12]],
],
[
- 'An area of 700 square miles Will get the alert',
+ 'An area of 1,000 square miles Will get the alert',
'An extra area of 1,000 square miles is Likely to get the alert',
'Unknown number of phones',
]
@@ -944,17 +944,17 @@ def test_preview_broadcast_areas_page(
(
[BRISTOL],
[
- 'An area of 7 square miles Will get the alert',
- 'An extra area of 6 square miles is Likely to get the alert',
+ 'An area of 4 square miles Will get the alert',
+ 'An extra area of 3 square miles is Likely to get the alert',
'70,000 to 100,000 phones',
]
),
(
[SKYE],
[
- 'An area of 3,000 square miles Will get the alert',
- 'An extra area of 800 square miles is Likely to get the alert',
- '4,000 phones estimated',
+ 'An area of 2,000 square miles Will get the alert',
+ 'An extra area of 600 square miles is Likely to get the alert',
+ '3,000 to 4,000 phones',
]
),
))
diff --git a/tests/app/models/test_broadcast_message.py b/tests/app/models/test_broadcast_message.py
index d59800842..b964899ae 100644
--- a/tests/app/models/test_broadcast_message.py
+++ b/tests/app/models/test_broadcast_message.py
@@ -45,7 +45,7 @@ def test_simple_polygons():
# Because the areas are close to each other, the simplification
# and unioning process results in a single polygon with fewer
# total coordinates
- [55],
+ [57],
]