routing support for excludables (not yet in UI)

This commit is contained in:
Laura Klünder 2016-12-19 21:24:40 +01:00
parent 1e0346a54d
commit 1c10ce443a
4 changed files with 41 additions and 15 deletions

View file

@ -208,7 +208,7 @@ class Graph:
level.draw_png(points, lines) level.draw_png(points, lines)
# Router # Router
def build_routers(self, allowed_ctypes): def build_routers(self, allowed_ctypes, public, nonpublic, avoid, include):
routers = {} routers = {}
empty_distances = np.empty(shape=(len(self.level_transfer_points),) * 2, dtype=np.float16) empty_distances = np.empty(shape=(len(self.level_transfer_points),) * 2, dtype=np.float16)
@ -220,7 +220,7 @@ class Graph:
level_transfers[:] = -1 level_transfers[:] = -1
for i, level in enumerate(self.levels.values()): for i, level in enumerate(self.levels.values()):
routers.update(level.build_routers(allowed_ctypes)) routers.update(level.build_routers(allowed_ctypes, public, nonpublic, avoid, include))
router = routers[level] router = routers[level]
level_distances = empty_distances.copy() level_distances = empty_distances.copy()
@ -254,7 +254,7 @@ class Graph:
def _allowed_points_index(self, points, allowed_points_i): def _allowed_points_index(self, points, allowed_points_i):
return np.array(tuple(i for i, point in enumerate(points) if point in allowed_points_i)) return np.array(tuple(i for i, point in enumerate(points) if point in allowed_points_i))
def get_route(self, origin: Location, destination: Location, allowed_ctypes): def get_route(self, origin: Location, destination: Location, allowed_ctypes, public, nonpublic, avoid, include):
orig_points_i = set(self.get_location_points(origin)) orig_points_i = set(self.get_location_points(origin))
dest_points_i = set(self.get_location_points(destination)) dest_points_i = set(self.get_location_points(destination))
@ -264,7 +264,7 @@ class Graph:
best_route = NoRoute best_route = NoRoute
# get routers # get routers
routers = self.build_routers(allowed_ctypes) routers = self.build_routers(allowed_ctypes, public, nonpublic, avoid, include)
# route within room # route within room
orig_rooms = set(point.room for point in orig_points) orig_rooms = set(point.room for point in orig_points)

View file

@ -352,7 +352,7 @@ class GraphLevel():
im.save(graph_filename) im.save(graph_filename)
# Routing # Routing
def build_routers(self, allowed_ctypes): def build_routers(self, allowed_ctypes, public, nonpublic, avoid, include):
routers = {} routers = {}
empty_distances = np.empty(shape=(len(self.room_transfer_points),) * 2, dtype=np.float16) empty_distances = np.empty(shape=(len(self.room_transfer_points),) * 2, dtype=np.float16)
@ -364,7 +364,7 @@ class GraphLevel():
room_transfers[:] = -1 room_transfers[:] = -1
for i, room in enumerate(self.rooms): for i, room in enumerate(self.rooms):
router = room.build_router(allowed_ctypes) router = room.build_router(allowed_ctypes, public, nonpublic, avoid, include)
routers[room] = router routers[room] = router
room_distances = empty_distances.copy() room_distances = empty_distances.copy()

View file

