connect levels in full_levels renderung
This commit is contained in:
parent
9ed381567d
commit
ab4402907d
2 changed files with 40 additions and 3 deletions
|
@ -15,7 +15,7 @@ from shapely.ops import unary_union
|
||||||
from c3nav.mapdata.cache import MapHistory
|
from c3nav.mapdata.cache import MapHistory
|
||||||
from c3nav.mapdata.models import Level, MapUpdate
|
from c3nav.mapdata.models import Level, MapUpdate
|
||||||
from c3nav.mapdata.utils.geometry import assert_multipolygon, get_rings
|
from c3nav.mapdata.utils.geometry import assert_multipolygon, get_rings
|
||||||
from c3nav.mapdata.utils.mesh import triangulate_rings
|
from c3nav.mapdata.utils.mesh import triangulate_rings, triangulate_polygon
|
||||||
from c3nav.mapdata.utils.mpl import shapely_to_mpl
|
from c3nav.mapdata.utils.mpl import shapely_to_mpl
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,6 +133,25 @@ class LevelRenderData:
|
||||||
|
|
||||||
single_level_geoms = {level.pk: LevelGeometries.build_for_level(level) for level in levels}
|
single_level_geoms = {level.pk: LevelGeometries.build_for_level(level) for level in levels}
|
||||||
|
|
||||||
|
|
||||||
|
interpolators = {}
|
||||||
|
last_interpolator = None
|
||||||
|
for level in reversed(levels):
|
||||||
|
if level.on_top_of_id is not None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if last_interpolator is not None:
|
||||||
|
interpolators[level.pk] = last_interpolator
|
||||||
|
|
||||||
|
coords = deque()
|
||||||
|
values = deque()
|
||||||
|
for area in single_level_geoms[level.pk].altitudeareas:
|
||||||
|
new_coords = np.vstack(tuple(np.array(ring.coords) for ring in get_rings(area.geometry)))
|
||||||
|
coords.append(new_coords)
|
||||||
|
values.append(np.full((new_coords.shape[0], ), fill_value=float(area.altitude)))
|
||||||
|
|
||||||
|
last_interpolator = NearestNDInterpolator(np.hstack(coords), np.hstack(values))
|
||||||
|
|
||||||
for i, level in enumerate(levels):
|
for i, level in enumerate(levels):
|
||||||
if level.on_top_of_id is not None:
|
if level.on_top_of_id is not None:
|
||||||
continue
|
continue
|
||||||
|
@ -184,6 +203,7 @@ class LevelRenderData:
|
||||||
new_geoms = LevelGeometries()
|
new_geoms = LevelGeometries()
|
||||||
new_geoms.doors = crop_to.intersection(old_geoms.doors)
|
new_geoms.doors = crop_to.intersection(old_geoms.doors)
|
||||||
new_geoms.walls = crop_to.intersection(old_geoms.walls)
|
new_geoms.walls = crop_to.intersection(old_geoms.walls)
|
||||||
|
new_geoms.walls_extended = crop_to.intersection(old_geoms.walls_extended)
|
||||||
|
|
||||||
for altitudearea in old_geoms.altitudeareas:
|
for altitudearea in old_geoms.altitudeareas:
|
||||||
new_geometry = crop_to.intersection(altitudearea.geometry)
|
new_geometry = crop_to.intersection(altitudearea.geometry)
|
||||||
|
@ -248,7 +268,7 @@ class LevelRenderData:
|
||||||
new_geoms.min_altitude = float(min(area.altitude for area in new_geoms.altitudeareas)
|
new_geoms.min_altitude = float(min(area.altitude for area in new_geoms.altitudeareas)
|
||||||
if new_geoms.altitudeareas else new_geoms.base_altitude)
|
if new_geoms.altitudeareas else new_geoms.base_altitude)
|
||||||
|
|
||||||
new_geoms.build_mesh()
|
new_geoms.build_mesh(interpolators.get(level.pk) if sublevel.pk == level.pk else None)
|
||||||
|
|
||||||
render_data.levels.append(new_geoms)
|
render_data.levels.append(new_geoms)
|
||||||
|
|
||||||
|
@ -296,6 +316,7 @@ class LevelGeometries:
|
||||||
self.altitudeareas = []
|
self.altitudeareas = []
|
||||||
self.heightareas = []
|
self.heightareas = []
|
||||||
self.walls = None
|
self.walls = None
|
||||||
|
self.walls_extended = None
|
||||||
self.doors = None
|
self.doors = None
|
||||||
self.holes = None
|
self.holes = None
|
||||||
self.access_restriction_affected = None
|
self.access_restriction_affected = None
|
||||||
|
@ -303,6 +324,9 @@ class LevelGeometries:
|
||||||
self.restricted_spaces_outdoors = None
|
self.restricted_spaces_outdoors = None
|
||||||
self.affected_area = None
|
self.affected_area = None
|
||||||
|
|
||||||
|
self.vertices = None
|
||||||
|
self.faces = None
|
||||||
|
|
||||||
self.level_base = None
|
self.level_base = None
|
||||||
self.optional_base = None
|
self.optional_base = None
|
||||||
|
|
||||||
|
@ -397,6 +421,7 @@ class LevelGeometries:
|
||||||
for access_restriction, spaces in restricted_spaces_outdoors.items()}
|
for access_restriction, spaces in restricted_spaces_outdoors.items()}
|
||||||
|
|
||||||
geoms.walls = buildings_geom.difference(spaces_geom).difference(doors_geom)
|
geoms.walls = buildings_geom.difference(spaces_geom).difference(doors_geom)
|
||||||
|
geoms.walls_extended = buildings_geom.difference(spaces_geom)
|
||||||
|
|
||||||
# general level infos
|
# general level infos
|
||||||
geoms.pk = level.pk
|
geoms.pk = level.pk
|
||||||
|
@ -419,6 +444,7 @@ class LevelGeometries:
|
||||||
self.heightareas = tuple((HybridGeometry.create(area, face_centers), height)
|
self.heightareas = tuple((HybridGeometry.create(area, face_centers), height)
|
||||||
for area, height in self.heightareas)
|
for area, height in self.heightareas)
|
||||||
self.walls = HybridGeometry.create(self.walls, face_centers)
|
self.walls = HybridGeometry.create(self.walls, face_centers)
|
||||||
|
self.walls_extended = HybridGeometry.create(self.walls_extended, face_centers)
|
||||||
self.doors = HybridGeometry.create(self.doors, face_centers)
|
self.doors = HybridGeometry.create(self.doors, face_centers)
|
||||||
self.restricted_spaces_indoors = {key: HybridGeometry.create(geom, face_centers)
|
self.restricted_spaces_indoors = {key: HybridGeometry.create(geom, face_centers)
|
||||||
for key, geom in self.restricted_spaces_indoors.items()}
|
for key, geom in self.restricted_spaces_indoors.items()}
|
||||||
|
@ -494,7 +520,7 @@ class LevelGeometries:
|
||||||
|
|
||||||
return (np.vstack(new_faces), )
|
return (np.vstack(new_faces), )
|
||||||
|
|
||||||
def build_mesh(self):
|
def build_mesh(self, interpolator=None):
|
||||||
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
|
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
|
||||||
self.vertices, self.faces = triangulate_rings(rings)
|
self.vertices, self.faces = triangulate_rings(rings)
|
||||||
self.create_hybrid_geometries(face_centers=self.vertices[self.faces].sum(axis=1) / 3)
|
self.create_hybrid_geometries(face_centers=self.vertices[self.faces].sum(axis=1) / 3)
|
||||||
|
@ -509,6 +535,13 @@ class LevelGeometries:
|
||||||
# create polyhedrons
|
# create polyhedrons
|
||||||
self.walls.build_polyhedron(self._create_polyhedron, bottom=vertex_altitudes-0.7, top=vertex_wall_heights)
|
self.walls.build_polyhedron(self._create_polyhedron, bottom=vertex_altitudes-0.7, top=vertex_wall_heights)
|
||||||
|
|
||||||
|
if interpolator is not None:
|
||||||
|
self.walls_extended.build_polyhedron(self._create_polyhedron,
|
||||||
|
bottom=vertex_wall_heights,
|
||||||
|
top=interpolator(*np.transpose(self.vertices))-0.3)
|
||||||
|
else:
|
||||||
|
self.walls_extended = None
|
||||||
|
|
||||||
for key, geometry in self.restricted_spaces_indoors.items():
|
for key, geometry in self.restricted_spaces_indoors.items():
|
||||||
geometry.crop_ids = frozenset(('in:%s' % key, ))
|
geometry.crop_ids = frozenset(('in:%s' % key, ))
|
||||||
for key, geometry in self.restricted_spaces_outdoors.items():
|
for key, geometry in self.restricted_spaces_outdoors.items():
|
||||||
|
@ -533,6 +566,7 @@ class LevelGeometries:
|
||||||
self.optional_base.build_polyhedron(self._create_polyhedron, bottom=0, top=1)
|
self.optional_base.build_polyhedron(self._create_polyhedron, bottom=0, top=1)
|
||||||
|
|
||||||
# unset heightareas, they are no loinger needed
|
# unset heightareas, they are no loinger needed
|
||||||
|
self.vertex_altitudes = None
|
||||||
self.heightareas = None
|
self.heightareas = None
|
||||||
self.vertices = None
|
self.vertices = None
|
||||||
self.faces = None
|
self.faces = None
|
||||||
|
|
|
@ -124,6 +124,9 @@ class MapRenderer:
|
||||||
if walls is not None:
|
if walls is not None:
|
||||||
engine.add_geometry(walls, height=geoms.default_height, fill=FillAttribs('#aaaaaa'))
|
engine.add_geometry(walls, height=geoms.default_height, fill=FillAttribs('#aaaaaa'))
|
||||||
|
|
||||||
|
if geoms.walls_extended and self.full_levels and engine.is_3d:
|
||||||
|
engine.add_geometry(geoms.walls_extended, height=geoms.default_height, fill=FillAttribs('#aaaaaa'))
|
||||||
|
|
||||||
if not geoms.doors.is_empty:
|
if not geoms.doors.is_empty:
|
||||||
engine.add_geometry(geoms.doors.difference(add_walls), fill=FillAttribs('#ffffff'),
|
engine.add_geometry(geoms.doors.difference(add_walls), fill=FillAttribs('#ffffff'),
|
||||||
stroke=StrokeAttribs('#ffffff', 0.05, min_px=0.2))
|
stroke=StrokeAttribs('#ffffff', 0.05, min_px=0.2))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue