[NUUG fiksgatami] [patch] Add support for norwegian post codes in mapit
Petter Reinholdtsen
pere at hungry.com
Sat Mar 5 09:26:42 CET 2011
[Petter Reinholdtsen]
> Here is a patch
Gah, as usual, I forgot to include the patch. Second try.
Happy hacking,
--
Petter Reinholdtsen
-------------- next part --------------
diff --git a/pylib/mapit/postcodes/models.py b/pylib/mapit/postcodes/models.py
index 4669f08..1d240e3 100644
--- a/pylib/mapit/postcodes/models.py
+++ b/pylib/mapit/postcodes/models.py
@@ -1,4 +1,5 @@
import re
+import mysociety
from django.contrib.gis.db import models
from django.db import connection, transaction
from mapit.managers import GeoManager
@@ -39,7 +40,10 @@ class Postcode(models.Model):
return self.get_postcode_display()
def get_postcode_display(self):
- return re.sub('(...)$', r' \1', self.postcode).strip()
+ if mysociety.config.get('COUNTRY') == 'GB':
+ return re.sub('(...)$', r' \1', self.postcode).strip()
+ else: # 'NO'
+ return self.postcode
def as_dict(self):
if not self.location:
diff --git a/pylib/mapit/postcodes/utils.py b/pylib/mapit/postcodes/utils.py
index b3f4943..e4f9286 100644
--- a/pylib/mapit/postcodes/utils.py
+++ b/pylib/mapit/postcodes/utils.py
@@ -1,8 +1,16 @@
import re
+import mysociety
def is_valid_postcode(pc):
pc = re.sub('\s+', '', pc.upper())
+ if mysociety.config.get('COUNTRY') == 'GB':
+ return is_valid_gb_postcode(pc)
+ elif mysociety.config.get('COUNTRY') == 'NO':
+ return is_valid_no_postcode(pc)
+ return False
+
+def is_valid_gb_postcode(pc):
# Our test postcode
if pc in ('ZZ99ZZ', 'ZZ99ZY'): return True
@@ -38,9 +46,23 @@ def is_valid_postcode(pc):
return False
+# Norwegian postcodes are four digits. Some put "no-" in front, but
+# this is ignored here.
+def is_valid_no_postcode(pc):
+ if re.match('^[0-9]{4}$', pc):
+ return True
+ return False
+
def is_valid_partial_postcode(pc):
pc = re.sub('\s+', '', pc.upper())
+ if mysociety.config.get('COUNTRY') == 'GB':
+ return is_valid_partial_gb_postcode(pc)
+ elif mysociety.config.get('COUNTRY') == 'NO':
+ return is_valid_partial_gb_postcode(pc)
+ return False
+
+def is_valid_partial_gb_postcode(pc):
# Our test postcode
if pc == 'ZZ9': return True
@@ -60,3 +82,8 @@ def is_valid_partial_postcode(pc):
return False
+# Should match one, two and three digits. FIXME: Do not work at the moment.
+def is_valid_partial_no_postcode(pc):
+ if re.match('^[0-9]{1,3}$', pc):
+ return True
+ return False
diff --git a/pylib/mapit/templates/no/index.html b/pylib/mapit/templates/no/index.html
index 36a859d..8a5cc8c 100644
--- a/pylib/mapit/templates/no/index.html
+++ b/pylib/mapit/templates/no/index.html
@@ -47,6 +47,22 @@ following keys: id, name, country, type, parent_area, generation_low,
generation_high, codes.</p>
<div id="col1">
+<h3>By postcode</h3>
+
+<ul>
+
+<li>/postcode/<i>[postcode]</i> – information on a particular
+postcode, including its location in WGS84 latitude/longitude, and the
+areas it is contained within. You may specify a previous generation as
+a ?generation=N parameter. <a href="/postcode/0373.html">Example
+postcode lookup</a>.</li>
+
+<li>/postcode/partial/<i>[partial postcode]</i> – location
+information on the centroid of a partial
+postcode. <a href="/postcode/partial/85.html">Example partial
+postcode lookup</a>.</li>
+
+</ul>
<h3>Multiple areas</h3>
--- /dev/null 2011-03-04 10:52:18.978954342 +0100
+++ pylib/mapit/postcodes/management/commands/import_bolstad_postcodes.py 2011-03-05 09:07:53.000000000 +0100
@@ -0,0 +1,50 @@
+# This script is used to import Norwegian postcode information from
+# http://www.erikbolstad.no/geo/noreg/postnummer/, released by the
+# Erik Bolstad.
+# http://www.erikbolstad.no/nedlasting/postnummer-utf8.txt
+#
+# The fields of Code-Point Open CSV file are:
+# Postnummer, Poststad, Bruksomraade, Kommunenummer, Kommune, Fylke,
+# Lat, Lon, Merknad
+
+import csv
+from django.contrib.gis.geos import Point
+from django.core.management.base import LabelCommand
+from mapit.postcodes.models import Postcode
+
+class Command(LabelCommand):
+ help = 'Import Norwegian postcodes from the Erik Bolstad data set'
+ args = '<CSV files>'
+ count = { 'total': 0, 'updated': 0, 'unchanged': 0, 'created': 0 }
+ def print_stats(self):
+ print "Imported %d (%d new, %d changed, %d same)" % (
+ self.count['total'], self.count['created'],
+ self.count['updated'], self.count['unchanged']
+ )
+ def handle_label(self, file, **options):
+ csv.register_dialect('tabs', delimiter='\t')
+ for row in csv.reader(open(file), dialect='tabs'):
+ postcode = row[0].strip().replace(' ', '')
+# print "'%s' '%s' '%s'" % (row, row[6:7], row[7:8])
+ if 0 == cmp('Lat',row[6]): continue # skip header
+ lat = float(row[6:7].pop())
+ lon = float(row[7:8].pop())
+ location = Point(lon, lat, srid=4326)
+ # Want to compare co-ordinates so can't use straightforward
+ # update_or_create
+ try:
+ pc = Postcode.objects.get(postcode=postcode)
+ if pc.location[0] != location[0] or \
+ pc.location[1] != location[1]:
+ pc.location = location
+ pc.save()
+ self.count['updated'] += 1
+ else:
+ self.count['unchanged'] += 1
+ except Postcode.DoesNotExist:
+ Postcode.objects.create(postcode=postcode, location=location)
+ self.count['created'] += 1
+ self.count['total'] += 1
+ if self.count['total'] % 1000 == 0:
+ self.print_stats()
+ self.print_stats()
More information about the fiksgatami
mailing list