Permalink
Browse files

Add an option to create a new area if polygons have changed

The default behaviour of the generic import script, if it finds
an area with the same name / code in a previous generation, is
to replace the polygons associated with that area.

However, we may want alternative behaviour, where if a new
generation of data has a changed boundary for an area whose
name / code remains the same, we create a new area with those
polygons and preserve the previous one.  This commit introduces
that change with the --preserve option.

Fixes #52
  • Loading branch information...
1 parent 49a3062 commit e9a6859bad446753a2f3a08746874d029efd35d2 @mhl mhl committed Jan 14, 2013
Showing with 46 additions and 5 deletions.
  1. +46 −5 mapit/management/commands/mapit_import.py
@@ -73,6 +73,12 @@ class Command(LabelCommand):
help="Set to use the code from code_field as the MapIt ID"
),
make_option(
+ '--preserve',
+ action="store_true",
+ dest='perserve',
+ help="Create a new area if the name's the same but polygons differ"
+ ),
+ make_option(
'--encoding',
action="store",
dest='encoding',
@@ -174,12 +180,49 @@ def handle_label(self, filename, **options):
print " looking at '%s'%s" % ( name.encode('utf-8'), (' (%s)' % code) if code else '' )
+ g = feat.geom.transform(4326, clone=True)
+
try:
if code:
- m = Area.objects.get(codes__code=code, codes__type=code_type)
+ matching_message = "code %s of code type %s" % (code, code_type)
+ areas = Area.objects.filter(codes__code=code, codes__type=code_type).order_by('-generation_high')
else:
- # Assumes unique names if no code column used
- m = Area.objects.get(name=name, type=area_type)
+ matching_message = "name %s of area type %s" % (name, area_type)
+ areas = Area.objects.filter(name=name, type=area_type).order_by('-generation_high')
+ if len(areas) == 0:
+ raise Area.DoesNotExist
+ m = areas[0]
+ if options['preserve']:
+ # Find whether we need to create a new Area:
+ previous_geos_geometry = m.polygons.collect()
+ if m.generation_high < current_generation.id:
+ # Then it was missing in current_generation:
+ create_new_area = True
+ elif previous_geos_geometry is None:
+ # It was empty in the previous generation:
+ create_new_area = True
+ else:
+ # Otherwise, create a new Area unless the
+ # polygons were the same in current_generation:
+ previous_geos_geometry = previous_geos_geometry.simplify(tolerance=0)
+ new_geos_geometry = g.geos.simplify(tolerance=0)
+ create_new_area = not previous_geos_geometry.equals(new_geos_geometry)
+ if create_new_area:
+ m = Area(
+ name = name,
+ type = area_type,
+ country = country,
+ # parent_area = parent_area,
+ generation_low = new_generation,
+ generation_high = new_generation
+ )
+ if options['use_code_as_id'] and code:
+ m.id = int(code)
+ else:
+ # If --preserve is not specified, the code or the name must be unique:
+ if len(areas) > 1:
+ raise Area.MultipleObjectsReturned, "There was more than one area with %s, and --preserve was not specified" % (matching_message,)
+
except Area.DoesNotExist:
m = Area(
name = name,
@@ -197,8 +240,6 @@ def handle_label(self, filename, **options):
raise Exception, "Area %s found, but not in current generation %s" % (m, current_generation)
m.generation_high = new_generation
- g = feat.geom.transform(4326, clone=True)
-
poly = [ g ]
if options['commit']:

0 comments on commit e9a6859

Please sign in to comment.