better graph building (routing to be fixed) using points with no room or no level

This commit is contained in:
Laura Klünder 2016-12-06 19:39:42 +01:00
parent e2a13e7f27
commit f0a2f5e058
5 changed files with 96 additions and 79 deletions

View file

@ -1,5 +1,4 @@
import os
from itertools import permutations
from django.conf import settings
from PIL import Image, ImageDraw
@ -17,68 +16,72 @@ class GraphLevel():
self.graph = graph
self.level = level
self.points = []
self.no_room_points = []
self.rooms = []
def build(self):
print('Level %s:' % self.level.name)
self.collect_rooms()
self.create_points()
print('%d rooms' % len(self.rooms))
for room in self.rooms:
room.create_points()
self.create_doors()
self.create_levelconnectors()
for room in self.rooms:
room.connect_points()
print('%d points' % len(self.points))
print('%d room transfer points' % len(self.no_room_points))
print()
def collect_rooms(self):
accessibles = self.level.geometries.accessible
accessibles = assert_multipolygon(accessibles)
for geometry in accessibles:
room = GraphRoom(self, geometry)
if not room.empty:
self.rooms.append(room)
def create_points(self):
print('Level %s:' % self.level.name)
for room in self.rooms:
room.create_points()
GraphRoom(self, geometry)
def create_doors(self):
doors = self.level.geometries.doors
doors = assert_multipolygon(doors)
for door in doors:
polygon = door.buffer(0.01, join_style=JOIN_STYLE.mitre)
center = door.centroid
points = []
center_point = GraphPoint(center.x, center.y, level=self)
num_points = 0
for room in self.rooms:
if polygon.intersects(room.geometry):
nearest_point = get_nearest_point(room.clear_geometry, center)
point = GraphPoint(room, *nearest_point.coords[0])
points.append(point)
room.points.append(point)
if not polygon.intersects(room.geometry):
continue
if len(points) < 2:
print('door with <2 rooms (%d) detected at (%.2f, %.2f)' % (len(points), center.x, center.y))
for subpolygon in assert_multipolygon(polygon.intersection(room.geometry)):
nearest_point = get_nearest_point(room.clear_geometry, subpolygon.centroid)
point = GraphPoint(nearest_point.x, nearest_point.y, room)
center_point.connect_to(point)
point.connect_to(center_point)
num_points += 1
for from_point, to_point in permutations(points, 2):
from_point.connect_to(to_point)
if num_points < 2:
print('door with <2 num_points (%d) detected at (%.2f, %.2f)' % (num_points, center.x, center.y))
def create_levelconnectors(self):
for levelconnector in self.level.levelconnectors.all():
polygon = levelconnector.geometry
center = polygon.centroid
for room in self.rooms:
if not polygon.intersects(room.geometry):
continue
point = center
if not point.within(room.clear_geometry):
point = get_nearest_point(room.clear_geometry, point)
for subpolygon in assert_multipolygon(polygon.intersection(room.geometry)):
point = subpolygon.centroid
if not point.within(room.clear_geometry):
point = get_nearest_point(room.clear_geometry, point)
point = GraphPoint(point.x, point.y, room)
self.graph.add_levelconnector_point(levelconnector, point)
point = GraphPoint(room, *point.coords[0])
room.points.append(point)
self.graph.add_levelconnector_point(levelconnector, point)
for room in self.rooms:
room.connect_points()
self.points = sum((room.points for room in self.rooms), [])
print('%d points' % len(self.points))
print()
def draw_png(self, points=True, lines=True, transfer_points=False, transfer_lines=False):
def draw_png(self, points=True, lines=True):
filename = os.path.join(settings.RENDER_ROOT, 'level-%s.base.png' % self.level.name)
graph_filename = os.path.join(settings.RENDER_ROOT, 'level-%s.graph.png' % self.level.name)
@ -94,15 +97,12 @@ class GraphLevel():
for point in self.points:
draw.ellipse(_ellipse_bbox(point.x, point.y, height), (200, 0, 0))
if transfer_lines:
for point in self.points:
if point.in_room_transfer_distances is not None:
for otherpoint, distance in point.in_room_transfer_distances.items():
draw.line(_line_coords(point, otherpoint, height), fill=(100, 100, 255))
for point in self.no_room_points:
draw.ellipse(_ellipse_bbox(point.x, point.y, height), (0, 0, 255))
if transfer_points:
for point in self.points:
if point.in_room_transfer_distances is not None:
draw.ellipse(_ellipse_bbox(point.x, point.y, height), (0, 0, 200))
for point in self.points:
for otherpoint, connection in point.connections.items():
if otherpoint in self.graph.no_level_points:
draw.line(_line_coords(point, otherpoint, height), fill=(0, 255, 255))
im.save(graph_filename)