2016-12-17 13:24:42 +01:00
|
|
|
import numpy as np
|
|
|
|
from django.utils.functional import cached_property
|
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
from c3nav.mapdata.utils.misc import get_dimensions
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
class Route:
|
|
|
|
def __init__(self, connections, distance=None):
|
|
|
|
self.connections = tuple(connections)
|
|
|
|
self.distance = sum(connection.distance for connection in self.connections)
|
|
|
|
self.from_point = connections[0].from_point
|
|
|
|
self.to_point = connections[-1].to_point
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 13:24:42 +01:00
|
|
|
def __repr__(self):
|
2016-12-17 19:25:27 +01:00
|
|
|
return ('<Route (\n %s\n) distance=%f>' %
|
|
|
|
('\n '.join(repr(connection) for connection in self.connections), self.distance))
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
@cached_property
|
|
|
|
def routeparts(self):
|
|
|
|
routeparts = []
|
|
|
|
connections = []
|
|
|
|
level = self.connections[0].from_point.level
|
|
|
|
|
|
|
|
for connection in self.connections:
|
|
|
|
connections.append(connection)
|
|
|
|
point = connection.to_point
|
|
|
|
if point.level and point.level != level:
|
|
|
|
routeparts.append(RoutePart(level, connections))
|
|
|
|
level = point.level
|
2016-12-18 00:26:00 +01:00
|
|
|
connections = [connection]
|
2016-12-17 19:25:27 +01:00
|
|
|
|
|
|
|
if connections:
|
|
|
|
routeparts.append(RoutePart(level, connections))
|
|
|
|
return tuple(routeparts)
|
|
|
|
|
|
|
|
|
|
|
|
class RoutePart:
|
|
|
|
def __init__(self, level, connections):
|
2016-12-17 13:24:42 +01:00
|
|
|
self.level = level
|
2016-12-17 19:25:27 +01:00
|
|
|
self.level_name = level.level.name
|
|
|
|
self.connections = connections
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 22:15:14 +01:00
|
|
|
svg_width, svg_height = get_dimensions()
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
points = (connections[0].from_point, ) + tuple(connection.to_point for connection in connections)
|
|
|
|
for point in points:
|
|
|
|
point.svg_x = point.x * 6
|
2016-12-17 22:15:14 +01:00
|
|
|
point.svg_y = (svg_height - point.y) * 6
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
x, y = zip(*((point.svg_x, point.svg_y) for point in points if point.level == level))
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
self.distance = sum(connection.distance for connection in connections)
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 19:25:27 +01:00
|
|
|
# bounds for rendering
|
2016-12-17 22:15:14 +01:00
|
|
|
self.svg_min_x = min(x) - 20
|
|
|
|
self.svg_max_x = max(x) + 20
|
|
|
|
self.svg_min_y = min(y) - 20
|
|
|
|
self.svg_max_y = max(y) + 20
|
2016-12-17 13:24:42 +01:00
|
|
|
|
2016-12-17 22:15:14 +01:00
|
|
|
svg_width = self.svg_max_x - self.svg_min_x
|
|
|
|
svg_height = self.svg_max_y - self.svg_min_y
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 22:15:14 +01:00
|
|
|
if svg_width < 150:
|
|
|
|
self.svg_min_x -= (10 - svg_width) / 2
|
|
|
|
self.svg_max_x += (10 - svg_width) / 2
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 22:15:14 +01:00
|
|
|
if svg_height < 150:
|
|
|
|
self.svg_min_y += (10 - svg_height) / 2
|
|
|
|
self.svg_max_y -= (10 - svg_height) / 2
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 22:15:14 +01:00
|
|
|
self.svg_width = self.svg_max_x - self.svg_min_x
|
|
|
|
self.svg_height = self.svg_max_y - self.svg_min_y
|
2016-12-17 19:25:27 +01:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return repr(self.__dict__)
|
|
|
|
|
|
|
|
|
|
|
|
class RouteLine:
|
|
|
|
def __init__(self, from_point, to_point, distance):
|
|
|
|
self.from_point = from_point
|
|
|
|
self.to_point = to_point
|
|
|
|
self.distance = distance
|
2016-12-17 14:46:15 +01:00
|
|
|
|
2016-12-17 13:24:42 +01:00
|
|
|
|
|
|
|
class NoRoute:
|
|
|
|
distance = np.inf
|