diff --git a/src/c3nav/routing/graph.py b/src/c3nav/routing/graph.py index 9112a340..ac3e9b09 100644 --- a/src/c3nav/routing/graph.py +++ b/src/c3nav/routing/graph.py @@ -10,7 +10,6 @@ from c3nav.routing.connection import GraphConnection from c3nav.routing.level import GraphLevel from c3nav.routing.point import GraphPoint from c3nav.routing.room import GraphRoom -from c3nav.routing.router import Router class Graph: @@ -21,23 +20,38 @@ class Graph: for level in Level.objects.all(): self.levels[level.name] = GraphLevel(self, level) - self.points = [] + self.rooms = () + self.points = () self.connections = [] - self.rooms = [] self.level_transfer_points = [] self.levelconnector_points = {} + # Building the Graph def build(self): for level in self.levels.values(): level.build() + # collect rooms and points self.rooms = sum((level.rooms for level in self.levels.values()), []) self.points = sum((level.points for level in self.levels.values()), []) + # create connections between levels print() self.connect_levelconnectors() + # convert everything to tuples + self.rooms = tuple(self.rooms) + self.points = tuple(self.points) + self.connections = tuple(self.connections) + + # give numbers to rooms and points + for i, room in enumerate(self.rooms): + room.i = i + + for i, point in enumerate(self.points): + point.i = i + print() print('Total:') print('%d points' % len(self.points)) @@ -50,13 +64,41 @@ class Graph: for name, level in self.levels.items(): print(('Level %s:' % name), *(sorted((len(room.points) for room in level.rooms), reverse=True))) + def add_connection(self, from_point, to_point, distance=None): + self.connections.append(GraphConnection(self, from_point, to_point, distance)) + + def add_levelconnector_point(self, levelconnector, point): + self.levelconnector_points.setdefault(levelconnector.name, []).append(point) + + def connect_levelconnectors(self): + for levelconnector in LevelConnector.objects.all(): + center = levelconnector.geometry.centroid + points = self.levelconnector_points.get(levelconnector.name, []) + rooms = tuple(set(sum((point.rooms for point in points), []))) + + if len(rooms) < 2: + print('levelconnector %s on levels %s at (%.2f, %.2f) has <2 rooms (%d%s)!' % + (levelconnector.name, ', '.join(level.name for level in levelconnector.levels.all()), + center.x, center.y, len(rooms), (' on level '+rooms[0].level.level.name) if rooms else '')) + continue + + center_point = GraphPoint(center.x, center.y, rooms=rooms) + self.points.append(center_point) + + levels = tuple(set(room.level for room in rooms)) + for level in levels: + level.room_transfer_points.append(center_point) + level.points.append(center_point) + + for room in rooms: + room.points.append(center_point) + + for point in points: + center_point.connect_to(point) + point.connect_to(center_point) + + # Loading/Saving the Graph def serialize(self): - for i, room in enumerate(self.rooms): - room.i = i - - for i, point in enumerate(self.points): - point.i = i - rooms = tuple((room.level.level.name, room.mpl_clear) for room in self.rooms) points = tuple((point.x, point.y, tuple(room.i for room in point.rooms)) for point in self.points) connections = tuple((conn.from_point.i, conn.to_point.i, conn.distance) for conn in self.connections) @@ -100,47 +142,12 @@ class Graph: graph = cls.unserialize(pickle.load(f)) return graph - def build_router(self): - for room in self.rooms: - room.build_router() - self.transfer_points.extend(room.router.transfer_points) - - self.router = Router() - self.router.build(self.transfer_points, global_routing=True) - + # Drawing def draw_pngs(self, points=True, lines=True): for level in self.levels.values(): level.draw_png(points, lines) - def add_levelconnector_point(self, levelconnector, point): - self.levelconnector_points.setdefault(levelconnector.name, []).append(point) - - def connect_levelconnectors(self): - for levelconnector in LevelConnector.objects.all(): - center = levelconnector.geometry.centroid - points = self.levelconnector_points.get(levelconnector.name, []) - rooms = tuple(set(sum((point.rooms for point in points), []))) - - if len(rooms) < 2: - print('levelconnector %s on levels %s at (%.2f, %.2f) has <2 rooms (%d%s)!' % - (levelconnector.name, ', '.join(level.name for level in levelconnector.levels.all()), - center.x, center.y, len(rooms), (' on level '+rooms[0].level.level.name) if rooms else '')) - continue - - center_point = GraphPoint(center.x, center.y, rooms=rooms) - self.points.append(center_point) - - levels = tuple(set(room.level for room in rooms)) - for level in levels: - level.room_transfer_points.append(center_point) - level.points.append(center_point) - - for room in rooms: - room.points.append(center_point) - - for point in points: - center_point.connect_to(point) - point.connect_to(center_point) - - def add_connection(self, from_point, to_point, distance=None): - self.connections.append(GraphConnection(self, from_point, to_point, distance)) + # Router + def build_router(self): + for level in self.levels.values(): + level.build_router() diff --git a/src/c3nav/routing/level.py b/src/c3nav/routing/level.py index e8121e84..756c6bc9 100644 --- a/src/c3nav/routing/level.py +++ b/src/c3nav/routing/level.py @@ -20,6 +20,7 @@ class GraphLevel(): self.room_transfer_points = [] self.rooms = [] + # Building the Graph def build(self): print() print('Level %s:' % self.level.name) @@ -99,6 +100,7 @@ class GraphLevel(): room.points.append(point) self.graph.add_levelconnector_point(levelconnector, point) + # Drawing def draw_png(self, points=True, lines=True): filename = os.path.join(settings.RENDER_ROOT, 'level-%s.base.png' % self.level.name) graph_filename = os.path.join(settings.RENDER_ROOT, 'level-%s.graph.png' % self.level.name) @@ -123,3 +125,8 @@ class GraphLevel(): draw.line(_line_coords(point, otherpoint, height), fill=(0, 255, 255)) im.save(graph_filename) + + # Routing + def build_router(self): + for room in self.rooms: + room.build_router() diff --git a/src/c3nav/routing/room.py b/src/c3nav/routing/room.py index a2c1c7da..a123d147 100644 --- a/src/c3nav/routing/room.py +++ b/src/c3nav/routing/room.py @@ -21,6 +21,7 @@ class GraphRoom(): self.points = [] + # Building the Graph def prepare_build(self): self.clear_geometry = self.geometry.buffer(-0.3, join_style=JOIN_STYLE.mitre) @@ -157,6 +158,7 @@ class GraphRoom(): point2.connect_to(point1) i += 1 + # Routing def build_router(self): self.router = Router() self.router.build(self.points) diff --git a/src/c3nav/routing/router.py b/src/c3nav/routing/router.py index 7348efab..cfce82e9 100644 --- a/src/c3nav/routing/router.py +++ b/src/c3nav/routing/router.py @@ -27,8 +27,6 @@ class Router(): for point, pk in self.points_pk.items(): for to_point, connection in point.connections.items(): if to_point not in self.points_pk: - if not global_routing: - self.transfer_points.add(point) continue matrix[pk, self.points_pk[to_point]] = connection.distance if global_routing: