add ways from/to origin/destination to final route

This commit is contained in:
Laura Klünder 2016-12-21 01:01:20 +01:00
parent bbfca9f318
commit f8e6e69b0f
2 changed files with 50 additions and 8 deletions

View file

@ -14,7 +14,8 @@ from c3nav.mapdata.models.locations import AreaLocation, Location, LocationGroup
from c3nav.routing.level import GraphLevel from c3nav.routing.level import GraphLevel
from c3nav.routing.point import GraphPoint from c3nav.routing.point import GraphPoint
from c3nav.routing.route import NoRoute from c3nav.routing.route import NoRoute
from c3nav.routing.routesegments import GraphRouteSegment, LevelRouteSegment, RoomRouteSegment, SegmentRoute from c3nav.routing.routesegments import (GraphRouteSegment, LevelRouteSegment, RoomRouteSegment, SegmentRoute,
SegmentRouteWrapper)
class Graph: class Graph:
@ -243,16 +244,16 @@ class Graph:
def get_location_points(self, location: Location, mode): def get_location_points(self, location: Location, mode):
if isinstance(location, PointLocation): if isinstance(location, PointLocation):
points = self.levels[location.level.name].connected_points(np.array((location.x, location.y)), mode) points = self.levels[location.level.name].connected_points(np.array((location.x, location.y)), mode)
points, distances = zip(*((point_i, distance) for point_i, (distance, ctype) in points.items())) points, distances, ctypes = zip(*((point, distance, ctype)for point, (distance, ctype) in points.items()))
points = np.array(points) points = np.array(points)
distances = np.array(distances) distances = np.array(distances)
return points, distances return points, distances, ctypes
elif isinstance(location, AreaLocation): elif isinstance(location, AreaLocation):
points = self.levels[location.level.name].arealocation_points[location.name] points = self.levels[location.level.name].arealocation_points[location.name]
return points, None return points, None, None
elif isinstance(location, LocationGroup): elif isinstance(location, LocationGroup):
points = set(np.hstack(tuple(self.get_location_points(area) for area in location.locationareas))) points = set(np.hstack(tuple(self.get_location_points(area) for area in location.locationareas)))
return points, None return points, None, None
def _get_points_by_i(self, points): def _get_points_by_i(self, points):
return tuple(self.points[i] for i in points) return tuple(self.points[i] for i in points)
@ -261,8 +262,11 @@ class Graph:
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, public, nonpublic, avoid, include): def get_route(self, origin: Location, destination: Location, allowed_ctypes, public, nonpublic, avoid, include):
orig_points_i, orig_distances = self.get_location_points(origin, 'orig') orig_points_i, orig_distances, orig_ctypes = self.get_location_points(origin, 'orig')
dest_points_i, dest_distances = self.get_location_points(destination, 'dest') dest_points_i, dest_distances, dest_ctypes = self.get_location_points(destination, 'dest')
add_orig_point = origin if isinstance(origin, PointLocation) else None
add_dest_point = destination if isinstance(destination, PointLocation) else None
orig_points = self._get_points_by_i(orig_points_i) orig_points = self._get_points_by_i(orig_points_i)
dest_points = self._get_points_by_i(dest_points_i) dest_points = self._get_points_by_i(dest_points_i)
@ -384,6 +388,11 @@ class Graph:
dest_level_transfers[self.level_transfer_points[to_point]]), dest_level_transfers[self.level_transfer_points[to_point]]),
distance=distance) distance=distance)
if best_route is not NoRoute:
orig_ctype = orig_ctypes[tuple(orig_points_i).index(best_route.from_point)] if add_orig_point else None
dest_ctype = dest_ctypes[tuple(dest_points_i).index(best_route.to_point)] if add_dest_point else None
best_route = SegmentRouteWrapper(best_route, orig_point=add_orig_point, dest_point=add_dest_point,
orig_ctype=orig_ctype, dest_ctype=dest_ctype)
return best_route return best_route
def _room_transfers(self, rooms, room_points, routers, mode): def _room_transfers(self, rooms, room_points, routers, mode):

View file

@ -2,6 +2,8 @@ from abc import ABC, abstractmethod
from django.utils.functional import cached_property from django.utils.functional import cached_property
from c3nav.routing.connection import GraphConnection
from c3nav.routing.point import GraphPoint
from c3nav.routing.route import Route from c3nav.routing.route import Route
@ -135,5 +137,36 @@ class SegmentRoute:
return ('<SegmentedRoute (\n %s\n) distance=%f>' % return ('<SegmentedRoute (\n %s\n) distance=%f>' %
('\n '.join(repr(segment) for segment in self.segments), self.distance)) ('\n '.join(repr(segment) for segment in self.segments), self.distance))
def rawsplit(self):
return sum((segment.get_connections() for segment in self.segments), ())
def split(self): def split(self):
return Route(sum((segment.get_connections() for segment in self.segments), ())) return Route(self.rawsplit())
class SegmentRouteWrapper:
def __init__(self, segmentroute: SegmentRoute, orig_point, dest_point, orig_ctype, dest_ctype):
self.segmentroute = segmentroute
self.orig_point = orig_point
self.dest_point = dest_point
self.orig_ctype = orig_ctype
self.dest_ctype = dest_ctype
def __repr__(self):
return ('<SegmentedRouteWrapper %s, add_orig_point=%s, add_dest_point=%s>' %
(repr(self.segmentroute), repr(self.orig_point), repr(self.dest_point)))
def split(self):
connections = self.segmentroute.rawsplit()
if self.orig_point:
first_point = connections[0].from_point
orig_point = GraphPoint(self.orig_point.x, self.orig_point.y, first_point.room)
connections = (GraphConnection(orig_point, first_point, ctype=self.orig_ctype),) + connections
if self.dest_point:
last_point = connections[-1].to_point
dest_point = GraphPoint(self.dest_point.x, self.dest_point.y, last_point.room)
connections = connections + (GraphConnection(last_point, dest_point, ctype=self.dest_ctype), )
return Route(connections)