From c3cb12d2bc5e5578cfc23c7082809f6365f24f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Tue, 10 Oct 2017 17:49:53 +0200 Subject: [PATCH] simple renderer for tiles --- src/c3nav/mapdata/models/geometry/level.py | 5 ++-- src/c3nav/mapdata/models/geometry/space.py | 4 +-- src/c3nav/mapdata/render/svg.py | 31 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/c3nav/mapdata/models/geometry/level.py b/src/c3nav/mapdata/models/geometry/level.py index ec6fcf9c..12df8292 100644 --- a/src/c3nav/mapdata/models/geometry/level.py +++ b/src/c3nav/mapdata/models/geometry/level.py @@ -54,7 +54,7 @@ class Building(LevelGeometryMixin, models.Model): default_related_name = 'buildings' -class Space(SpecificLocation, LevelGeometryMixin, models.Model): +class Space(LevelGeometryMixin, SpecificLocation, models.Model): """ An accessible space. Shouldn't overlap with spaces on the same level. """ @@ -74,7 +74,7 @@ class Space(SpecificLocation, LevelGeometryMixin, models.Model): return result -class Door(AccessRestrictionMixin, LevelGeometryMixin, models.Model): +class Door(LevelGeometryMixin, AccessRestrictionMixin, models.Model): """ A connection between two spaces """ @@ -97,6 +97,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model): verbose_name = _('Altitude Area') verbose_name_plural = _('Altitude Areas') default_related_name = 'altitudeareas' + ordering = ('altitude', ) @classmethod def recalculate(cls): diff --git a/src/c3nav/mapdata/models/geometry/space.py b/src/c3nav/mapdata/models/geometry/space.py index fa80d235..bc070084 100644 --- a/src/c3nav/mapdata/models/geometry/space.py +++ b/src/c3nav/mapdata/models/geometry/space.py @@ -41,7 +41,7 @@ class Column(SpaceGeometryMixin, models.Model): default_related_name = 'columns' -class Area(SpecificLocation, SpaceGeometryMixin, models.Model): +class Area(SpaceGeometryMixin, SpecificLocation, models.Model): """ An area in a space. """ @@ -125,7 +125,7 @@ class LineObstacle(SpaceGeometryMixin, models.Model): return result -class POI(SpecificLocation, SpaceGeometryMixin, models.Model): +class POI(SpaceGeometryMixin, SpecificLocation, models.Model): """ An point of interest """ diff --git a/src/c3nav/mapdata/render/svg.py b/src/c3nav/mapdata/render/svg.py index 4bd4ca04..5f1c4e8e 100644 --- a/src/c3nav/mapdata/render/svg.py +++ b/src/c3nav/mapdata/render/svg.py @@ -1,9 +1,38 @@ +from django.db.models import Prefetch, Q +from shapely.geometry import box +from shapely.ops import unary_union + +from c3nav.mapdata.models import AltitudeArea, Building, Door, Level, Space from c3nav.mapdata.utils.svg import SVGImage def render_svg(level, miny, minx, maxy, maxx, scale=1): svg = SVGImage(bounds=((miny, minx), (maxy, maxx)), scale=scale) - # todo: render + within_coords = (minx-1, miny-1, maxx+1, maxy+1) + bbox = box(*within_coords) + + levels = Level.objects.filter(Q(on_top_of=level.pk) | Q(base_altitude__lte=level.base_altitude)) + levels = levels.prefetch_related(Prefetch('altitudeareas', AltitudeArea.objects.within(*within_coords)), + Prefetch('buildings', Building.objects.within(*within_coords)), + Prefetch('spaces', Space.objects.within(*within_coords)), + Prefetch('doors', Door.objects.within(*within_coords))) + + for level in levels: + buildings_geom = bbox.intersection(unary_union([b.geometry for b in level.buildings.all()])) + svg.add_geometry(buildings_geom, fill_color='#aaaaaa') + + for altitudearea in level.altitudeareas.all(): + svg.add_geometry(bbox.intersection(altitudearea.geometry), fill_color='#ececec') + + for space in level.spaces.all(): + if space.outside: + space.geometry = space.geometry.difference(buildings_geom) + + spaces_geom = bbox.intersection(unary_union([s.geometry for s in level.spaces.all()])) + doors_geom = bbox.intersection(unary_union([d.geometry for d in level.doors.all()])) + doors_geom = doors_geom.difference(spaces_geom) + + svg.add_geometry(spaces_geom, fill_color='#ffffff') return svg.get_xml()