diff --git a/src/c3nav/editor/static/editor/js/editor.js b/src/c3nav/editor/static/editor/js/editor.js index 04497cc7..6f61cd97 100644 --- a/src/c3nav/editor/static/editor/js/editor.js +++ b/src/c3nav/editor/static/editor/js/editor.js @@ -158,7 +158,8 @@ editor = { 'outside': '#EEFFEE', 'obstacle': '#999999', 'door': '#FF00FF', - 'elevatorlevel': '#9EF8FB' + 'hole': '#66CC66', + 'elevatorlevel': '#9EF8FB', }, _get_geometry_style: function (feature) { // style callback for GeoJSON loader diff --git a/src/c3nav/mapdata/migrations/0008_hole.py b/src/c3nav/mapdata/migrations/0008_hole.py new file mode 100644 index 00000000..b4c64962 --- /dev/null +++ b/src/c3nav/mapdata/migrations/0008_hole.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.2 on 2016-11-28 22:05 +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', '0007_auto_20161128_1903'), + ] + + operations = [ + migrations.CreateModel( + name='Hole', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.SlugField(unique=True, verbose_name='Name')), + ('geometry', c3nav.mapdata.fields.GeometryField()), + ('level', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='holes', to='mapdata.Level', verbose_name='level')), + ('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='holes', to='mapdata.Package', verbose_name='map package')), + ], + options={ + 'default_related_name': 'holes', + 'verbose_name': 'Hole', + 'verbose_name_plural': 'Holes', + }, + ), + ] diff --git a/src/c3nav/mapdata/models/geometry.py b/src/c3nav/mapdata/models/geometry.py index e1b3db68..5cf031a5 100644 --- a/src/c3nav/mapdata/models/geometry.py +++ b/src/c3nav/mapdata/models/geometry.py @@ -165,6 +165,18 @@ class Door(GeometryMapItem): default_related_name = 'doors' +class Hole(GeometryMapItem): + """ + A hole in the ground of a room, e.g. for stairs. + """ + geomtype = 'polygon' + + class Meta: + verbose_name = _('Hole') + verbose_name_plural = _('Holes') + default_related_name = 'holes' + + class ElevatorLevel(GeometryMapItem): """ An elevator Level diff --git a/src/c3nav/mapdata/models/level.py b/src/c3nav/mapdata/models/level.py index f37e181f..63fc7396 100644 --- a/src/c3nav/mapdata/models/level.py +++ b/src/c3nav/mapdata/models/level.py @@ -57,7 +57,7 @@ class LevelGeometries(): @cached_property def rooms(self): - return cascaded_union([room.geometry for room in self.level.rooms.all()]) + return cascaded_union([room.geometry for room in self.level.rooms.all()]).intersection(self.buildings) @cached_property def outsides(self): @@ -81,7 +81,15 @@ class LevelGeometries(): @cached_property def areas(self): - return cascaded_union([self.rooms, self.outsides, self.elevatorlevels]).intersection(self.buildings) + return cascaded_union([self.rooms, self.outsides, self.elevatorlevels]) + + @cached_property + def holes(self): + return cascaded_union([holes.geometry for holes in self.level.holes.all()]).intersection(self.areas) + + @cached_property + def buildings_with_holes(self): + return self.buildings.difference(self.holes) @cached_property def areas_and_doors(self): @@ -89,15 +97,11 @@ class LevelGeometries(): @cached_property def walls(self): - return self.buildings.difference(self.areas) - - @cached_property - def walls_without_doors(self): - return self.walls.difference(self.areas_and_doors) + return self.buildings.difference(self.areas_and_doors) @cached_property def walls_shadow(self): - return self.walls_without_doors.buffer(0.2, join_style=JOIN_STYLE.mitre).intersection(self.buildings) + return self.walls.buffer(0.2, join_style=JOIN_STYLE.mitre).intersection(self.buildings_with_holes) @cached_property def doors(self): diff --git a/src/c3nav/mapdata/packageio/const.py b/src/c3nav/mapdata/packageio/const.py index 05297dee..13a779cb 100644 --- a/src/c3nav/mapdata/packageio/const.py +++ b/src/c3nav/mapdata/packageio/const.py @@ -1,6 +1,6 @@ from c3nav.mapdata.models import Level, Package, Source from c3nav.mapdata.models.collections import Elevator -from c3nav.mapdata.models.geometry import Building, Door, ElevatorLevel, Obstacle, Outside, Room +from c3nav.mapdata.models.geometry import Building, Door, ElevatorLevel, Hole, Obstacle, Outside, Room -ordered_models = (Package, Level, Source, Building, Room, Outside, Door, Obstacle) +ordered_models = (Package, Level, Source, Building, Room, Outside, Door, Obstacle, Hole) ordered_models += (Elevator, ElevatorLevel) diff --git a/src/c3nav/mapdata/render/renderer.py b/src/c3nav/mapdata/render/renderer.py index 07f2172e..bfaf3bca 100644 --- a/src/c3nav/mapdata/render/renderer.py +++ b/src/c3nav/mapdata/render/renderer.py @@ -67,7 +67,7 @@ class LevelRenderer(): contents.append(self.polygon_svg(box(0, 0, width, height), fill_color='#000000')) - contents.append(self.polygon_svg(self.level.geometries.buildings, + contents.append(self.polygon_svg(self.level.geometries.buildings_with_holes, fill_color='#D5D5D5')) contents.append(self.polygon_svg(self.level.geometries.outsides, @@ -90,7 +90,7 @@ class LevelRenderer(): contents.append(self.polygon_svg(self.level.geometries.elevatorlevels, fill_color='#9EF8FB')) - contents.append(self.polygon_svg(self.level.geometries.walls_without_doors, + contents.append(self.polygon_svg(self.level.geometries.walls, fill_color='#949494', stroke_color='#757575', stroke_width=3))