mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-23 09:29:14 -04:00
Merge pull request #3565 from alphagov/polygon-overspill
Show indication of how a broadcast will overspill the selected area
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -36,12 +36,23 @@
|
||||
attribution: '© <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
|
||||
})
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
|
||||
|
||||
30
tests/app/models/test_broadcast_message.py
Normal file
30
tests/app/models/test_broadcast_message.py
Normal 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],
|
||||
]
|
||||
Reference in New Issue
Block a user