-
Notifications
You must be signed in to change notification settings - Fork 88
/
countries.py
149 lines (123 loc) · 5.34 KB
/
countries.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import re
from django.urls import reverse, NoReverseMatch
from django.http import HttpResponseRedirect
from ukpostcodeutils import validation
from mapit.shortcuts import get_object_or_404
def area_code_lookup(request, area_code, format):
from mapit.models import Area, CodeType
area_code_type = None
if re.match(r'\d\d([A-Z]{2}|[A-Z]{4}|[A-Z]{2}\d\d\d|[A-Z]|[A-Z]\d\d)$', area_code):
area_code_type = CodeType.objects.get(code='ons')
elif re.match(r'[ESW]0[12]\d{6}$', area_code): # LSOA/MSOA have ONS code type
area_code_type = CodeType.objects.get(code='ons')
elif re.match(r'[ENSW]\d{8}$', area_code):
area_code_type = CodeType.objects.get(code='gss')
if not area_code_type:
return None
args = {'format': format, 'codes__type': area_code_type, 'codes__code': area_code}
if re.match('[EW]01', area_code):
args['type__code'] = 'OLF'
elif re.match('[EW]02', area_code):
args['type__code'] = 'OMF'
area = get_object_or_404(Area, **args)
area_kwargs = {'area_id': area.id}
if format:
area_kwargs['format'] = format
# We're called either by area or area_polygon
try:
redirect_path = reverse('area', kwargs=area_kwargs)
except NoReverseMatch:
redirect_path = reverse('area_polygon', kwargs=area_kwargs)
# If there was a query string, make sure it's passed on in the
# redirect:
if request.META['QUERY_STRING']:
redirect_path += "?" + request.META['QUERY_STRING']
return HttpResponseRedirect(redirect_path)
def canonical_postcode(pc):
pc = re.sub('[^A-Z0-9]', '', pc.upper())
return pc
SPECIAL_POSTCODES = (
'ASCN1ZZ', # Ascension Island
'BBND1ZZ', # BIOT
'BIQQ1ZZ', # British Antarctic Territory
'FIQQ1ZZ', # Falkland Islands
'PCRN1ZZ', # Pitcairn Islands
'SIQQ1ZZ', # South Georgia and the South Sandwich Islands
'STHL1ZZ', # St Helena
'TDCU1ZZ', # Tristan da Cunha
'TKCA1ZZ', # Turks and Caicos Islands
'GIR0AA', 'G1R0AA', # Girobank
'SANTA1', 'XM45HQ', # Santa Claus
)
def is_special_postcode(pc):
return pc in SPECIAL_POSTCODES
def is_valid_postcode(pc):
return validation.is_valid_postcode(pc, SPECIAL_POSTCODES + ('ZZ99ZZ', 'ZZ99ZY'))
def is_valid_partial_postcode(pc):
return validation.is_valid_partial_postcode(pc, ('ZZ9',))
def get_postcode_display(pc):
return re.sub('([0-9]..)$', r' \1', pc).strip()
def augment_postcode(postcode, result):
pc = postcode.postcode
if is_special_postcode(pc):
return
loc = postcode.as_uk_grid()
result['coordsyst'] = 'I' if pc[0:2] == 'BT' else 'G'
result['easting'] = loc[0]
result['northing'] = loc[1]
# Hacky function to restrict certain geographical links in the HTML pages to
# types to make them more likely to return results.
def restrict_geo_html(area):
geotype = {}
if area.type.code == 'EUR':
geotype = {'touches': ['EUR'], 'overlaps': ['UTA'], 'covers': ['UTA'], 'coverlaps': ['UTA']}
elif area.type.code in ('CTY', 'UTA'):
geotype = {
'touches': ['CTY', 'DIS', 'MTD', 'LBO', 'COI', 'UTA'],
'overlaps': ['WMC'],
'covers': ['CED', 'DIW', 'MTW', 'LBW', 'UTE', 'UTW'],
'coverlaps': ['CED', 'DIW', 'MTW', 'LBW', 'UTE', 'UTW']}
elif area.type.code == 'COI':
geotype = {'covers': ['CPC'], 'coverlaps': ['CPC']}
elif area.type.code == 'LGD':
geotype = {'overlaps': ['LGE', 'LGW'], 'coverlaps': ['LGE', 'LGW']}
elif area.type.code == 'GLA':
geotype = {'touches': ['CTY', 'UTA'], 'overlaps': ['WMC'], 'covers': ['LBO'], 'coverlaps': ['WMC']}
elif area.type.code == 'SPE':
geotype = {'touches': ['SPE'], 'overlaps': ['UTA'], 'covers': ['UTA'], 'coverlaps': ['UTA']}
elif area.type.code == 'WAE':
geotype = {'touches': ['WAE'], 'overlaps': ['UTA'], 'covers': ['UTA'], 'coverlaps': ['UTA']}
for k, v in geotype.items():
geotype[k] = ['?type=%s' % ','.join(v), ' (%s)' % ', '.join(v)]
return geotype
def make_friendly_name(name_obj, name):
n = re.sub(r'\s+', ' ', name.name.strip())
n = n.replace('St. ', 'St ')
if name.type.code == 'M':
return n
if name.type.code == 'S':
return n
# Type must be 'O' here
n = re.sub(' Euro Region$', '', n) # EUR
n = re.sub(' (Burgh|Co|Boro) Const$', '', n) # WMC
n = re.sub(' P Const$', '', n) # SPC
n = re.sub(' PER$', '', n) # SPE
n = re.sub(' GL Assembly Const$', '', n) # LAC
n = re.sub(' Assembly Const$', '', n) # WAC
n = re.sub(' Assembly ER$', '', n) # WAE
n = re.sub(' London Boro$', ' Borough', n) # LBO
if name_obj.area.country and name_obj.area.country.name == 'Wales':
n = re.sub('^.*? - ', '', n) # UTA
n = re.sub(r'(?:The )?City of (.*?) (District )?\(B\)$', r'\1 City', n) # UTA
n = re.sub(r' District \(B\)$', ' Borough', n) # DIS
n = re.sub(r' \(B\)$', ' Borough', n) # DIS
if name_obj.area.type.code in ('CTY', 'DIS', 'LBO', 'UTA', 'MTD'):
n += ' Council'
n = re.sub(' (ED|CP)$', '', n) # CPC, CED, UTE
n = re.sub(' Ward$', '', n) # DIW, LBW, MTW, UTW
return n
def name_save_hook(name_obj):
name = name_obj.area.names.filter(type__code__in=('M', 'O', 'S')).order_by('type__code')[:1]
if name:
name_obj.area.name = make_friendly_name(name_obj, name[0])
name_obj.area.save()