@ -46,7 +46,7 @@ class GraphRoom():
def unserialize(cls, level, data): def unserialize(cls, level, data):
room = cls(level) room = cls(level)
(room.mpl_clear, areas, room.points, room.room_transfer_points, (room.mpl_clear, areas, room.points, room.room_transfer_points,
room.distances, room.ctypes, room.edcludables, room.excludable_points) = data room.distances, room.ctypes, room.excludables, room.excludable_points) = data
room.areas = tuple(GraphArea(room, *area) for area in areas) room.areas = tuple(GraphArea(room, *area) for area in areas)
return room return room
@ -221,7 +221,7 @@ class GraphRoom():
excludable_points = list() excludable_points = list()
for excludable in self.excludables: for excludable in self.excludables:
points = self.level.arealocation_points[excludable] points = self.level.arealocation_points[excludable]
excludable_points.append(np.array(tuple(i for i in self.points if i in points))) excludable_points.append(np.array(tuple((i in points) for i in self.points)))
self.excludable_points = np.array(excludable_points) self.excludable_points = np.array(excludable_points)
mapping = {point.i: i for i, point in enumerate(self._built_points)} mapping = {point.i: i for i, point in enumerate(self._built_points)}
@ -248,19 +248,44 @@ class GraphRoom():
# Routing # Routing
router_cache = {} router_cache = {}
def build_router(self, allowed_ctypes): def build_router(self, allowed_ctypes, public, nonpublic, avoid, include):
ctypes = tuple(i for i, ctype in enumerate(self.ctypes) if ctype in allowed_ctypes) ctypes = tuple(i for i, ctype in enumerate(self.ctypes) if ctype in allowed_ctypes)
cache_key = ('c3nav__graph__roomrouter__%s__%s__%s' % avoid = tuple(i for i, excludable in enumerate(self.excludables) if excludable in avoid)
(self.graph.mtime, self.i, ','.join(str(i) for i in ctypes))) include = tuple(i for i, excludable in enumerate(self.excludables) if excludable in include)
cache_key = ('c3nav__graph__roomrouter__%s__%s__%s__%d,%d__%s__%s' %
(self.graph.mtime, self.i, ','.join(str(i) for i in ctypes),
public, nonpublic, ','.join(str(i) for i in avoid), ','.join(str(i) for i in include)))
roomrouter = self.router_cache.get(cache_key) roomrouter = self.router_cache.get(cache_key)
if not roomrouter: if not roomrouter:
roomrouter = self._build_router(ctypes) roomrouter = self._build_router(ctypes, public, nonpublic, avoid, include)
self.router_cache[cache_key] = roomrouter self.router_cache[cache_key] = roomrouter
return roomrouter return roomrouter
def _build_router(self, ctypes): def _build_router(self, ctypes, public, nonpublic, avoid, include):
g_sparse = csgraph_from_dense(np.amin(self.distances[ctypes, :, :], 0), null_value=np.inf) distances = np.amin(self.distances[ctypes, :, :], axis=0)
orig_distances = None
if include:
orig_distances = distances.copy()
if ':public' in self.excludables and not public:
points, = self.excludable_points[self.excludables.index(':public')].nonzero()
distances[points[:, None], points] *= 1000
if ':private' in self.excludables and not nonpublic:
points, = self.excludable_points[self.excludables.index(':private')].nonzero()
print(points)
distances[points[:, None], points] = np.inf
if avoid:
points, = self.excludable_points[avoid, :].any(axis=0).nonzero()
distances[points[:, None], points] *= 1000
if include:
points, = self.excludable_points[include, :].any(axis=0).nonzero()
distances[points[:, None], points] = orig_distances[points[:, None], points]
g_sparse = csgraph_from_dense(distances, null_value=np.inf)
shortest_paths, predecessors = shortest_path(g_sparse, return_predecessors=True) shortest_paths, predecessors = shortest_path(g_sparse, return_predecessors=True)
return RoomRouter(shortest_paths, predecessors) return RoomRouter(shortest_paths, predecessors)

View file

@ -44,7 +44,8 @@ def main(request, origin=None, destination=None):
allowed_ctypes += get_ctypes('escalator', request.POST.get('escalators')) allowed_ctypes += get_ctypes('escalator', request.POST.get('escalators'))
allowed_ctypes += get_ctypes('elevator', request.POST.get('elevators')) allowed_ctypes += get_ctypes('elevator', request.POST.get('elevators'))
route = graph.get_route(origin, destination, allowed_ctypes) route = graph.get_route(origin, destination, allowed_ctypes,
public=True, nonpublic=False, avoid=(), include=())
route = route.split() route = route.split()
route.create_routeparts() route.create_routeparts()