buildgraph: add oneways

This commit is contained in:
Laura Klünder 2016-12-18 14:36:06 +01:00
parent 405c688eac
commit 1e5923dbb8
3 changed files with 73 additions and 3 deletions

View file

@ -180,6 +180,10 @@ class LevelGeometries():
def accessible(self): def accessible(self):
return self.areas.difference(self.holes).difference(self.obstacles) return self.areas.difference(self.holes).difference(self.obstacles)
@cached_property
def accessible_without_oneways(self):
return self.accessible.difference(self.oneways_buffered)
@cached_property @cached_property
def buildings_with_holes(self): def buildings_with_holes(self):
return self.buildings.difference(self.holes) return self.buildings.difference(self.holes)
@ -241,6 +245,18 @@ class LevelGeometries():
def escalatorslopes(self): def escalatorslopes(self):
return cascaded_union([s.geometry for s in self.query('escalatorslopes')]).intersection(self.accessible) return cascaded_union([s.geometry for s in self.query('escalatorslopes')]).intersection(self.accessible)
@cached_property
def oneways_raw(self):
return cascaded_union([oneway.geometry for oneway in self.query('oneways')])
@cached_property
def oneways(self):
return self.oneways_raw.intersection(self.accessible)
@cached_property
def oneways_buffered(self):
return self.oneways_raw.buffer(0.05, join_style=JOIN_STYLE.mitre, cap_style=CAP_STYLE.square)
@cached_property @cached_property
def stair_areas(self): def stair_areas(self):
left = [] left = []

View file

@ -7,7 +7,7 @@ from matplotlib.path import Path
from PIL import Image, ImageDraw from PIL import Image, ImageDraw
from scipy.sparse.csgraph._shortest_path import shortest_path from scipy.sparse.csgraph._shortest_path import shortest_path
from scipy.sparse.csgraph._tools import csgraph_from_dense from scipy.sparse.csgraph._tools import csgraph_from_dense
from shapely.geometry import JOIN_STYLE from shapely.geometry import CAP_STYLE, JOIN_STYLE, LineString
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
from c3nav.routing.point import GraphPoint from c3nav.routing.point import GraphPoint
@ -61,6 +61,7 @@ class GraphLevel():
room.build_points() room.build_points()
self.create_doors() self.create_doors()
self.create_oneways()
self.create_levelconnectors() self.create_levelconnectors()
self.create_elevatorlevels() self.create_elevatorlevels()
@ -103,8 +104,15 @@ class GraphLevel():
print('Escalator %s has no slope line!' % escalator.name) print('Escalator %s has no slope line!' % escalator.name)
continue continue
def collect_oneways(self):
self._built_oneways = ()
for oneway_line in assert_multilinestring(self.level.geometries.oneways):
coords = tuple(oneway_line.coords)
self._built_oneways += tuple((Path(part), coord_angle(*part))
for part in zip(coords[:-1], coords[1:]))
def collect_rooms(self): def collect_rooms(self):
accessibles = self.level.geometries.accessible accessibles = self.level.geometries.accessible_without_oneways
accessibles = assert_multipolygon(accessibles) accessibles = assert_multipolygon(accessibles)
for geometry in accessibles: for geometry in accessibles:
room = GraphRoom(self) room = GraphRoom(self)
@ -144,6 +152,52 @@ class GraphLevel():
center_point.connect_to(point) center_point.connect_to(point)
point.connect_to(center_point) point.connect_to(center_point)
def create_oneways(self):
oneways = self.level.geometries.oneways
oneways = assert_multilinestring(oneways)
segments = ()
for oneway in oneways:
coords = tuple(oneway.coords)
segments += tuple((Path(part), coord_angle(*part))
for part in zip(coords[:-1], coords[1:]))
for oneway, oneway_angle in segments:
line_string = LineString(tuple(oneway.vertices))
polygon = line_string.buffer(0.10, join_style=JOIN_STYLE.mitre, cap_style=CAP_STYLE.flat)
center = polygon.centroid
num_points = 0
connected_rooms = set()
points = []
for room in self.rooms:
if not polygon.intersects(room._built_geometry):
continue
for subpolygon in assert_multipolygon(polygon.intersection(room._built_geometry)):
connected_rooms.add(room)
nearest_point = get_nearest_point(room.clear_geometry, subpolygon.centroid)
point, = room.add_point(nearest_point.coords[0])
points.append(point)
if len(points) < 2:
print('oneway with <2 points (%d) detected at (%.2f, %.2f)' % (num_points, center.x, center.y))
continue
center_point = GraphPoint(center.x, center.y, None)
self._built_room_transfer_points.append(center_point)
for room in connected_rooms:
room._built_points.append(center_point)
for point in points:
angle = coord_angle(point.xy, center_point.xy)
angle_diff = ((oneway_angle - angle + 180) % 360) - 180
direction_up = (angle_diff > 0)
if direction_up:
point.connect_to(center_point)
else:
center_point.connect_to(point)
def create_levelconnectors(self): def create_levelconnectors(self):
for levelconnector in self.level.levelconnectors.all(): for levelconnector in self.level.levelconnectors.all():
polygon = levelconnector.geometry polygon = levelconnector.geometry

View file

@ -42,7 +42,7 @@ def main(request, origin=None, destination=None):
route = None route = None
if origin and destination: if origin and destination:
graph = Graph.load() graph = Graph.load()
route = graph.get_route(origin, destination, ('', 'steps_down', 'steps_up', 'elevator_down', 'elevator_up')) route = graph.get_route(origin, destination, ('', 'escalator_down', 'escalator_up'))
print(route) print(route)
route = route.split() route = route.split()
print(route) print(route)