From 6930e1bb7c2c4ddaaa12a66e051051f330b5a8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sat, 5 Aug 2017 11:56:29 +0200 Subject: [PATCH] new altitude modeling --- src/c3nav/editor/api.py | 2 + src/c3nav/editor/forms.py | 6 +- src/c3nav/editor/urls.py | 1 + src/c3nav/editor/views/edit.py | 3 +- .../mapdata/migrations/0030_altitudes.py | 63 +++++++++++++++++++ src/c3nav/mapdata/models/geometry/level.py | 13 ++++ src/c3nav/mapdata/models/geometry/space.py | 13 ++++ src/c3nav/mapdata/models/level.py | 10 +-- 8 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 src/c3nav/mapdata/migrations/0030_altitudes.py diff --git a/src/c3nav/editor/api.py b/src/c3nav/editor/api.py index b8ac6d50..41807f00 100644 --- a/src/c3nav/editor/api.py +++ b/src/c3nav/editor/api.py @@ -173,6 +173,7 @@ class EditorViewSet(ViewSet): space.obstacles.all(), space.lineobstacles.all(), space.columns.all(), + space.altitudemarkers.all(), space.pois.filter(POI.q_for_request(request)).prefetch_related('groups'), other_spaces_upper, graphedges, @@ -204,6 +205,7 @@ class EditorViewSet(ViewSet): 'graphnode': '#00BB00', 'graphnode__space_transfer': '#008800', 'graphedge': '#00CC00', + 'altitudemarker': '#ffff00', }) @list_route(methods=['get']) diff --git a/src/c3nav/editor/forms.py b/src/c3nav/editor/forms.py index 51d0000f..f609e3be 100644 --- a/src/c3nav/editor/forms.py +++ b/src/c3nav/editor/forms.py @@ -160,9 +160,9 @@ class EditorFormBase(ModelForm): def create_editor_form(editor_model): - possible_fields = ['slug', 'name', 'altitude', 'category', 'width', 'groups', 'color', 'priority', 'waytype', - 'access_restriction', 'space_transfer', 'can_search', 'can_describe', 'outside', 'geometry', - 'single', 'allow_levels', 'allow_spaces', 'allow_areas', 'allow_pois', + possible_fields = ['slug', 'name', 'ordering', 'category', 'width', 'groups', 'color', 'priority', 'altitude', + 'waytype', 'access_restriction', 'space_transfer', 'can_search', 'can_describe', 'outside', + 'geometry', 'single', 'allow_levels', 'allow_spaces', 'allow_areas', 'allow_pois', 'left', 'top', 'right', 'bottom'] field_names = [field.name for field in editor_model._meta.get_fields() if not field.one_to_many] existing_fields = [name for name in possible_fields if name in field_names] diff --git a/src/c3nav/editor/urls.py b/src/c3nav/editor/urls.py index f79a03dc..4700825c 100644 --- a/src/c3nav/editor/urls.py +++ b/src/c3nav/editor/urls.py @@ -63,3 +63,4 @@ urlpatterns.extend(add_editor_urls('Obstacle', 'Space')) urlpatterns.extend(add_editor_urls('LineObstacle', 'Space')) urlpatterns.extend(add_editor_urls('Column', 'Space')) urlpatterns.extend(add_editor_urls('POI', 'Space')) +urlpatterns.extend(add_editor_urls('AltitudeMarker', 'Space')) diff --git a/src/c3nav/editor/views/edit.py b/src/c3nav/editor/views/edit.py index 597ded76..98bae962 100644 --- a/src/c3nav/editor/views/edit.py +++ b/src/c3nav/editor/views/edit.py @@ -78,7 +78,8 @@ def space_detail(request, level, pk): 'can_edit': request.changeset.can_edit(request), 'child_models': [child_model(request, model_name, kwargs={'space': pk}, parent=space) - for model_name in ('Hole', 'Area', 'Stair', 'Obstacle', 'LineObstacle', 'Column', 'POI')], + for model_name in ('Hole', 'Area', 'Stair', 'Obstacle', 'LineObstacle', 'Column', 'POI', + 'AltitudeMarker')], 'geometry_url': '/api/editor/geometries/?space='+pk, }) diff --git a/src/c3nav/mapdata/migrations/0030_altitudes.py b/src/c3nav/mapdata/migrations/0030_altitudes.py new file mode 100644 index 00000000..125b3cff --- /dev/null +++ b/src/c3nav/mapdata/migrations/0030_altitudes.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.2 on 2017-08-05 09:48 +from __future__ import unicode_literals + +import c3nav.mapdata.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapdata', '0029_auto_20170714_1519'), + ] + + operations = [ + migrations.CreateModel( + name='AltitudeArea', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geometry', c3nav.mapdata.fields.GeometryField(default=None, geomtype='polygon')), + ('altitude', models.DecimalField(decimal_places=2, max_digits=6, verbose_name='altitude')), + ], + options={ + 'verbose_name': 'Altitude Area', + 'verbose_name_plural': 'Altitude Areas', + 'default_related_name': 'altitudeareas', + }, + ), + migrations.CreateModel( + name='AltitudeMarker', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('geometry', c3nav.mapdata.fields.GeometryField(default=None, geomtype='point')), + ('altitude', models.DecimalField(decimal_places=2, max_digits=6, verbose_name='altitude')), + ('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='altitudemarkers', to='mapdata.Space', verbose_name='space')), + ], + options={ + 'verbose_name': 'Altitude Marker', + 'verbose_name_plural': 'Altitude Markers', + 'default_related_name': 'altitudemarkers', + }, + ), + migrations.AlterModelOptions( + name='level', + options={'ordering': ['ordering'], 'verbose_name': 'Level', 'verbose_name_plural': 'Levels'}, + ), + migrations.RenameField( + model_name='level', + old_name='altitude', + new_name='ordering', + ), + migrations.AlterField( + model_name='level', + name='ordering', + field=models.DecimalField(decimal_places=2, max_digits=6, unique=True, verbose_name='ordering'), + ), + migrations.AddField( + model_name='altitudearea', + name='level', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='altitudeareas', to='mapdata.Level', verbose_name='level'), + ), + ] diff --git a/src/c3nav/mapdata/models/geometry/level.py b/src/c3nav/mapdata/models/geometry/level.py index 104c1566..fb8e970d 100644 --- a/src/c3nav/mapdata/models/geometry/level.py +++ b/src/c3nav/mapdata/models/geometry/level.py @@ -66,3 +66,16 @@ class Door(AccessRestrictionMixin, LevelGeometryMixin, models.Model): verbose_name = _('Door') verbose_name_plural = _('Doors') default_related_name = 'doors' + + +class AltitudeArea(LevelGeometryMixin, models.Model): + """ + An altitude area + """ + geometry = GeometryField('polygon') + altitude = models.DecimalField(_('altitude'), null=False, max_digits=6, decimal_places=2) + + class Meta: + verbose_name = _('Altitude Area') + verbose_name_plural = _('Altitude Areas') + default_related_name = 'altitudeareas' diff --git a/src/c3nav/mapdata/models/geometry/space.py b/src/c3nav/mapdata/models/geometry/space.py index 3dbd43ba..2fe640a4 100644 --- a/src/c3nav/mapdata/models/geometry/space.py +++ b/src/c3nav/mapdata/models/geometry/space.py @@ -162,3 +162,16 @@ class Hole(SpaceGeometryMixin, models.Model): verbose_name = _('Hole') verbose_name_plural = _('Holes') default_related_name = 'holes' + + +class AltitudeMarker(SpaceGeometryMixin, models.Model): + """ + An altitude marker + """ + geometry = GeometryField('point') + altitude = models.DecimalField(_('altitude'), null=False, max_digits=6, decimal_places=2) + + class Meta: + verbose_name = _('Altitude Marker') + verbose_name_plural = _('Altitude Markers') + default_related_name = 'altitudemarkers' diff --git a/src/c3nav/mapdata/models/level.py b/src/c3nav/mapdata/models/level.py index 7d8e4cb5..e2502a94 100644 --- a/src/c3nav/mapdata/models/level.py +++ b/src/c3nav/mapdata/models/level.py @@ -16,7 +16,7 @@ class Level(SpecificLocation, models.Model): """ A map level """ - altitude = models.DecimalField(_('level altitude'), null=False, unique=True, max_digits=6, decimal_places=2) + ordering = models.DecimalField(_('ordering'), null=False, unique=True, max_digits=6, decimal_places=2) on_top_of = models.ForeignKey('mapdata.Level', null=True, on_delete=models.CASCADE, related_name='levels_on_top', verbose_name=_('on top of')) @@ -24,7 +24,7 @@ class Level(SpecificLocation, models.Model): verbose_name = _('Level') verbose_name_plural = _('Levels') default_related_name = 'levels' - ordering = ['altitude'] + ordering = ['ordering'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -34,14 +34,14 @@ class Level(SpecificLocation, models.Model): raise TypeError if level_model is None: level_model = Level - return level_model.objects.filter(altitude__lt=self.altitude, on_top_of__isnull=True).order_by('-altitude') + return level_model.objects.filter(ordering__lt=self.ordering, on_top_of__isnull=True).order_by('-ordering') def higher(self, level_model=None): if self.on_top_of_id is not None: raise TypeError if level_model is None: level_model = Level - return level_model.objects.filter(altitude__gt=self.altitude, on_top_of__isnull=True).order_by('altitude') + return level_model.objects.filter(ordering__gt=self.ordering, on_top_of__isnull=True).order_by('ordering') @property def sublevels(self): @@ -63,7 +63,7 @@ class Level(SpecificLocation, models.Model): def _serialize(self, level=True, **kwargs): result = super()._serialize(**kwargs) - result['altitude'] = float(str(self.altitude)) + result['ordering'] = float(str(self.ordering)) return result def _render_space_ground(self, svg, space):