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.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):
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -54,6 +54,5 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue