def connect_levelconnectors(self): for levelconnector in LevelConnector.objects.all(): center = levelconnector.geometry.centroid points = self._built_levelconnector_points.get( levelconnector.name, []) rooms = set(point.room for point in points if point.room is not None) connected_levels = set(room.level for room in rooms) should_levels = tuple(level.name for level in levelconnector.levels.all()) missing_levels = set(should_levels) - set( level.level.name for level in connected_levels) if missing_levels: print( 'levelconnector %s on levels %s at (%.2f, %.2f) is not connected to levels %s!' % (levelconnector.name, ', '.join(should_levels), center.x, center.y, ', '.join(missing_levels))) continue center_point = GraphPoint(center.x, center.y, None) self.points.append(center_point) self._built_level_transfer_points.append(center_point) for level in connected_levels: level._built_room_transfer_points.append(center_point) level._built_points.append(center_point) for room in rooms: room._built_points.append(center_point) for point in points: center_point.connect_to(point) point.connect_to(center_point)
def create_doors(self): doors = self.level.geometries.doors doors = assert_multipolygon(doors) for door in doors: polygon = door.buffer(0.01, join_style=JOIN_STYLE.mitre) center = door.centroid num_points = 0 connected_rooms = set() points = [] for room in self.rooms: if not polygon.intersects(room._built_geometry): continue for subpolygon in assert_multipolygon(polygon.intersection(room._built_geometry)): connected_rooms.add(room) nearest_point = get_nearest_point(room.clear_geometry, subpolygon.centroid) point, = room.add_point(nearest_point.coords[0]) points.append(point) if len(points) < 2: print('door with <2 points (%d) detected at (%.2f, %.2f)' % (num_points, center.x, center.y)) continue center_point = GraphPoint(center.x, center.y, None) self._built_room_transfer_points.append(center_point) for room in connected_rooms: room._built_points.append(center_point) for point in points: center_point.connect_to(point) point.connect_to(center_point)
def create_oneways(self): oneways = self.level.geometries.oneways oneways = assert_multilinestring(oneways) segments = () for oneway in oneways: coords = tuple(oneway.coords) segments += tuple((Path(part), coord_angle(*part)) for part in zip(coords[:-1], coords[1:])) for oneway, oneway_angle in segments: line_string = LineString(tuple(oneway.vertices)) polygon = line_string.buffer(0.10, join_style=JOIN_STYLE.mitre, cap_style=CAP_STYLE.flat) center = polygon.centroid num_points = 0 connected_rooms = set() points = [] for room in self.rooms: if not polygon.intersects(room._built_geometry): continue for subpolygon in assert_multipolygon(polygon.intersection(room._built_geometry)): connected_rooms.add(room) nearest_point = get_nearest_point(room.clear_geometry, subpolygon.centroid) point, = room.add_point(nearest_point.coords[0]) points.append(point) if len(points) < 2: print('oneway with <2 points (%d) detected at (%.2f, %.2f)' % (num_points, center.x, center.y)) continue center_point = GraphPoint(center.x, center.y, None) self._built_room_transfer_points.append(center_point) for room in connected_rooms: room._built_points.append(center_point) for point in points: angle = coord_angle(point.xy, center_point.xy) angle_diff = ((oneway_angle - angle + 180) % 360) - 180 direction_up = (angle_diff > 0) if direction_up: point.connect_to(center_point) else: center_point.connect_to(point)
def connect_elevators(self): for elevator in Elevator.objects.all(): elevatorlevels = tuple(elevator.elevatorlevels.all()) for level1, level2 in combinations(elevatorlevels, 2): point1 = self._built_elevatorlevel_points[level1.name] point2 = self._built_elevatorlevel_points[level2.name] center = GraphPoint((point1.x + point2.x) / 2, (point1.y + point2.y) / 2, None) self.points.append(center) self._built_level_transfer_points.append(center) for room in (point1.room, point2.room): room._built_points.append(center) room.level._built_room_transfer_points.append(center) room.level._built_points.append(center) direction_up = level2.altitude > level1.altitude dist = abs(level2.altitude - level1.altitude) point1.connect_to( center, ctype=('elevator_up' if direction_up else 'elevator_down'), distance=dist) center.connect_to( point2, ctype=('elevator_up' if direction_up else 'elevator_down'), distance=dist) point2.connect_to( center, ctype=('elevator_down' if direction_up else 'elevator_up'), distance=dist) center.connect_to( point1, ctype=('elevator_down' if direction_up else 'elevator_up'), distance=dist)