mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-06 15:08:25 -04:00
broadcast-areas: create broadcast areas in groups
Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
This commit is contained in:
@@ -1,15 +1,26 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
import sqlite3
|
||||||
import geojson
|
import geojson
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import shapely.geometry as sgeom
|
import shapely.geometry as sgeom
|
||||||
|
|
||||||
|
from notifications_utils.safe_string import make_string_safe_for_id
|
||||||
|
|
||||||
from repo import BroadcastAreasRepository
|
from repo import BroadcastAreasRepository
|
||||||
|
|
||||||
package_path = Path(__file__).resolve().parent
|
package_path = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def convert_shape_to_feature(shape):
|
||||||
|
return {
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {},
|
||||||
|
"geometry": sgeom.mapping(shape),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def simplify_polygon(series):
|
def simplify_polygon(series):
|
||||||
polygon, *_holes = series # discard holes
|
polygon, *_holes = series # discard holes
|
||||||
|
|
||||||
@@ -26,7 +37,7 @@ def simplify_polygon(series):
|
|||||||
simplified_polygon = [[c[0], c[1]] for c in simplified_polygon.exterior.coords]
|
simplified_polygon = [[c[0], c[1]] for c in simplified_polygon.exterior.coords]
|
||||||
|
|
||||||
num_polys = len(simplified_polygon)
|
num_polys = len(simplified_polygon)
|
||||||
simplify_degrees *= 1.5
|
simplify_degrees *= 1.75
|
||||||
if num_polys <= 125:
|
if num_polys <= 125:
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -53,22 +64,30 @@ repo.delete_db()
|
|||||||
repo.create_tables()
|
repo.create_tables()
|
||||||
|
|
||||||
simple_datasets = [
|
simple_datasets = [
|
||||||
("Countries", "ctry19nm"),
|
("Countries", "ctry19cd", "ctry19nm"),
|
||||||
("Regions of England", "rgn18nm"),
|
("Regions of England", "rgn18cd", "rgn18nm"),
|
||||||
("Counties and Unitary Authorities in England and Wales", "ctyua16nm"),
|
("Counties and Unitary Authorities in England and Wales", "ctyua16cd", "ctyua16nm"),
|
||||||
]
|
]
|
||||||
for dataset_name, name_field in simple_datasets:
|
for dataset_name, id_field, name_field in simple_datasets:
|
||||||
filepath = package_path / "{}.geojson".format(dataset_name)
|
filepath = package_path / "{}.geojson".format(dataset_name)
|
||||||
|
|
||||||
|
dataset_id = make_string_safe_for_id(dataset_name)
|
||||||
dataset_geojson = geojson.loads(filepath.read_text())
|
dataset_geojson = geojson.loads(filepath.read_text())
|
||||||
|
|
||||||
repo.insert_broadcast_area_library(dataset_name)
|
repo.insert_broadcast_area_library(dataset_id, dataset_name, False)
|
||||||
|
|
||||||
for feature in dataset_geojson["features"]:
|
for feature in dataset_geojson["features"]:
|
||||||
|
f_id = dataset_id + "-" + feature["properties"][id_field]
|
||||||
f_name = feature["properties"][name_field]
|
f_name = feature["properties"][name_field]
|
||||||
|
|
||||||
simple_feature = deepcopy(feature)
|
simple_feature = deepcopy(feature)
|
||||||
simple_feature["geometry"] = simplify_geometry(simple_feature["geometry"])
|
simple_feature["geometry"] = simplify_geometry(simple_feature["geometry"])
|
||||||
repo.insert_broadcast_areas([[f_name, dataset_name, feature, simple_feature]])
|
|
||||||
|
repo.insert_broadcast_areas([[
|
||||||
|
f_id, f_name,
|
||||||
|
dataset_id, None,
|
||||||
|
feature, simple_feature,
|
||||||
|
]])
|
||||||
|
|
||||||
# https://geoportal.statistics.gov.uk/datasets/wards-may-2020-boundaries-uk-bgc
|
# https://geoportal.statistics.gov.uk/datasets/wards-may-2020-boundaries-uk-bgc
|
||||||
# Converted to geojson manually from SHP because of GeoJSON download limits
|
# Converted to geojson manually from SHP because of GeoJSON download limits
|
||||||
@@ -81,28 +100,73 @@ ward_code_to_la_mapping = {
|
|||||||
f["properties"]["WD19CD"]: f["properties"]["LAD19NM"]
|
f["properties"]["WD19CD"]: f["properties"]["LAD19NM"]
|
||||||
for f in geojson.loads(las_filepath.read_text())["features"]
|
for f in geojson.loads(las_filepath.read_text())["features"]
|
||||||
}
|
}
|
||||||
|
ward_code_to_la_id_mapping = {
|
||||||
|
f["properties"]["WD19CD"]: f["properties"]["LAD19CD"]
|
||||||
|
for f in geojson.loads(las_filepath.read_text())["features"]
|
||||||
|
}
|
||||||
|
|
||||||
dataset_name = "Electoral Wards of the United Kingdom"
|
dataset_name = "Electoral Wards of the United Kingdom"
|
||||||
repo.insert_broadcast_area_library(dataset_name)
|
dataset_id = make_string_safe_for_id(dataset_name)
|
||||||
|
repo.insert_broadcast_area_library(dataset_id, dataset_name, True)
|
||||||
|
|
||||||
|
for f in geojson.loads(las_filepath.read_text())["features"]:
|
||||||
|
group_id = dataset_id + "-" + f["properties"]["LAD19CD"]
|
||||||
|
group_name = f["properties"]["LAD19NM"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
repo.insert_broadcast_area_library_group(group_id, group_name, dataset_id)
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
# Already exists
|
||||||
|
pass
|
||||||
|
|
||||||
areas_to_add = []
|
areas_to_add = []
|
||||||
|
|
||||||
for f in geojson.loads(wards_filepath.read_text())["features"]:
|
for f in geojson.loads(wards_filepath.read_text())["features"]:
|
||||||
|
|
||||||
ward_code = f["properties"]["wd20cd"]
|
ward_code = f["properties"]["wd20cd"]
|
||||||
ward_name = f["properties"]["wd20nm"]
|
ward_name = f["properties"]["wd20nm"]
|
||||||
|
ward_id = dataset_id + "-" + ward_code
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
la_id = dataset_id + "-" + ward_code_to_la_id_mapping[ward_code]
|
||||||
la_name = ward_code_to_la_mapping[ward_code]
|
la_name = ward_code_to_la_mapping[ward_code]
|
||||||
|
|
||||||
f_name = "{} - {}".format(la_name, ward_name)
|
|
||||||
|
|
||||||
sf = deepcopy(f)
|
sf = deepcopy(f)
|
||||||
sf["geometry"] = simplify_geometry(sf["geometry"])
|
sf["geometry"] = simplify_geometry(sf["geometry"])
|
||||||
|
|
||||||
areas_to_add.append([f_name, dataset_name, f, sf])
|
areas_to_add.append([
|
||||||
|
ward_id, ward_name,
|
||||||
|
dataset_id, la_id,
|
||||||
|
f, sf
|
||||||
|
])
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print("Skipping", ward_code, ward_name) # noqa: T001
|
print("Skipping", ward_code, ward_name) # noqa: T001
|
||||||
|
|
||||||
repo.insert_broadcast_areas(areas_to_add)
|
repo.insert_broadcast_areas(areas_to_add)
|
||||||
|
areas_to_add = []
|
||||||
|
|
||||||
|
for group_id, group_name in repo.get_all_groups_for_library(dataset_id):
|
||||||
|
areas = repo.get_all_areas_for_group(group_id)
|
||||||
|
|
||||||
|
features = [geojson.loads(f) for _, _, f, _ in areas]
|
||||||
|
shapes = [sgeom.shape(f["geometry"]) for f in features]
|
||||||
|
|
||||||
|
if len(shapes) == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(group_id, group_name, "union")
|
||||||
|
shape = shapes[0]
|
||||||
|
for other in shapes[1:]:
|
||||||
|
shape = shape.buffer(0).union(other.buffer(0))
|
||||||
|
|
||||||
|
feature = convert_shape_to_feature(shape)
|
||||||
|
simple_feature = deepcopy(feature)
|
||||||
|
simple_feature["geometry"] = simplify_geometry(simple_feature["geometry"])
|
||||||
|
|
||||||
|
areas_to_add.append([
|
||||||
|
group_id, group_name,
|
||||||
|
dataset_id, None,
|
||||||
|
feature, simple_feature
|
||||||
|
])
|
||||||
|
|
||||||
|
repo.insert_broadcast_areas(areas_to_add)
|
||||||
|
|||||||
Reference in New Issue
Block a user