cjber commited on
Commit
613cc82
·
1 Parent(s): 0d9117e

add themes and policies

Browse files
Files changed (1) hide show
  1. 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