From a6913d84aa0d02a152fffda2dd76edaf348525c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Thu, 4 May 2017 15:44:32 +0200 Subject: [PATCH] assign area to many GeometryMapItems --- .../mapdata/migrations/0046_assign_area.py | 66 +++++++++++++++++++ src/c3nav/mapdata/models/geometry.py | 34 ++++++++-- 2 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 src/c3nav/mapdata/migrations/0046_assign_area.py diff --git a/src/c3nav/mapdata/migrations/0046_assign_area.py b/src/c3nav/mapdata/migrations/0046_assign_area.py new file mode 100644 index 00000000..d078286d --- /dev/null +++ b/src/c3nav/mapdata/migrations/0046_assign_area.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.4 on 2017-05-04 13:31 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +def assign_area(apps, schema_editor): + Level = apps.get_model('mapdata', 'Level') + for level in Level.objects.all(): + level_areas = list(level.areas.all()) + for c in ('escalators', 'obstacles', 'lineobstacles', 'stairs', 'stuffedareas'): + getattr(level, c).filter(name__endswith='_').delete() + for obj in getattr(level, c).all(): + geom = obj.buffered_geometry if hasattr(obj, 'buffered_geometry') else obj.geometry + areas = [a for a in level_areas if a.geometry.intersects(geom)] + if not areas: + obj.delete() + continue + for area in areas: + obj.area = area + obj.save() + obj.pk = None + obj.name += '_' + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapdata', '0045_merge_areas'), + ] + + operations = [ + migrations.AddField( + model_name='escalator', + name='area', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='escalators', to='mapdata.Area', verbose_name='area'), + preserve_default=False, + ), + migrations.AddField( + model_name='lineobstacle', + name='area', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='lineobstacles', to='mapdata.Area', verbose_name='area'), + preserve_default=False, + ), + migrations.AddField( + model_name='obstacle', + name='area', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='obstacles', to='mapdata.Area', verbose_name='area'), + preserve_default=False, + ), + migrations.AddField( + model_name='stair', + name='area', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='stairs', to='mapdata.Area', verbose_name='area'), + preserve_default=False, + ), + migrations.AddField( + model_name='stuffedarea', + name='area', + field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, related_name='stuffedareas', to='mapdata.Area', verbose_name='area'), + preserve_default=False, + ), + migrations.RunPython(assign_area), + ] diff --git a/src/c3nav/mapdata/models/geometry.py b/src/c3nav/mapdata/models/geometry.py index 9b3fa07f..f30440e4 100644 --- a/src/c3nav/mapdata/models/geometry.py +++ b/src/c3nav/mapdata/models/geometry.py @@ -68,6 +68,23 @@ class GeometryMapItemWithLevel(GeometryMapItem): return result +class GeometryMapItemWithArea(GeometryMapItem): + """ + A map feature + """ + level = models.ForeignKey('mapdata.Level', on_delete=models.CASCADE, verbose_name=_('level')) + area = models.ForeignKey('mapdata.Area', on_delete=models.CASCADE, verbose_name=_('area')) + + class Meta: + abstract = True + + def get_geojson_properties(self): + result = super().get_geojson_properties() + result['level'] = self.level.name + result['area'] = self.area.name + return result + + class Building(GeometryMapItemWithLevel): """ The outline of a building on a specific level @@ -113,7 +130,7 @@ class Area(GeometryMapItemWithLevel): return result -class StuffedArea(GeometryMapItemWithLevel): +class StuffedArea(GeometryMapItemWithArea): """ A slow area with many tables or similar. Avoid it from routing by slowing it a bit down """ @@ -125,7 +142,7 @@ class StuffedArea(GeometryMapItemWithLevel): default_related_name = 'stuffedareas' -class Escalator(GeometryMapItemWithLevel): +class Escalator(GeometryMapItemWithArea): """ An escalator area """ @@ -148,7 +165,7 @@ class Escalator(GeometryMapItemWithLevel): return result -class Stair(GeometryMapItemWithLevel): +class Stair(GeometryMapItemWithArea): """ A stair """ @@ -182,7 +199,7 @@ class Stair(GeometryMapItemWithLevel): )) -class Obstacle(GeometryMapItemWithLevel): +class Obstacle(GeometryMapItemWithArea): """ An obstacle """ @@ -203,7 +220,7 @@ class Obstacle(GeometryMapItemWithLevel): return result -class LineObstacle(GeometryMapItemWithLevel): +class LineObstacle(GeometryMapItemWithArea): """ An obstacle that is a line with a specific width """ @@ -216,11 +233,14 @@ class LineObstacle(GeometryMapItemWithLevel): verbose_name_plural = _('Line Obstacles') default_related_name = 'lineobstacles' + @property + def buffered_geometry(self): + return self.geometry.buffer(self.width / 2, join_style=JOIN_STYLE.mitre, cap_style=CAP_STYLE.flat) + def to_geojson(self): result = super().to_geojson() original_geometry = result['geometry'] - draw = self.geometry.buffer(self.width/2, join_style=JOIN_STYLE.mitre, cap_style=CAP_STYLE.flat) - result['geometry'] = format_geojson(mapping(draw)) + result['geometry'] = format_geojson(mapping(self.buffered_geometry)) result['original_geometry'] = original_geometry return result