From 016def817819cbd50785cd51b74d0e4f19f0d663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Thu, 6 Dec 2018 18:30:28 +0100 Subject: [PATCH] support setting render bounds in rendermap and openscad renderer --- .../mapdata/management/commands/rendermap.py | 24 ++++++++++++++++++- src/c3nav/mapdata/render/engines/openscad.py | 21 ++++++++++------ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/c3nav/mapdata/management/commands/rendermap.py b/src/c3nav/mapdata/management/commands/rendermap.py index 6cbb7e9c..732c2592 100644 --- a/src/c3nav/mapdata/management/commands/rendermap.py +++ b/src/c3nav/mapdata/management/commands/rendermap.py @@ -2,7 +2,7 @@ import argparse import os from django.conf import settings -from django.core.management.base import BaseCommand +from django.core.management.base import BaseCommand, CommandError from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy @@ -74,9 +74,31 @@ class Command(BaseCommand): help=_('do not center the output')) parser.add_argument('--scale', default=1, type=self.scale_value, help=_('scale (from 1 to 32), only relevant for image renderers')) + parser.add_argument('--minx', default=None, type=float, + help=_('minimum x coordinate, everthing left of it will be cropped')) + parser.add_argument('--miny', default=None, type=float, + help=_('minimum y coordinate, everthing below it will be cropped')) + parser.add_argument('--maxx', default=None, type=float, + help=_('maximum x coordinate, everthing right of it will be cropped')) + parser.add_argument('--maxy', default=None, type=float, + help=_('maximum y coordinate, everthing above it will be cropped')) def handle(self, *args, **options): (minx, miny), (maxx, maxy) = Source.max_bounds() + if options['minx'] is not None: + minx = options['minx'] + if options['miny'] is not None: + miny = options['miny'] + if options['maxx'] is not None: + maxx = options['maxx'] + if options['maxy'] is not None: + maxy = options['maxy'] + + if minx >= maxx: + raise CommandError(_('minx has to be lower than maxx')) + if miny >= maxy: + raise CommandError(_('miny has to be lower than maxy')) + for level in options['levels']: renderer = MapRenderer(level.pk, minx, miny, maxx, maxy, access_permissions=options['permissions'], scale=options['scale'], full_levels=options['full_levels']) diff --git a/src/c3nav/mapdata/render/engines/openscad.py b/src/c3nav/mapdata/render/engines/openscad.py index 74122957..928641aa 100644 --- a/src/c3nav/mapdata/render/engines/openscad.py +++ b/src/c3nav/mapdata/render/engines/openscad.py @@ -121,10 +121,13 @@ class OpenSCADEngine(Base3DEngine): main_building_block_diff = OpenScadBlock('difference()') main_building_block.append(main_building_block_diff) main_building_block_diff.append( - self._add_polygon(None, buildings, geoms.lower_bound, geoms.upper_bound) + self._add_polygon(None, buildings.intersection(self.bbox), geoms.lower_bound, geoms.upper_bound) ) for altitudearea in sorted(geoms.altitudeareas, key=attrgetter('altitude')): + if not altitudearea.geometry.intersects(self.bbox): + continue + if altitudearea.altitude2 is not None: name = 'Altitudearea %s-%s' % (altitudearea.altitude/1000, altitudearea.altitude2/1000) else: @@ -142,7 +145,7 @@ class OpenSCADEngine(Base3DEngine): areas = areas.union(geometry) buildings = buildings.difference(geometry).buffer(0) inside_geometry = inside_geometry.intersection(areas).buffer(0) - outside_geometry = outside_geometry.intersection(areas).buffer(0) + outside_geometry = outside_geometry.intersection(areas).buffer(0).intersection(self.bbox) geometry_buffered = geometry_buffered.intersection(areas).buffer(0) slopes = True @@ -165,8 +168,8 @@ class OpenSCADEngine(Base3DEngine): ) # actual thingy - if max_slope_altitude > current_upper_bound: - polygon = self._add_polygon(None, inside_geometry, + if max_slope_altitude > current_upper_bound and inside_geometry.intersects(self.bbox): + polygon = self._add_polygon(None, inside_geometry.intersection(self.bbox), current_upper_bound-10, max_slope_altitude+10) slope = self._add_slope(bounds, altitudearea.altitude, altitudearea.altitude2, altitudearea.point1, altitudearea.point2, bottom=False) @@ -182,7 +185,7 @@ class OpenSCADEngine(Base3DEngine): ) else: main_building_block.append( - self._add_polygon(name+' inside', inside_geometry, + self._add_polygon(name+' inside', inside_geometry.intersection(self.bbox), min(altitudearea.altitude-700, current_upper_bound-10), altitudearea.altitude) ) @@ -237,13 +240,15 @@ class OpenSCADEngine(Base3DEngine): height_diff.append(height_union) for obstacle in obstacles: + if not obstacle.geom.intersects(self.bbox): + continue obstacle = obstacle.geom.buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre) obstacle = obstacle.intersection(geometry_buffered) if not obstacle.is_empty: had_height_obstacles = True had_obstacles = True height_union.append( - self._add_polygon(None, obstacle, + self._add_polygon(None, obstacle.intersection(self.bbox), min_slope_altitude-20, max_slope_altitude+height+10) ) @@ -265,8 +270,10 @@ class OpenSCADEngine(Base3DEngine): had_obstacles = False for height, obstacles in altitudearea.obstacles.items(): for obstacle in obstacles: + if not obstacle.geom.intersects(self.bbox): + continue obstacle = obstacle.geom.buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre) - obstacle = obstacle.intersection(geometry_buffered) + obstacle = obstacle.intersection(geometry_buffered).intersection(self.bbox) if not obstacle.is_empty: had_obstacles = True obstacles_block.append(