Merge pull request #3565 from alphagov/polygon-overspill

Show indication of how a broadcast will overspill the selected area
This commit is contained in:
Chris Hill-Scott
2020-08-13 16:37:52 +01:00
committed by GitHub
9 changed files with 82 additions and 5 deletions

View File

@@ -138,5 +138,17 @@ class BroadcastAreaLibraries(SerialisedModelCollection, GetItemByIdMixin):
for polygon in self.get_polygons_for_areas_long_lat(*area_ids)
]
def get_simple_polygons_for_areas_long_lat(self, *area_ids):
return list(itertools.chain(*(
area.simple_polygons
for area in self.get_areas(*area_ids)
)))
def get_simple_polygons_for_areas_lat_long(self, *area_ids):
return [
[[long, lat] for lat, long in polygon]
for polygon in self.get_simple_polygons_for_areas_long_lat(*area_ids)
]
broadcast_area_libraries = BroadcastAreaLibraries()

View File

@@ -4,9 +4,9 @@ from copy import deepcopy
from pathlib import Path
import geojson
import shapely.geometry as sgeom
from notifications_utils.safe_string import make_string_safe_for_id
import shapely.geometry as sgeom
from repo import BroadcastAreasRepository
package_path = Path(__file__).resolve().parent

View File

@@ -3,12 +3,12 @@
from random import sample
import geojson
import shapely.geometry as sgeom
from notifications_utils.safe_string import make_string_safe_for_id
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
from repo import BroadcastAreasRepository

View File

@@ -2,6 +2,8 @@ from datetime import datetime
from notifications_utils.template import BroadcastPreviewTemplate
from orderedset import OrderedSet
from shapely.geometry import MultiPolygon, Polygon
from shapely.ops import unary_union
from werkzeug.utils import cached_property
from app.broadcast_areas import broadcast_area_libraries
@@ -76,6 +78,25 @@ class BroadcastMessage(JSONModel):
*self._dict['areas']
)
@property
def simple_polygons(self):
simple_polygons = broadcast_area_libraries.get_simple_polygons_for_areas_lat_long(
*self._dict['areas']
)
unioned_polygons = unary_union([
Polygon(i) for i in simple_polygons
])
if isinstance(unioned_polygons, MultiPolygon):
return [
[
[x, y] for x, y in p.exterior.coords
]
for p in unioned_polygons
]
return [[
[x, y] for x, y in unioned_polygons.exterior.coords
]]
@property
def template(self):
response = service_api_client.get_service_template(

View File

@@ -36,12 +36,23 @@
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(mymap);
{% for polygon in broadcast_message.simple_polygons %}
polygons.push(
L.polygon({{polygon}}, {
color: '#2B8CC4', // $light-blue
opacity: 0.4,
fillColor: '#2B8CC4', // $light-blue
fillOpacity: 0.3,
weight: 1
})
);
{% endfor %}
{% for polygon in broadcast_message.polygons %}
polygons.push(
L.polygon({{polygon}}, {
color: '#0b0b0c', // $black
fillColor: '#2B8CC4', // $light-blue
fillOpacity: 0.2,
fillOpacity: 0,
weight: 2
})
);

View File

@@ -18,6 +18,7 @@ pytz==2020.1
gunicorn==20.0.4
eventlet==0.26.1
notifications-python-client==5.7.0
Shapely==1.7.0
# PaaS
awscli-cwlogs>=1.4,<1.5

View File

@@ -20,6 +20,7 @@ pytz==2020.1
gunicorn==20.0.4
eventlet==0.26.1
notifications-python-client==5.7.0
Shapely==1.7.0
# PaaS
awscli-cwlogs>=1.4,<1.5

View File

@@ -649,6 +649,7 @@ def broadcast_message_json(
cancelled_at=None,
approved_by_id=None,
cancelled_by_id=None,
areas=None,
):
return {
'id': id_,
@@ -660,7 +661,7 @@ def broadcast_message_json(
'template_name': 'Example template',
'personalisation': {},
'areas': [
'areas': areas or [
'countries-E92000001', 'countries-S92000003',
],

View File

@@ -0,0 +1,30 @@
from app.models.broadcast_message import BroadcastMessage
from tests import broadcast_message_json
def test_simple_polygons(fake_uuid):
broadcast_message = BroadcastMessage(broadcast_message_json(
id_=fake_uuid,
service_id=fake_uuid,
template_id=fake_uuid,
status='draft',
created_by_id=fake_uuid,
areas=[
# Hackney Central
'electoral-wards-of-the-united-kingdom-E05009372',
# Hackney Wick
'electoral-wards-of-the-united-kingdom-E05009374',
],
))
assert [
[len(polygon) for polygon in broadcast_message.polygons],
[len(polygon) for polygon in broadcast_message.simple_polygons],
] == [
# One polygon for each area
[27, 31],
# Because the areas are close to each other, the simplification
# and unioning process results in a single polygon with fewer
# total coordinates
[34],
]