Spaces:
Build error
Build error
add themes and policies
Browse files- planning_ai/themes.py +134 -0
planning_ai/themes.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from enum import Enum
|
2 |
+
|
3 |
+
from pydantic import BaseModel, field_validator
|
4 |
+
|
5 |
+
|
6 |
+
class Theme(str, Enum):
|
7 |
+
climate = "Climate change"
|
8 |
+
biodiversity = "Biodiversity and green spaces"
|
9 |
+
wellbeing = "Wellbeing and social inclusion"
|
10 |
+
great_places = "Great places"
|
11 |
+
jobs = "Jobs"
|
12 |
+
homes = "Homes"
|
13 |
+
infrastructure = "Infrastructure"
|
14 |
+
|
15 |
+
|
16 |
+
class ClimatePolicies(str, Enum):
|
17 |
+
CC_NZ = "Net zero carbon new buildings"
|
18 |
+
CC_WE = "Water efficiency in new developments"
|
19 |
+
CC_DC = "Designing for a changing climate"
|
20 |
+
CC_FM = "Flooding and integrated water management"
|
21 |
+
CC_RE = "Renewable energy projects and infrastructure"
|
22 |
+
CC_CE = "Reducing waste and supporting the circular economy"
|
23 |
+
CC_CS = "Supporting land-based carbon sequestration"
|
24 |
+
|
25 |
+
|
26 |
+
class BiodiversityPolicies(str, Enum):
|
27 |
+
BG_BG = "Biodiversity and geodiversity"
|
28 |
+
BG_GI = "Green infrastructure"
|
29 |
+
BG_TC = "Improving Tree Canopy Cover and the Tree Population"
|
30 |
+
BG_RC = "River corridors"
|
31 |
+
BG_PO = "Protecting open spaces"
|
32 |
+
BG_EO = "Providing and enhancing open spaces"
|
33 |
+
|
34 |
+
|
35 |
+
class WellbeingPolicies(str, Enum):
|
36 |
+
WS_HD = "Creating healthy new developments"
|
37 |
+
WS_CF = "Community, sports and leisure facilities"
|
38 |
+
WS_MU = "Meanwhile uses during long term redevelopments"
|
39 |
+
WS_IO = "Creating inclusive employment and business opportunities through new developments"
|
40 |
+
WS_HS = "Pollution, health and safety"
|
41 |
+
|
42 |
+
|
43 |
+
class GreatPlacesPolicies(str, Enum):
|
44 |
+
GP_PP = "People and place responsive design"
|
45 |
+
GP_LC = "Protection and enhancement of landscape character"
|
46 |
+
GP_GB = "Protection and enhancement of the Cambridge Green Belt"
|
47 |
+
GP_QD = "Achieving high quality development"
|
48 |
+
GP_QP = "Establishing high quality landscape and public realm"
|
49 |
+
GP_HA = "Conservation and enhancement of heritage assets"
|
50 |
+
GP_CC = "Adapting heritage assets to climate change"
|
51 |
+
GP_PH = "Protection of public houses"
|
52 |
+
|
53 |
+
|
54 |
+
class JobsPolicies(str, Enum):
|
55 |
+
J_NE = "New employment and development proposals"
|
56 |
+
J_RE = "Supporting the rural economy"
|
57 |
+
J_AL = "Protecting the best agricultural land"
|
58 |
+
J_PB = "Protecting existing business space"
|
59 |
+
J_RW = "Enabling remote working"
|
60 |
+
J_AW = "Affordable workspace and creative industries"
|
61 |
+
J_EP = "Supporting a range of facilities in employment parks"
|
62 |
+
J_RC = "Retail and centres"
|
63 |
+
J_VA = "Visitor accommodation, attractions and facilities"
|
64 |
+
J_FD = "Faculty development and specialist / language schools"
|
65 |
+
|
66 |
+
|
67 |
+
class HomesPolicies(str, Enum):
|
68 |
+
H_AH = "Affordable housing"
|
69 |
+
H_ES = "Exception sites for affordable housing"
|
70 |
+
H_HM = "Housing mix"
|
71 |
+
H_HD = "Housing density"
|
72 |
+
H_GL = "Garden land and subdivision of existing plots"
|
73 |
+
H_SS = "Residential space standards and accessible homes"
|
74 |
+
H_SH = "Specialist housing and homes for older people"
|
75 |
+
H_CB = "Self and custom build homes"
|
76 |
+
H_BR = "Build to rent homes"
|
77 |
+
H_MO = "Houses in multiple occupation (HMOs)"
|
78 |
+
H_SA = "Student accommodation"
|
79 |
+
H_DC = "Dwellings in the countryside"
|
80 |
+
H_RM = "Residential moorings"
|
81 |
+
H_RC = "Residential caravan sites"
|
82 |
+
H_GT = "Gypsy and Traveller and Travelling Showpeople sites"
|
83 |
+
H_CH = "Community-led housing"
|
84 |
+
|
85 |
+
|
86 |
+
class InfrastructurePolicies(str, Enum):
|
87 |
+
I_ST = "Sustainable transport and connectivity"
|
88 |
+
I_EV = "Parking and electric vehicles"
|
89 |
+
I_FD = "Freight and delivery consolidation"
|
90 |
+
I_SI = "Safeguarding important infrastructure"
|
91 |
+
I_AD = "Aviation development"
|
92 |
+
I_EI = "Energy infrastructure masterplanning"
|
93 |
+
I_ID = "Infrastructure and delivery"
|
94 |
+
I_DI = "Digital infrastructure"
|
95 |
+
|
96 |
+
|
97 |
+
THEME_TO_POLICY_GROUP = {
|
98 |
+
Theme.climate: ClimatePolicies,
|
99 |
+
Theme.biodiversity: BiodiversityPolicies,
|
100 |
+
Theme.wellbeing: WellbeingPolicies,
|
101 |
+
Theme.great_places: GreatPlacesPolicies,
|
102 |
+
Theme.jobs: JobsPolicies,
|
103 |
+
Theme.homes: HomesPolicies,
|
104 |
+
Theme.infrastructure: InfrastructurePolicies,
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
class PolicyDetail(BaseModel):
|
109 |
+
policy: str
|
110 |
+
details: list[str]
|
111 |
+
|
112 |
+
|
113 |
+
class PolicySelection(BaseModel):
|
114 |
+
theme: Theme
|
115 |
+
policies: list[PolicyDetail]
|
116 |
+
|
117 |
+
@field_validator("policies", mode="before")
|
118 |
+
@classmethod
|
119 |
+
def validate_policies(cls, policies, info):
|
120 |
+
"""Ensure policies match the selected theme."""
|
121 |
+
if not isinstance(policies, list):
|
122 |
+
raise ValueError("Policies must be provided as a list.")
|
123 |
+
|
124 |
+
theme = info.data.get("theme")
|
125 |
+
if not theme:
|
126 |
+
raise ValueError("Theme must be provided before validating policies.")
|
127 |
+
|
128 |
+
allowed_policies = [p.value for p in THEME_TO_POLICY_GROUP[theme]]
|
129 |
+
for policy in policies:
|
130 |
+
if policy["policy"] not in allowed_policies:
|
131 |
+
raise ValueError(
|
132 |
+
f"Policy '{policy['policy']}' is not valid for theme '{theme.value}'."
|
133 |
+
)
|
134 |
+
return policies
|