columns can have an accessrestriction now
This commit is contained in:
parent
f05b8f19c5
commit
8936fe5aea
5 changed files with 58 additions and 7 deletions
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.1.4 on 2018-12-12 17:47
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mapdata', '0002_fix_broken_spaces'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='column',
|
||||
name='access_restriction',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='columns', to='mapdata.AccessRestriction', verbose_name='Access Restriction'),
|
||||
),
|
||||
]
|
|
@ -206,7 +206,7 @@ class AltitudeArea(LevelGeometryMixin, models.Model):
|
|||
if space.outside:
|
||||
space.geometry = space.geometry.difference(buildings_geom)
|
||||
space_accessible = space.geometry.difference(
|
||||
unary_union(tuple(c.geometry for c in space.columns.all()) +
|
||||
unary_union(tuple(c.geometry for c in space.columns.all() if c.access_restriction_id is None) +
|
||||
tuple(o.geometry for o in space.obstacles.all()) +
|
||||
tuple(o.buffered_geometry for o in space.lineobstacles.all()) +
|
||||
tuple(h.geometry for h in space.holes.all()))
|
||||
|
|
|
@ -13,6 +13,7 @@ from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
|
|||
from c3nav.mapdata.fields import GeometryField, I18nField, JSONField
|
||||
from c3nav.mapdata.grid import grid
|
||||
from c3nav.mapdata.models import Space
|
||||
from c3nav.mapdata.models.access import AccessRestrictionMixin
|
||||
from c3nav.mapdata.models.base import SerializableMixin
|
||||
from c3nav.mapdata.models.geometry.base import GeometryMixin
|
||||
from c3nav.mapdata.models.locations import SpecificLocation
|
||||
|
@ -97,7 +98,7 @@ class SpaceGeometryMixin(GeometryMixin):
|
|||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class Column(SpaceGeometryMixin, models.Model):
|
||||
class Column(SpaceGeometryMixin, AccessRestrictionMixin, models.Model):
|
||||
"""
|
||||
An column in a space, also used to be able to create rooms within rooms.
|
||||
"""
|
||||
|
|
|
@ -74,7 +74,7 @@ class LevelGeometries:
|
|||
subtract = []
|
||||
if space.outside:
|
||||
subtract.append(buildings_geom)
|
||||
columns = [c.geometry for c in space.columns.all()]
|
||||
columns = [c.geometry for c in space.columns.all() if c.access_restriction_id is None]
|
||||
if columns:
|
||||
subtract.extend(columns)
|
||||
if subtract:
|
||||
|
@ -108,14 +108,15 @@ class LevelGeometries:
|
|||
obstacles = {}
|
||||
heightareas = {}
|
||||
for space in level.spaces.all():
|
||||
buffered = space.geometry.buffer(0.01).union(unary_union(
|
||||
tuple(door.geometry for door in level.doors.all() if door.geometry.intersects(space.geometry))
|
||||
).difference(walkable_spaces_geom))
|
||||
intersects = buildings_geom_prep.intersects(buffered)
|
||||
|
||||
access_restriction = space.access_restriction_id
|
||||
if access_restriction is not None:
|
||||
access_restriction_affected.setdefault(access_restriction, []).append(space.geometry)
|
||||
buffered = space.geometry.buffer(0.01).union(unary_union(
|
||||
tuple(door.geometry for door in level.doors.all() if door.geometry.intersects(space.geometry))
|
||||
).difference(walkable_spaces_geom))
|
||||
|
||||
intersects = buildings_geom_prep.intersects(buffered)
|
||||
if intersects:
|
||||
restricted_spaces_indoors.setdefault(access_restriction, []).append(
|
||||
buffered.intersection(buildings_geom)
|
||||
|
@ -134,6 +135,18 @@ class LevelGeometries:
|
|||
access_restriction_affected.setdefault(access_restriction, []).append(area.geometry)
|
||||
colors.setdefault(area.get_color(), {}).setdefault(access_restriction, []).append(area.geometry)
|
||||
|
||||
for column in space.columns.all():
|
||||
access_restriction = column.access_restriction_id
|
||||
if access_restriction is None:
|
||||
continue
|
||||
column.geometry = column.geometry.intersection(space.walkable_geom)
|
||||
buffered_column = column.geometry.buffer(0.01)
|
||||
if intersects:
|
||||
restricted_spaces_indoors.setdefault(access_restriction, []).append(buffered_column)
|
||||
if not intersects or not buildings_geom_prep.contains(buffered):
|
||||
restricted_spaces_outdoors.setdefault(access_restriction, []).append(buffered_column)
|
||||
access_restriction_affected.setdefault(access_restriction, []).append(column.geometry)
|
||||
|
||||
for obstacle in space.obstacles.all():
|
||||
if not obstacle.height:
|
||||
continue
|
||||
|
|
|
@ -176,6 +176,15 @@ class Router:
|
|||
pois[poi.pk] = poi
|
||||
space.pois.add(poi.pk)
|
||||
|
||||
for column in space_obj.columns.all():
|
||||
if column.access_restriction_id is None:
|
||||
continue
|
||||
column.geometry_prep = prepared.prep(column.geometry)
|
||||
column_nodes = tuple(node for node in space_nodes if column.geometry_prep.intersects(node.point))
|
||||
column_nodes = set(node.i for node in column_nodes)
|
||||
restrictions.setdefault(column.access_restriction_id,
|
||||
RouterRestriction()).additional_nodes.update(column_nodes)
|
||||
|
||||
space_obj._prefetched_objects_cache = {}
|
||||
|
||||
space.src.geometry = accessible_geom
|
||||
|
@ -397,6 +406,9 @@ class Router:
|
|||
space_nodes = tuple(reduce(operator.or_, (self.spaces[space].nodes for space in restrictions.spaces), set()))
|
||||
graph[space_nodes, :] = np.inf
|
||||
graph[:, space_nodes] = np.inf
|
||||
if restrictions.additional_nodes:
|
||||
graph[restrictions.additional_nodes, :] = np.inf
|
||||
graph[:, restrictions.additional_nodes] = np.inf
|
||||
graph[restrictions.edges.transpose().tolist()] = np.inf
|
||||
|
||||
distances, predecessors = shortest_path(graph, directed=True, return_predecessors=True)
|
||||
|
@ -670,6 +682,7 @@ class RouterLocation:
|
|||
class RouterRestriction:
|
||||
def __init__(self, spaces=None):
|
||||
self.spaces = spaces if spaces else set()
|
||||
self.additional_nodes = set()
|
||||
self.edges = deque()
|
||||
|
||||
|
||||
|
@ -681,6 +694,11 @@ class RouterRestrictionSet:
|
|||
def spaces(self):
|
||||
return reduce(operator.or_, (restriction.spaces for restriction in self.restrictions.values()), frozenset())
|
||||
|
||||
@cached_property
|
||||
def additional_nodes(self):
|
||||
return reduce(operator.or_, (restriction.additional_nodes
|
||||
for restriction in self.restrictions.values()), frozenset())
|
||||
|
||||
@cached_property
|
||||
def edges(self):
|
||||
if not self.restrictions:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue