[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> &ndash; 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> &ndash; 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