add min_width option
This commit is contained in:
parent
d75e8064d2
commit
0937b078f1
4 changed files with 24 additions and 4 deletions
|
@ -82,6 +82,8 @@ class Command(BaseCommand):
|
|||
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'))
|
||||
parser.add_argument('--min-width', default=None, type=float,
|
||||
help=_('ensure that all objects are at least this thick'))
|
||||
|
||||
def handle(self, *args, **options):
|
||||
(minx, miny), (maxx, maxy) = Source.max_bounds()
|
||||
|
@ -101,7 +103,8 @@ class Command(BaseCommand):
|
|||
|
||||
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'])
|
||||
scale=options['scale'], full_levels=options['full_levels'],
|
||||
min_width=options['min_width'])
|
||||
|
||||
filename = os.path.join(settings.RENDER_ROOT,
|
||||
'level_%s.%s' % (level.short_label, options['filetype']))
|
||||
|
|
|
@ -30,7 +30,7 @@ class RenderEngine(ABC):
|
|||
|
||||
# draw an svg image. supports pseudo-3D shadow-rendering
|
||||
def __init__(self, width: int, height: int, xoff=0, yoff=0, zoff=0,
|
||||
scale=1, buffer=0, background='#FFFFFF', center=True):
|
||||
scale=1, buffer=0, background='#FFFFFF', min_width=None, center=True):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.minx = xoff
|
||||
|
@ -40,6 +40,7 @@ class RenderEngine(ABC):
|
|||
self.orig_buffer = buffer
|
||||
self.buffer = int(math.ceil(buffer*self.scale))
|
||||
self.background = background
|
||||
self.min_width = min_width
|
||||
|
||||
self.maxx = self.minx + width / scale
|
||||
self.maxy = self.miny + height / scale
|
||||
|
|
|
@ -248,6 +248,8 @@ class OpenSCADEngine(Base3DEngine):
|
|||
if not obstacle.geom.intersects(self.bbox):
|
||||
continue
|
||||
obstacle = obstacle.geom.buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre)
|
||||
if self.min_width:
|
||||
obstacle = obstacle.union(self._satisfy_min_width(obstacle)).buffer(0)
|
||||
obstacle = obstacle.intersection(geometry_buffered)
|
||||
if not obstacle.is_empty:
|
||||
had_height_obstacles = True
|
||||
|
@ -278,6 +280,8 @@ class OpenSCADEngine(Base3DEngine):
|
|||
if not obstacle.geom.intersects(self.bbox):
|
||||
continue
|
||||
obstacle = obstacle.geom.buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre)
|
||||
if self.min_width:
|
||||
obstacle = obstacle.union(self._satisfy_min_width(obstacle)).buffer(0)
|
||||
obstacle = obstacle.intersection(geometry_buffered).intersection(self.bbox)
|
||||
if not obstacle.is_empty:
|
||||
had_obstacles = True
|
||||
|
@ -289,6 +293,13 @@ class OpenSCADEngine(Base3DEngine):
|
|||
if had_obstacles:
|
||||
main_building_block.append(obstacles_block)
|
||||
|
||||
if self.min_width and geoms.on_top_of_id is None:
|
||||
main_building_block.append(
|
||||
self._add_polygon('min width',
|
||||
self._satisfy_min_width(buildings).intersection(self.bbox).buffer(0),
|
||||
geoms.lower_bound, geoms.upper_bound)
|
||||
)
|
||||
|
||||
def _add_polygon(self, name, geometry, minz, maxz):
|
||||
geometry = geometry.buffer(0)
|
||||
polygons = []
|
||||
|
@ -340,5 +351,8 @@ class OpenSCADEngine(Base3DEngine):
|
|||
cmd = OpenScadBlock('translate([%f, %f, %f])' % (point1.x, point1.y, altitude1/1000), children=[cmd])
|
||||
return cmd
|
||||
|
||||
def _satisfy_min_width(self, geometry):
|
||||
return geometry.buffer(self.min_width/2, join_style=JOIN_STYLE.mitre)
|
||||
|
||||
def render(self, filename=None):
|
||||
return self.root.render().encode()
|
||||
|
|
|
@ -10,7 +10,8 @@ from c3nav.mapdata.render.utils import get_full_levels, get_min_altitude
|
|||
|
||||
|
||||
class MapRenderer:
|
||||
def __init__(self, level, minx, miny, maxx, maxy, scale=1, access_permissions=None, full_levels=False):
|
||||
def __init__(self, level, minx, miny, maxx, maxy, scale=1, access_permissions=None, full_levels=False,
|
||||
min_width=None):
|
||||
self.level = level.pk if isinstance(level, Level) else level
|
||||
self.minx = minx
|
||||
self.miny = miny
|
||||
|
@ -19,6 +20,7 @@ class MapRenderer:
|
|||
self.scale = scale
|
||||
self.access_permissions = set(access_permissions) if access_permissions else set()
|
||||
self.full_levels = full_levels
|
||||
self.min_width = min_width/self.scale
|
||||
|
||||
self.width = int(round((maxx - minx) * scale))
|
||||
self.height = int(round((maxy - miny) * scale))
|
||||
|
@ -36,7 +38,7 @@ class MapRenderer:
|
|||
level_render_data = LevelRenderData.get(self.level)
|
||||
|
||||
engine = engine_cls(self.width, self.height, self.minx, self.miny, float(level_render_data.base_altitude),
|
||||
scale=self.scale, buffer=1, background='#DCDCDC', center=center)
|
||||
scale=self.scale, buffer=1, background='#DCDCDC', center=center, min_width=self.min_width)
|
||||
|
||||
if hasattr(engine, 'custom_render'):
|
||||
engine.custom_render(level_render_data, access_permissions, self.full_levels)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue