add option to include/exclude areas to UI
This commit is contained in:
parent
1c10ce443a
commit
91b9bc92b8
7 changed files with 70 additions and 23 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
@ -45,6 +47,17 @@ def get_public_private_area(level):
|
||||||
return public_area, private_area
|
return public_area, private_area
|
||||||
|
|
||||||
|
|
||||||
|
def get_excludables_includables():
|
||||||
|
excludables = []
|
||||||
|
includables = []
|
||||||
|
if settings.DEBUG:
|
||||||
|
excludables.append((':public', _('public areas')))
|
||||||
|
includables.append((':nonpublic', _('non-public areas')))
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
return OrderedDict(excludables), OrderedDict(includables)
|
||||||
|
|
||||||
|
|
||||||
class LockedMapFeatures(BasePermission):
|
class LockedMapFeatures(BasePermission):
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
if isinstance(obj, Source):
|
if isinstance(obj, Source):
|
||||||
|
|
|
@ -136,8 +136,8 @@ class GraphLevel():
|
||||||
self._built_arealocations[':public'] = public_area
|
self._built_arealocations[':public'] = public_area
|
||||||
self._built_excludables[':public'] = public_area
|
self._built_excludables[':public'] = public_area
|
||||||
|
|
||||||
self._built_arealocations[':private'] = private_area
|
self._built_arealocations[':nonpublic'] = private_area
|
||||||
self._built_excludables[':private'] = private_area
|
self._built_excludables[':nonpublic'] = private_area
|
||||||
|
|
||||||
# add points inside arealocations to be able to route to its borders
|
# add points inside arealocations to be able to route to its borders
|
||||||
for excludable in self._built_arealocations.values():
|
for excludable in self._built_arealocations.values():
|
||||||
|
|
|
@ -263,29 +263,26 @@ class GraphRoom():
|
||||||
return roomrouter
|
return roomrouter
|
||||||
|
|
||||||
def _build_router(self, ctypes, public, nonpublic, avoid, include):
|
def _build_router(self, ctypes, public, nonpublic, avoid, include):
|
||||||
distances = np.amin(self.distances[ctypes, :, :], axis=0)
|
distances = np.amin(self.distances[ctypes, :, :], axis=0).astype(np.float32)
|
||||||
orig_distances = None
|
factors = np.ones_like(distances, dtype=np.float16)
|
||||||
if include:
|
|
||||||
orig_distances = distances.copy()
|
|
||||||
|
|
||||||
if ':public' in self.excludables and not public:
|
if ':public' in self.excludables and not public:
|
||||||
points, = self.excludable_points[self.excludables.index(':public')].nonzero()
|
points, = self.excludable_points[self.excludables.index(':public')].nonzero()
|
||||||
distances[points[:, None], points] *= 1000
|
factors[points[:, None], points] = 1000
|
||||||
|
|
||||||
if ':private' in self.excludables and not nonpublic:
|
if ':nonpublic' in self.excludables and not nonpublic:
|
||||||
points, = self.excludable_points[self.excludables.index(':private')].nonzero()
|
points, = self.excludable_points[self.excludables.index(':nonpublic')].nonzero()
|
||||||
print(points)
|
factors[points[:, None], points] = np.inf
|
||||||
distances[points[:, None], points] = np.inf
|
|
||||||
|
|
||||||
if avoid:
|
if avoid:
|
||||||
points, = self.excludable_points[avoid, :].any(axis=0).nonzero()
|
points, = self.excludable_points[avoid].any(axis=0).nonzero()
|
||||||
distances[points[:, None], points] *= 1000
|
factors[points[:, None], points] = 1000
|
||||||
|
|
||||||
if include:
|
if include:
|
||||||
points, = self.excludable_points[include, :].any(axis=0).nonzero()
|
points, = self.excludable_points[include].any(axis=0).nonzero()
|
||||||
distances[points[:, None], points] = orig_distances[points[:, None], points]
|
factors[points[:, None], points] = 1
|
||||||
|
|
||||||
g_sparse = csgraph_from_dense(distances, null_value=np.inf)
|
g_sparse = csgraph_from_dense(distances*factors, null_value=np.inf)
|
||||||
shortest_paths, predecessors = shortest_path(g_sparse, return_predecessors=True)
|
shortest_paths, predecessors = shortest_path(g_sparse, return_predecessors=True)
|
||||||
return RoomRouter(shortest_paths, predecessors)
|
return RoomRouter(shortest_paths, predecessors)
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,6 @@ class Route:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def describe_point(point):
|
def describe_point(point):
|
||||||
print(point.arealocations)
|
|
||||||
locations = sorted(AreaLocation.objects.filter(location_type__in=('room', 'level', 'area'),
|
locations = sorted(AreaLocation.objects.filter(location_type__in=('room', 'level', 'area'),
|
||||||
name__in=point.arealocations),
|
name__in=point.arealocations),
|
||||||
key=AreaLocation.get_sort_key, reverse=True)
|
key=AreaLocation.get_sort_key, reverse=True)
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{% trans "Destination" as heading %}
|
{% trans "Destination" as heading %}
|
||||||
{% include 'site/fragment_location.html' with name='destination' location=destination heading=heading %}
|
{% include 'site/fragment_location.html' with name='destination' location=destination heading=heading %}
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row settings">
|
||||||
<div class="form-group col-md-2">
|
<div class="form-group col-md-2">
|
||||||
<label for="stairs-select">{% trans 'Stairs' %}</label>
|
<label for="stairs-select">{% trans 'Stairs' %}</label>
|
||||||
<select name="stairs" id="stairs-select" class="form-control">
|
<select name="stairs" id="stairs-select" class="form-control">
|
||||||
|
@ -42,8 +42,31 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="elevators-select">{% trans 'Get Route' %}</label>
|
<label>{% trans 'Include / Avoid:' %}</label>
|
||||||
<button type="submit" id="submitbtn" class="btn btn-block btn-primary">{% trans 'Get Route' %}</button>
|
<p class="form-control-static">
|
||||||
|
{% for name, includable in includables %}
|
||||||
|
<label class="checkbox-inline">
|
||||||
|
<input type="checkbox" name="include" value="{{ name }}"> {% blocktrans %}Include {{ includable }}{% endblocktrans %}
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
{% for name, excludable in excludables %}
|
||||||
|
<label class="checkbox-inline">
|
||||||
|
<input type="checkbox" name="avoid" value="{{ name }}"> {% blocktrans %}Avoid {{ excludable }}{% endblocktrans %}
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox"> {% trans 'Save Settings in cookie' %}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<button type="submit" id="submitbtn" class="btn btn-block btn-lg btn-primary">{% trans 'Get Route' %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -7,6 +7,7 @@ from PIL import Image, ImageDraw
|
||||||
|
|
||||||
from c3nav.mapdata.models import Level
|
from c3nav.mapdata.models import Level
|
||||||
from c3nav.mapdata.models.locations import get_location
|
from c3nav.mapdata.models.locations import get_location
|
||||||
|
from c3nav.mapdata.permissions import get_excludables_includables
|
||||||
from c3nav.mapdata.render.compose import composer
|
from c3nav.mapdata.render.compose import composer
|
||||||
from c3nav.mapdata.utils.misc import get_dimensions
|
from c3nav.mapdata.utils.misc import get_dimensions
|
||||||
from c3nav.routing.graph import Graph
|
from c3nav.routing.graph import Graph
|
||||||
|
@ -35,6 +36,8 @@ def main(request, origin=None, destination=None):
|
||||||
if destination is None:
|
if destination is None:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
|
excludables, includables = get_excludables_includables()
|
||||||
|
|
||||||
route = None
|
route = None
|
||||||
if request.method in ('GET', 'POST') and origin and destination:
|
if request.method in ('GET', 'POST') and origin and destination:
|
||||||
graph = Graph.load()
|
graph = Graph.load()
|
||||||
|
@ -44,8 +47,17 @@ def main(request, origin=None, destination=None):
|
||||||
allowed_ctypes += get_ctypes('escalator', request.POST.get('escalators'))
|
allowed_ctypes += get_ctypes('escalator', request.POST.get('escalators'))
|
||||||
allowed_ctypes += get_ctypes('elevator', request.POST.get('elevators'))
|
allowed_ctypes += get_ctypes('elevator', request.POST.get('elevators'))
|
||||||
|
|
||||||
route = graph.get_route(origin, destination, allowed_ctypes,
|
include = request.POST.getlist('include')
|
||||||
public=True, nonpublic=False, avoid=(), include=())
|
avoid = request.POST.getlist('avoid')
|
||||||
|
|
||||||
|
include = set(include) & set(includables)
|
||||||
|
avoid = set(avoid) & set(excludables)
|
||||||
|
|
||||||
|
public = ':public' not in avoid
|
||||||
|
nonpublic = ':nonpublic' in include
|
||||||
|
|
||||||
|
route = graph.get_route(origin, destination, allowed_ctypes, public=public, nonpublic=nonpublic,
|
||||||
|
avoid=avoid-set(':public'), include=include-set(':nonpublic'))
|
||||||
route = route.split()
|
route = route.split()
|
||||||
route.create_routeparts()
|
route.create_routeparts()
|
||||||
|
|
||||||
|
@ -67,6 +79,10 @@ def main(request, origin=None, destination=None):
|
||||||
return render(request, 'site/main.html', {
|
return render(request, 'site/main.html', {
|
||||||
'origin': origin,
|
'origin': origin,
|
||||||
'destination': destination,
|
'destination': destination,
|
||||||
|
|
||||||
|
'excludables': excludables.items(),
|
||||||
|
'includables': includables.items(),
|
||||||
|
|
||||||
'route': route,
|
'route': route,
|
||||||
'width': width,
|
'width': width,
|
||||||
'height': height,
|
'height': height,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue