add option to include/exclude areas to UI

This commit is contained in:
Laura Klünder 2016-12-19 22:52:09 +01:00
parent 1c10ce443a
commit 91b9bc92b8
7 changed files with 70 additions and 23 deletions

View file

@ -1,3 +1,5 @@
from collections import OrderedDict
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import PermissionDenied
@ -45,6 +47,17 @@ def get_public_private_area(level):
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):
def has_object_permission(self, request, view, obj):
if isinstance(obj, Source):

View file

@ -136,8 +136,8 @@ class GraphLevel():
self._built_arealocations[':public'] = public_area
self._built_excludables[':public'] = public_area
self._built_arealocations[':private'] = private_area
self._built_excludables[':private'] = private_area
self._built_arealocations[':nonpublic'] = private_area
self._built_excludables[':nonpublic'] = private_area
# add points inside arealocations to be able to route to its borders
for excludable in self._built_arealocations.values():

View file

@ -263,29 +263,26 @@ class GraphRoom():
return roomrouter
def _build_router(self, ctypes, public, nonpublic, avoid, include):
distances = np.amin(self.distances[ctypes, :, :], axis=0)
orig_distances = None
if include:
orig_distances = distances.copy()
distances = np.amin(self.distances[ctypes, :, :], axis=0).astype(np.float32)
factors = np.ones_like(distances, dtype=np.float16)
if ':public' in self.excludables and not public:
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:
points, = self.excludable_points[self.excludables.index(':private')].nonzero()
print(points)
distances[points[:, None], points] = np.inf
if ':nonpublic' in self.excludables and not nonpublic:
points, = self.excludable_points[self.excludables.index(':nonpublic')].nonzero()
factors[points[:, None], points] = np.inf
if avoid:
points, = self.excludable_points[avoid, :].any(axis=0).nonzero()
distances[points[:, None], points] *= 1000
points, = self.excludable_points[avoid].any(axis=0).nonzero()
factors[points[:, None], points] = 1000
if include:
points, = self.excludable_points[include, :].any(axis=0).nonzero()
distances[points[:, None], points] = orig_distances[points[:, None], points]
points, = self.excludable_points[include].any(axis=0).nonzero()
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)
return RoomRouter(shortest_paths, predecessors)

View file

@ -53,7 +53,6 @@ class Route:
@staticmethod
def describe_point(point):
print(point.arealocations)
locations = sorted(AreaLocation.objects.filter(location_type__in=('room', 'level', 'area'),
name__in=point.arealocations),
key=AreaLocation.get_sort_key, reverse=True)

View file

@ -53,7 +53,6 @@
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>

View file

@ -13,7 +13,7 @@
{% trans "Destination" as heading %}
{% include 'site/fragment_location.html' with name='destination' location=destination heading=heading %}
</div>
<div class="row">
<div class="row settings">
<div class="form-group col-md-2">
<label for="stairs-select">{% trans 'Stairs' %}</label>
<select name="stairs" id="stairs-select" class="form-control">
@ -42,8 +42,31 @@
</select>
</div>
<div class="form-group col-md-6">
<label for="elevators-select">{% trans 'Get Route' %}</label>
<button type="submit" id="submitbtn" class="btn btn-block btn-primary">{% trans 'Get Route' %}</button>
<label>{% trans 'Include / Avoid:' %}</label>
<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>
</form>

View file

@ -7,6 +7,7 @@ from PIL import Image, ImageDraw
from c3nav.mapdata.models import Level
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.utils.misc import get_dimensions
from c3nav.routing.graph import Graph
@ -35,6 +36,8 @@ def main(request, origin=None, destination=None):
if destination is None:
raise Http404
excludables, includables = get_excludables_includables()
route = None
if request.method in ('GET', 'POST') and origin and destination:
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('elevator', request.POST.get('elevators'))
route = graph.get_route(origin, destination, allowed_ctypes,
public=True, nonpublic=False, avoid=(), include=())
include = request.POST.getlist('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.create_routeparts()
@ -67,6 +79,10 @@ def main(request, origin=None, destination=None):
return render(request, 'site/main.html', {
'origin': origin,
'destination': destination,
'excludables': excludables.items(),
'includables': includables.items(),
'route': route,
'width': width,
'height': height,