From 7734863c391f254e4006738d794b18ccc8cd2421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sun, 22 Dec 2019 20:57:32 +0100 Subject: [PATCH] obstacle altitude --- .../migrations/0077_obstacle_altitude.py | 25 +++++++++++++++++++ src/c3nav/mapdata/models/geometry/level.py | 4 +-- src/c3nav/mapdata/models/geometry/space.py | 6 +++++ .../mapdata/render/geometry/altitudearea.py | 1 + src/c3nav/mapdata/render/geometry/level.py | 4 ++- 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 src/c3nav/mapdata/migrations/0077_obstacle_altitude.py diff --git a/src/c3nav/mapdata/migrations/0077_obstacle_altitude.py b/src/c3nav/mapdata/migrations/0077_obstacle_altitude.py new file mode 100644 index 00000000..e466902d --- /dev/null +++ b/src/c3nav/mapdata/migrations/0077_obstacle_altitude.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.8 on 2019-12-22 19:55 + +from decimal import Decimal +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mapdata', '0076_obstacle_color'), + ] + + operations = [ + migrations.AddField( + model_name='lineobstacle', + name='altitude', + field=models.DecimalField(decimal_places=2, default=0, max_digits=6, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='altitude above ground'), + ), + migrations.AddField( + model_name='obstacle', + name='altitude', + field=models.DecimalField(decimal_places=2, default=0, max_digits=6, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='altitude above ground'), + ), + ] diff --git a/src/c3nav/mapdata/models/geometry/level.py b/src/c3nav/mapdata/models/geometry/level.py index ca02b1c6..218401aa 100644 --- a/src/c3nav/mapdata/models/geometry/level.py +++ b/src/c3nav/mapdata/models/geometry/level.py @@ -230,8 +230,8 @@ class AltitudeArea(LevelGeometryMixin, models.Model): space.geometry = space.geometry.difference(buildings_geom) space_accessible = space.geometry.difference( unary_union(tuple(c.geometry for c in space.columns.all() if c.access_restriction_id is None) + - tuple(o.geometry for o in space.obstacles.all()) + - tuple(o.buffered_geometry for o in space.lineobstacles.all()) + + tuple(o.geometry for o in space.obstacles.all() if o.altitude == 0) + + tuple(o.buffered_geometry for o in space.lineobstacles.all() if o.altitude == 0) + tuple(h.geometry for h in space.holes.all())) ) diff --git a/src/c3nav/mapdata/models/geometry/space.py b/src/c3nav/mapdata/models/geometry/space.py index ed4794e8..6ffc2bd1 100644 --- a/src/c3nav/mapdata/models/geometry/space.py +++ b/src/c3nav/mapdata/models/geometry/space.py @@ -170,6 +170,8 @@ class Obstacle(SpaceGeometryMixin, models.Model): geometry = GeometryField('polygon') height = models.DecimalField(_('height'), max_digits=6, decimal_places=2, default=0.8, validators=[MinValueValidator(Decimal('0'))]) + altitude = models.DecimalField(_('altitude above ground'), max_digits=6, decimal_places=2, default=0, + validators=[MinValueValidator(Decimal('0'))]) color = models.CharField(null=True, blank=True, max_length=32, verbose_name=_('color (optional)')) class Meta: @@ -186,6 +188,7 @@ class Obstacle(SpaceGeometryMixin, models.Model): def _serialize(self, geometry=True, **kwargs): result = super()._serialize(geometry=geometry, **kwargs) result['height'] = float(str(self.height)) + result['altitude'] = float(str(self.altitude)) result['color'] = self.color return result @@ -198,6 +201,8 @@ class LineObstacle(SpaceGeometryMixin, models.Model): width = models.DecimalField(_('width'), max_digits=4, decimal_places=2, default=0.15) height = models.DecimalField(_('height'), max_digits=6, decimal_places=2, default=0.8, validators=[MinValueValidator(Decimal('0'))]) + altitude = models.DecimalField(_('altitude above ground'), max_digits=6, decimal_places=2, default=0, + validators=[MinValueValidator(Decimal('0'))]) color = models.CharField(null=True, blank=True, max_length=32, verbose_name=_('color (optional)')) class Meta: @@ -215,6 +220,7 @@ class LineObstacle(SpaceGeometryMixin, models.Model): result = super()._serialize(geometry=geometry, **kwargs) result['width'] = float(str(self.width)) result['height'] = float(str(self.height)) + result['altitude'] = float(str(self.altitude)) result['color'] = self.color if geometry: result['buffered_geometry'] = format_geojson(mapping(self.buffered_geometry)) diff --git a/src/c3nav/mapdata/render/geometry/altitudearea.py b/src/c3nav/mapdata/render/geometry/altitudearea.py index eb4fbdb4..f7ffc65a 100644 --- a/src/c3nav/mapdata/render/geometry/altitudearea.py +++ b/src/c3nav/mapdata/render/geometry/altitudearea.py @@ -92,6 +92,7 @@ class AltitudeAreaGeometries: lower=altitudes, upper=altitudes + int(0.001 * 1000), crops=crops) + # todo: treat altitude properly for height, height_geometries in self.obstacles.items(): for color, color_geometries in height_geometries.items(): for geometry in color_geometries: diff --git a/src/c3nav/mapdata/render/geometry/level.py b/src/c3nav/mapdata/render/geometry/level.py index c66d9073..6a705e10 100644 --- a/src/c3nav/mapdata/render/geometry/level.py +++ b/src/c3nav/mapdata/render/geometry/level.py @@ -151,7 +151,9 @@ class LevelGeometries: for obstacle in space.obstacles.all(): if not obstacle.height: continue - obstacles.setdefault(int(obstacle.height*1000), {}).setdefault(obstacle.color, []).append( + obstacles.setdefault( + int((obstacle.height+obstacle.altitude)*1000), {} + ).setdefault(obstacle.color, []).append( obstacle.geometry.intersection(space.walkable_geom) )