refactor graph code
This commit is contained in:
parent
e6978c6e61
commit
57ed2ec368
4 changed files with 65 additions and 51 deletions
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue