buildgraph: add oneways
This commit is contained in:
parent
405c688eac
commit
1e5923dbb8
3 changed files with 73 additions and 3 deletions
|
@ -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 = []
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue