rename Level to Section
This commit is contained in:
parent
d1fe5bce5c
commit
c9661e4edb
22 changed files with 217 additions and 157 deletions
|
@ -7,10 +7,10 @@ from rest_framework.generics import GenericAPIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.routers import SimpleRouter
|
from rest_framework.routers import SimpleRouter
|
||||||
|
|
||||||
from c3nav.mapdata.api import GeometryTypeViewSet, GeometryViewSet, LevelViewSet, LocationViewSet, SourceViewSet
|
from c3nav.mapdata.api import GeometryTypeViewSet, GeometryViewSet, LocationViewSet, SectionViewSet, SourceViewSet
|
||||||
|
|
||||||
router = SimpleRouter()
|
router = SimpleRouter()
|
||||||
router.register(r'levels', LevelViewSet)
|
router.register(r'sections', SectionViewSet)
|
||||||
router.register(r'sources', SourceViewSet)
|
router.register(r'sources', SourceViewSet)
|
||||||
|
|
||||||
router.register(r'geometrytypes', GeometryTypeViewSet, base_name='geometrytype')
|
router.register(r'geometrytypes', GeometryTypeViewSet, base_name='geometrytype')
|
||||||
|
|
|
@ -22,22 +22,9 @@ class MapitemFormMixin(ModelForm):
|
||||||
if creating:
|
if creating:
|
||||||
self.fields['name'].initial = hex(int(time.time()*1000000))[2:]
|
self.fields['name'].initial = hex(int(time.time()*1000000))[2:]
|
||||||
|
|
||||||
if 'level' in self.fields:
|
if 'section' in self.fields:
|
||||||
# hide level widget and set field_name
|
# hide section widget
|
||||||
self.fields['level'].widget = HiddenInput()
|
self.fields['section'].widget = HiddenInput()
|
||||||
self.fields['level'].to_field_name = 'name'
|
|
||||||
if not creating:
|
|
||||||
self.initial['level'] = self.instance.level.name
|
|
||||||
|
|
||||||
if 'crop_to_level' in self.fields:
|
|
||||||
# set field_name
|
|
||||||
self.fields['crop_to_level'].to_field_name = 'name'
|
|
||||||
if not creating and self.instance.crop_to_level is not None:
|
|
||||||
self.initial['crop_to_level'] = self.instance.crop_to_level.name
|
|
||||||
|
|
||||||
if 'levels' in self.fields:
|
|
||||||
# set field_name
|
|
||||||
self.fields['levels'].to_field_name = 'name'
|
|
||||||
|
|
||||||
if 'groups' in self.fields:
|
if 'groups' in self.fields:
|
||||||
# set field_name
|
# set field_name
|
||||||
|
@ -66,12 +53,6 @@ class MapitemFormMixin(ModelForm):
|
||||||
initial=titles[language].strip(), max_length=50)
|
initial=titles[language].strip(), max_length=50)
|
||||||
self.titles = titles
|
self.titles = titles
|
||||||
|
|
||||||
def clean_levels(self):
|
|
||||||
levels = self.cleaned_data.get('levels')
|
|
||||||
if len(levels) < 2:
|
|
||||||
raise ValidationError(_('Please select at least two levels.'))
|
|
||||||
return levels
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if 'geometry' in self.fields:
|
if 'geometry' in self.fields:
|
||||||
if not self.cleaned_data.get('geometry'):
|
if not self.cleaned_data.get('geometry'):
|
||||||
|
|
|
@ -7,7 +7,7 @@ urlpatterns = [
|
||||||
url(r'^$', TemplateView.as_view(template_name='editor/map.html'), name='editor.index'),
|
url(r'^$', TemplateView.as_view(template_name='editor/map.html'), name='editor.index'),
|
||||||
url(r'^mapitemtypes/(?P<level>[^/]+)/$', list_mapitemtypes, name='editor.mapitemtypes'),
|
url(r'^mapitemtypes/(?P<level>[^/]+)/$', list_mapitemtypes, name='editor.mapitemtypes'),
|
||||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/$', list_mapitems, name='editor.mapitems'),
|
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/$', list_mapitems, name='editor.mapitems'),
|
||||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/(?P<level>[^/]+)/$', list_mapitems, name='editor.mapitems.level'),
|
url(r'^mapitems/(?P<mapitem_type>[^/]+)/list/(?P<sectionl>[0-9]+)/$', list_mapitems, name='editor.mapitems.level'),
|
||||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/add/$', edit_mapitem, name='editor.mapitems.add'),
|
url(r'^mapitems/(?P<mapitem_type>[^/]+)/add/$', edit_mapitem, name='editor.mapitems.add'),
|
||||||
url(r'^mapitems/(?P<mapitem_type>[^/]+)/edit/(?P<id>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
|
url(r'^mapitems/(?P<mapitem_type>[^/]+)/edit/(?P<id>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,54 +4,49 @@ from django.http.response import Http404
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
|
|
||||||
from c3nav.access.apply import can_access, filter_queryset_by_access
|
from c3nav.access.apply import can_access, filter_queryset_by_access
|
||||||
from c3nav.mapdata.models import AreaLocation, Level
|
from c3nav.mapdata.models import AreaLocation, Section
|
||||||
from c3nav.mapdata.models.base import FEATURE_TYPES
|
from c3nav.mapdata.models.base import FEATURE_TYPES
|
||||||
|
|
||||||
|
|
||||||
def list_mapitemtypes(request, level):
|
def list_mapitemtypes(request, section):
|
||||||
level = get_object_or_404()
|
section = get_object_or_404(Section, pk=section)
|
||||||
|
|
||||||
def get_item_count(mapitemtype):
|
def get_item_count(mapitemtype):
|
||||||
if hasattr(mapitemtype, 'level'):
|
if hasattr(mapitemtype, 'section'):
|
||||||
return filter_queryset_by_access(request, mapitemtype.objects.filter(level__name=level)).count()
|
return filter_queryset_by_access(request, mapitemtype.objects.filter(section=section)).count()
|
||||||
|
|
||||||
if hasattr(mapitemtype, 'levels'):
|
|
||||||
return filter_queryset_by_access(request, mapitemtype.objects.filter(levels__name=level)).count()
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return render(request, 'editor/mapitemtypes.html', {
|
return render(request, 'editor/mapitemtypes.html', {
|
||||||
'level': level,
|
'section': section,
|
||||||
'mapitemtypes': [
|
'mapitemtypes': [
|
||||||
{
|
{
|
||||||
'name': name,
|
'name': name,
|
||||||
'title': mapitemtype._meta.verbose_name_plural,
|
'title': mapitemtype._meta.verbose_name_plural,
|
||||||
'has_level': hasattr(mapitemtype, 'level') or hasattr(mapitemtype, 'levels'),
|
'has_section': hasattr(mapitemtype, 'section'),
|
||||||
'count': get_item_count(mapitemtype),
|
'count': get_item_count(mapitemtype),
|
||||||
} for name, mapitemtype in FEATURE_TYPES.items()
|
} for name, mapitemtype in FEATURE_TYPES.items()
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def list_mapitems(request, mapitem_type, level=None):
|
def list_mapitems(request, mapitem_type, section=None):
|
||||||
mapitemtype = FEATURE_TYPES.get(mapitem_type)
|
mapitemtype = FEATURE_TYPES.get(mapitem_type)
|
||||||
if mapitemtype is None:
|
if mapitemtype is None:
|
||||||
raise Http404('Unknown mapitemtype.')
|
raise Http404('Unknown mapitemtype.')
|
||||||
|
|
||||||
has_level = hasattr(mapitemtype, 'level') or hasattr(mapitemtype, 'levels')
|
has_section = hasattr(mapitemtype, 'section')
|
||||||
if has_level and level is None:
|
if has_section and section is None:
|
||||||
raise Http404('Missing level.')
|
raise Http404('Missing section.')
|
||||||
elif not has_level and level is not None:
|
elif not has_section and section is not None:
|
||||||
return redirect('editor.mapitems', mapitem_type=mapitem_type)
|
return redirect('editor.mapitems', mapitem_type=mapitem_type)
|
||||||
|
|
||||||
queryset = mapitemtype.objects.all().order_by('name')
|
queryset = mapitemtype.objects.all().order_by('name')
|
||||||
|
|
||||||
if level is not None:
|
if section is not None:
|
||||||
level = get_object_or_404(Level, level)
|
section = get_object_or_404(Section, section)
|
||||||
if hasattr(mapitemtype, 'level'):
|
if hasattr(mapitemtype, 'section'):
|
||||||
queryset = queryset.filter(level=level)
|
queryset = queryset.filter(section=section)
|
||||||
elif hasattr(mapitemtype, 'levels'):
|
|
||||||
queryset = queryset.filter(levels=level)
|
|
||||||
|
|
||||||
queryset = filter_queryset_by_access(request, queryset)
|
queryset = filter_queryset_by_access(request, queryset)
|
||||||
|
|
||||||
|
@ -61,12 +56,9 @@ def list_mapitems(request, mapitem_type, level=None):
|
||||||
return render(request, 'editor/mapitems.html', {
|
return render(request, 'editor/mapitems.html', {
|
||||||
'mapitem_type': mapitem_type,
|
'mapitem_type': mapitem_type,
|
||||||
'title': mapitemtype._meta.verbose_name_plural,
|
'title': mapitemtype._meta.verbose_name_plural,
|
||||||
'has_level': level is not None,
|
'has_section': section is not None,
|
||||||
'has_elevator': hasattr(mapitemtype, 'elevator'),
|
|
||||||
'has_levels': hasattr(mapitemtype, 'levels'),
|
|
||||||
'has_altitude': hasattr(mapitemtype, 'altitude'),
|
'has_altitude': hasattr(mapitemtype, 'altitude'),
|
||||||
'has_intermediate': hasattr(mapitemtype, 'intermediate'),
|
'section': section.id,
|
||||||
'level': level.id,
|
|
||||||
'items': queryset,
|
'items': queryset,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,18 @@ import mimetypes
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.http import Http404, HttpResponse, HttpResponseNotModified
|
from django.http import Http404, HttpResponse, HttpResponseNotModified
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
from rest_framework.decorators import detail_route, list_route
|
from rest_framework.decorators import detail_route, list_route
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
||||||
|
|
||||||
from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access
|
from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access
|
||||||
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
||||||
from c3nav.mapdata.models import AreaLocation, Level, LocationGroup, Source
|
from c3nav.mapdata.models import AreaLocation, LocationGroup, Source
|
||||||
from c3nav.mapdata.models.geometry.space import Stair
|
|
||||||
from c3nav.mapdata.models.geometry.base import GEOMETRY_FEATURE_TYPES
|
from c3nav.mapdata.models.geometry.base import GEOMETRY_FEATURE_TYPES
|
||||||
|
from c3nav.mapdata.models.geometry.space import Stair
|
||||||
|
from c3nav.mapdata.models.section import Section
|
||||||
from c3nav.mapdata.search import get_location
|
from c3nav.mapdata.search import get_location
|
||||||
from c3nav.mapdata.serializers.main import LevelSerializer, SourceSerializer
|
from c3nav.mapdata.serializers.main import SectionSerializer, SourceSerializer
|
||||||
from c3nav.mapdata.utils.cache import CachedReadOnlyViewSetMixin, cache_mapdata_api_response, get_bssid_areas_cached
|
from c3nav.mapdata.utils.cache import CachedReadOnlyViewSetMixin, cache_mapdata_api_response, get_bssid_areas_cached
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ class GeometryTypeViewSet(ViewSet):
|
||||||
class GeometryViewSet(ViewSet):
|
class GeometryViewSet(ViewSet):
|
||||||
"""
|
"""
|
||||||
List all geometries.
|
List all geometries.
|
||||||
You can filter by adding a level GET parameter.
|
|
||||||
"""
|
"""
|
||||||
def list(self, request):
|
def list(self, request):
|
||||||
types = set(request.GET.getlist('type'))
|
types = set(request.GET.getlist('type'))
|
||||||
|
@ -47,45 +46,25 @@ class GeometryViewSet(ViewSet):
|
||||||
else:
|
else:
|
||||||
types = [t for t in valid_types if t in types]
|
types = [t for t in valid_types if t in types]
|
||||||
|
|
||||||
level = None
|
|
||||||
if 'level' in request.GET:
|
|
||||||
level = get_object_or_404(Level, id=request.GET['level'])
|
|
||||||
|
|
||||||
cache_key = '__'.join((
|
cache_key = '__'.join((
|
||||||
','.join([str(i) for i in types]),
|
','.join([str(i) for i in types]),
|
||||||
str(level.id) if level is not None else '',
|
|
||||||
))
|
))
|
||||||
|
|
||||||
return self._list(request, types=types, level=level, add_cache_key=cache_key)
|
return self._list(request, types=types, add_cache_key=cache_key)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def compare_by_location_type(x: AreaLocation, y: AreaLocation):
|
def compare_by_location_type(x: AreaLocation, y: AreaLocation):
|
||||||
return AreaLocation.LOCATION_TYPES.index(x.location_type) - AreaLocation.LOCATION_TYPES.index(y.location_type)
|
return AreaLocation.LOCATION_TYPES.index(x.location_type) - AreaLocation.LOCATION_TYPES.index(y.location_type)
|
||||||
|
|
||||||
@cache_mapdata_api_response()
|
@cache_mapdata_api_response()
|
||||||
def _list(self, request, types, level):
|
def _list(self, request, types):
|
||||||
results = []
|
results = []
|
||||||
for t in types:
|
for t in types:
|
||||||
mapitemtype = GEOMETRY_FEATURE_TYPES[t]
|
mapitemtype = GEOMETRY_FEATURE_TYPES[t]
|
||||||
queryset = mapitemtype.objects.all()
|
queryset = mapitemtype.objects.all()
|
||||||
if level:
|
|
||||||
if hasattr(mapitemtype, 'level'):
|
|
||||||
queryset = queryset.filter(level=level)
|
|
||||||
elif hasattr(mapitemtype, 'levels'):
|
|
||||||
queryset = queryset.filter(levels=level)
|
|
||||||
else:
|
|
||||||
queryset = queryset.none()
|
|
||||||
queryset = filter_queryset_by_access(request, queryset)
|
queryset = filter_queryset_by_access(request, queryset)
|
||||||
queryset = queryset.order_by('id')
|
queryset = queryset.order_by('id')
|
||||||
|
|
||||||
for field_name in ('level', 'crop_to_level', 'elevator'):
|
|
||||||
if hasattr(mapitemtype, field_name):
|
|
||||||
queryset = queryset.select_related(field_name)
|
|
||||||
|
|
||||||
for field_name in ('levels', ):
|
|
||||||
if hasattr(mapitemtype, field_name):
|
|
||||||
queryset.prefetch_related(field_name)
|
|
||||||
|
|
||||||
if issubclass(mapitemtype, AreaLocation):
|
if issubclass(mapitemtype, AreaLocation):
|
||||||
queryset = sorted(queryset, key=AreaLocation.get_sort_key)
|
queryset = sorted(queryset, key=AreaLocation.get_sort_key)
|
||||||
|
|
||||||
|
@ -97,12 +76,12 @@ class GeometryViewSet(ViewSet):
|
||||||
return Response(results)
|
return Response(results)
|
||||||
|
|
||||||
|
|
||||||
class LevelViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
|
class SectionViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
List and retrieve levels.
|
List and retrieve sections.
|
||||||
"""
|
"""
|
||||||
queryset = Level.objects.all()
|
queryset = Section.objects.all()
|
||||||
serializer_class = LevelSerializer
|
serializer_class = SectionSerializer
|
||||||
lookup_field = 'id'
|
lookup_field = 'id'
|
||||||
|
|
||||||
|
|
||||||
|
|
19
src/c3nav/mapdata/migrations/0059_auto_20170507_0937.py
Normal file
19
src/c3nav/mapdata/migrations/0059_auto_20170507_0937.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-05-07 09:37
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0058_auto_20170506_1549'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameModel(
|
||||||
|
old_name='Level',
|
||||||
|
new_name='Section',
|
||||||
|
),
|
||||||
|
]
|
40
src/c3nav/mapdata/migrations/0060_auto_20170507_0952.py
Normal file
40
src/c3nav/mapdata/migrations/0060_auto_20170507_0952.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-05-07 09:52
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0059_auto_20170507_0937'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='arealocation',
|
||||||
|
old_name='level',
|
||||||
|
new_name='section',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='building',
|
||||||
|
old_name='level',
|
||||||
|
new_name='section',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='door',
|
||||||
|
old_name='level',
|
||||||
|
new_name='section',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='hole',
|
||||||
|
old_name='level',
|
||||||
|
new_name='section',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='space',
|
||||||
|
old_name='level',
|
||||||
|
new_name='section',
|
||||||
|
),
|
||||||
|
]
|
51
src/c3nav/mapdata/migrations/0061_auto_20170507_0953.py
Normal file
51
src/c3nav/mapdata/migrations/0061_auto_20170507_0953.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-05-07 09:53
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0060_auto_20170507_0952'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='arealocation',
|
||||||
|
name='section',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='arealocations', to='mapdata.Section', verbose_name='section'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='building',
|
||||||
|
name='section',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='buildings', to='mapdata.Section', verbose_name='section'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='door',
|
||||||
|
name='section',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doors', to='mapdata.Section', verbose_name='section'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hole',
|
||||||
|
name='section',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='holes', to='mapdata.Section', verbose_name='section'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='section',
|
||||||
|
name='altitude',
|
||||||
|
field=models.DecimalField(decimal_places=2, max_digits=6, unique=True, verbose_name='section altitude'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='section',
|
||||||
|
name='name',
|
||||||
|
field=models.SlugField(unique=True, verbose_name='section name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='space',
|
||||||
|
name='section',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='areas', to='mapdata.Section', verbose_name='section'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,3 +1,3 @@
|
||||||
from .level import Level # noqa
|
from .section import Section # noqa
|
||||||
from .source import Source # noqa
|
from .source import Source # noqa
|
||||||
from .locations import AreaLocation, LocationGroup # noqa
|
from .locations import AreaLocation, LocationGroup # noqa
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.base import ModelBase
|
from django.db.models.base import ModelBase
|
||||||
from django.utils.translation import get_language
|
from django.utils.translation import get_language
|
||||||
|
@ -38,5 +39,3 @@ class Feature(models.Model, metaclass=FeatureBase):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from shapely.geometry import mapping, Point
|
|
||||||
|
from shapely.geometry import Point, mapping
|
||||||
|
|
||||||
from c3nav.mapdata.fields import GeometryField
|
from c3nav.mapdata.fields import GeometryField
|
||||||
from c3nav.mapdata.models.base import Feature, FeatureBase
|
from c3nav.mapdata.models.base import Feature, FeatureBase
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureB
|
||||||
LEVEL_FEATURE_TYPES = OrderedDict()
|
LEVEL_FEATURE_TYPES = OrderedDict()
|
||||||
|
|
||||||
|
|
||||||
class LevelFeatureBase(GeometryFeatureBase):
|
class SectionFeatureBase(GeometryFeatureBase):
|
||||||
def __new__(mcs, name, bases, attrs):
|
def __new__(mcs, name, bases, attrs):
|
||||||
cls = super().__new__(mcs, name, bases, attrs)
|
cls = super().__new__(mcs, name, bases, attrs)
|
||||||
if not cls._meta.abstract:
|
if not cls._meta.abstract:
|
||||||
|
@ -15,22 +16,22 @@ class LevelFeatureBase(GeometryFeatureBase):
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
class LevelFeature(GeometryFeature, metaclass=LevelFeatureBase):
|
class SectionFeature(GeometryFeature, metaclass=SectionFeatureBase):
|
||||||
"""
|
"""
|
||||||
a map feature that has a geometry and belongs to a level
|
a map feature that has a geometry and belongs to a section
|
||||||
"""
|
"""
|
||||||
level = models.ForeignKey('mapdata.Level', on_delete=models.CASCADE, verbose_name=_('level'))
|
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
def get_geojson_properties(self):
|
def get_geojson_properties(self):
|
||||||
result = super().get_geojson_properties()
|
result = super().get_geojson_properties()
|
||||||
result['level'] = self.level.id
|
result['section'] = self.section.id
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Building(LevelFeature):
|
class Building(SectionFeature):
|
||||||
"""
|
"""
|
||||||
The outline of a building on a specific level
|
The outline of a building on a specific level
|
||||||
"""
|
"""
|
||||||
|
@ -42,7 +43,7 @@ class Building(LevelFeature):
|
||||||
default_related_name = 'buildings'
|
default_related_name = 'buildings'
|
||||||
|
|
||||||
|
|
||||||
class Space(LevelFeature):
|
class Space(SectionFeature):
|
||||||
"""
|
"""
|
||||||
An accessible space. Shouldn't overlap.
|
An accessible space. Shouldn't overlap.
|
||||||
"""
|
"""
|
||||||
|
@ -77,7 +78,7 @@ class Space(LevelFeature):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Door(LevelFeature):
|
class Door(SectionFeature):
|
||||||
"""
|
"""
|
||||||
A connection between two rooms
|
A connection between two rooms
|
||||||
"""
|
"""
|
||||||
|
@ -89,7 +90,7 @@ class Door(LevelFeature):
|
||||||
default_related_name = 'doors'
|
default_related_name = 'doors'
|
||||||
|
|
||||||
|
|
||||||
class Hole(LevelFeature):
|
class Hole(SectionFeature):
|
||||||
"""
|
"""
|
||||||
A hole in the ground of a room, e.g. for stairs.
|
A hole in the ground of a room, e.g. for stairs.
|
||||||
"""
|
"""
|
|
@ -1,12 +1,12 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from shapely.geometry import JOIN_STYLE, CAP_STYLE, mapping
|
from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
|
||||||
|
|
||||||
from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase
|
from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase
|
||||||
from c3nav.mapdata.utils.json import format_geojson
|
from c3nav.mapdata.utils.json import format_geojson
|
||||||
|
|
||||||
|
|
||||||
SPACE_FEATURE_TYPES = OrderedDict()
|
SPACE_FEATURE_TYPES = OrderedDict()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ from django.utils.translation import ungettext_lazy
|
||||||
|
|
||||||
from c3nav.mapdata.fields import JSONField, validate_bssid_lines
|
from c3nav.mapdata.fields import JSONField, validate_bssid_lines
|
||||||
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
||||||
from c3nav.mapdata.models import Level
|
|
||||||
from c3nav.mapdata.models.base import Feature
|
from c3nav.mapdata.models.base import Feature
|
||||||
from c3nav.mapdata.models.geometry.level import LevelFeature
|
from c3nav.mapdata.models.geometry.section import SectionFeature
|
||||||
|
from c3nav.mapdata.models.section import Section
|
||||||
|
|
||||||
|
|
||||||
class Location:
|
class Location:
|
||||||
|
@ -85,7 +85,7 @@ class LocationGroup(LocationModelMixin, Feature):
|
||||||
level_ids.add(area.id)
|
level_ids.add(area.id)
|
||||||
in_levels.append(area)
|
in_levels.append(area)
|
||||||
|
|
||||||
in_levels = sorted(in_levels, key=lambda area: area.level.altitude)
|
in_levels = sorted(in_levels, key=lambda area: area.section.altitude)
|
||||||
return in_levels
|
return in_levels
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -102,7 +102,7 @@ class LocationGroup(LocationModelMixin, Feature):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class AreaLocation(LocationModelMixin, LevelFeature):
|
class AreaLocation(LocationModelMixin, SectionFeature):
|
||||||
LOCATION_TYPES = (
|
LOCATION_TYPES = (
|
||||||
('level', _('Level')),
|
('level', _('Level')),
|
||||||
('area', _('General Area')),
|
('area', _('General Area')),
|
||||||
|
@ -162,7 +162,7 @@ class AreaLocation(LocationModelMixin, LevelFeature):
|
||||||
in_areas = []
|
in_areas = []
|
||||||
area_location_i = self.get_sort_key(self)
|
area_location_i = self.get_sort_key(self)
|
||||||
for location_type in reversed(self.LOCATION_TYPES_ORDER[:area_location_i]):
|
for location_type in reversed(self.LOCATION_TYPES_ORDER[:area_location_i]):
|
||||||
for arealocation in AreaLocation.objects.filter(location_type=location_type, level=self.level):
|
for arealocation in AreaLocation.objects.filter(location_type=location_type, section=self.section):
|
||||||
intersection_area = arealocation.geometry.intersection(self.geometry).area
|
intersection_area = arealocation.geometry.intersection(self.geometry).area
|
||||||
if intersection_area and intersection_area / my_area > 0.99:
|
if intersection_area and intersection_area / my_area > 0.99:
|
||||||
in_areas.append(arealocation)
|
in_areas.append(arealocation)
|
||||||
|
@ -196,15 +196,15 @@ class AreaLocation(LocationModelMixin, LevelFeature):
|
||||||
|
|
||||||
|
|
||||||
class PointLocation(Location):
|
class PointLocation(Location):
|
||||||
def __init__(self, level: Level, x: int, y: int, request):
|
def __init__(self, section: Section, x: int, y: int, request):
|
||||||
self.level = level
|
self.section = section
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def location_id(self):
|
def location_id(self):
|
||||||
return 'c:%s:%d:%d' % (self.level.name, self.x*100, self.y*100)
|
return 'c:%d:%d:%d' % (self.section.id, self.x * 100, self.y * 100)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def xy(self):
|
def xy(self):
|
||||||
|
@ -214,7 +214,7 @@ class PointLocation(Location):
|
||||||
def description(self):
|
def description(self):
|
||||||
from c3nav.routing.graph import Graph
|
from c3nav.routing.graph import Graph
|
||||||
graph = Graph.load()
|
graph = Graph.load()
|
||||||
point = graph.get_nearest_point(self.level, self.x, self.y)
|
point = graph.get_nearest_point(self.section, self.x, self.y)
|
||||||
|
|
||||||
if point is None or (':nonpublic' in point.arealocations and not self.request.c3nav_full_access and
|
if point is None or (':nonpublic' in point.arealocations and not self.request.c3nav_full_access and
|
||||||
not len(set(self.request.c3nav_access_list) & set(point.arealocations))):
|
not len(set(self.request.c3nav_access_list) & set(point.arealocations))):
|
||||||
|
@ -239,14 +239,14 @@ class PointLocation(Location):
|
||||||
@property
|
@property
|
||||||
def subtitle(self) -> str:
|
def subtitle(self) -> str:
|
||||||
add_subtitle = self.description[1]
|
add_subtitle = self.description[1]
|
||||||
subtitle = '%s:%d:%d' % (self.level.name, self.x*100, self.y*100)
|
subtitle = '%s:%d:%d' % (self.section.name, self.x * 100, self.y * 100)
|
||||||
if add_subtitle:
|
if add_subtitle:
|
||||||
subtitle += ' - '+add_subtitle
|
subtitle += ' - '+add_subtitle
|
||||||
return subtitle
|
return subtitle
|
||||||
|
|
||||||
def to_location_json(self):
|
def to_location_json(self):
|
||||||
result = super().to_location_json()
|
result = super().to_location_json()
|
||||||
result['level'] = self.level.name
|
result['section'] = self.section.id
|
||||||
result['x'] = self.x
|
result['x'] = self.x
|
||||||
result['y'] = self.y
|
result['y'] = self.y
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -8,18 +8,17 @@ from c3nav.mapdata.models.base import Feature
|
||||||
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
|
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
|
||||||
|
|
||||||
|
|
||||||
class Level(Feature):
|
class Section(Feature):
|
||||||
"""
|
"""
|
||||||
A map level (-1, 0, 1, 2…)
|
A map section like a level
|
||||||
"""
|
"""
|
||||||
name = models.SlugField(_('level name'), unique=True, max_length=50,
|
name = models.SlugField(_('section name'), unique=True, max_length=50)
|
||||||
help_text=_('Usually just an integer (e.g. -1, 0, 1, 2)'))
|
altitude = models.DecimalField(_('section altitude'), null=False, unique=True, max_digits=6, decimal_places=2)
|
||||||
altitude = models.DecimalField(_('level altitude'), null=False, unique=True, max_digits=6, decimal_places=2)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Level')
|
verbose_name = _('Section')
|
||||||
verbose_name_plural = _('Levels')
|
verbose_name_plural = _('Sections')
|
||||||
default_related_name = 'levels'
|
default_related_name = 'sections'
|
||||||
ordering = ['altitude']
|
ordering = ['altitude']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -27,35 +26,35 @@ class Level(Feature):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def public_geometries(self):
|
def public_geometries(self):
|
||||||
return LevelGeometries.by_level(self, only_public=True)
|
return SectionGeometries.by_section(self, only_public=True)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def geometries(self):
|
def geometries(self):
|
||||||
return LevelGeometries.by_level(self, only_public=False)
|
return SectionGeometries.by_section(self, only_public=False)
|
||||||
|
|
||||||
def lower(self):
|
def lower(self):
|
||||||
return Level.objects.filter(altitude__lt=self.altitude).order_by('altitude')
|
return Section.objects.filter(altitude__lt=self.altitude).order_by('altitude')
|
||||||
|
|
||||||
def higher(self):
|
def higher(self):
|
||||||
return Level.objects.filter(altitude__gt=self.altitude).order_by('altitude')
|
return Section.objects.filter(altitude__gt=self.altitude).order_by('altitude')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class LevelGeometries():
|
class SectionGeometries():
|
||||||
by_level_name = {}
|
by_section_id = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def by_level(cls, level, only_public=True):
|
def by_section(cls, section, only_public=True):
|
||||||
return cls.by_level_name.setdefault((level.name, only_public), cls(level, only_public=only_public))
|
return cls.by_section_id.setdefault((section.id, only_public), cls(section, only_public=only_public))
|
||||||
|
|
||||||
def __init__(self, level, only_public=True):
|
def __init__(self, section, only_public=True):
|
||||||
self.level = level
|
self.section = section
|
||||||
self.only_public = only_public
|
self.only_public = only_public
|
||||||
|
|
||||||
def query(self, name):
|
def query(self, name):
|
||||||
queryset = getattr(self.level, name)
|
queryset = getattr(self.section, name)
|
||||||
if not self.only_public:
|
if not self.only_public:
|
||||||
return queryset.all()
|
return queryset.all()
|
||||||
return queryset.filter(public=True)
|
return queryset.filter(public=True)
|
||||||
|
@ -67,7 +66,7 @@ class LevelGeometries():
|
||||||
@cached_property
|
@cached_property
|
||||||
def buildings(self):
|
def buildings(self):
|
||||||
result = cascaded_union([building.geometry for building in self.query('buildings')])
|
result = cascaded_union([building.geometry for building in self.query('buildings')])
|
||||||
if self.level.intermediate:
|
if self.section.intermediate:
|
||||||
result = cascaded_union([result, self.raw_rooms])
|
result = cascaded_union([result, self.raw_rooms])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -181,7 +180,7 @@ class LevelGeometries():
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def intermediate_shadows(self):
|
def intermediate_shadows(self):
|
||||||
qs = self.query('levelconnectors').prefetch_related('levels').filter(levels__altitude__lt=self.level.altitude)
|
qs = self.query('levelconnectors').prefetch_related('levels').filter(levels__altitude__lt=self.section.altitude)
|
||||||
connectors = cascaded_union([levelconnector.geometry for levelconnector in qs])
|
connectors = cascaded_union([levelconnector.geometry for levelconnector in qs])
|
||||||
shadows = self.buildings.difference(connectors.buffer(0.4, join_style=JOIN_STYLE.mitre))
|
shadows = self.buildings.difference(connectors.buffer(0.4, join_style=JOIN_STYLE.mitre))
|
||||||
shadows = shadows.buffer(0.3)
|
shadows = shadows.buffer(0.3)
|
||||||
|
@ -192,7 +191,7 @@ class LevelGeometries():
|
||||||
holes = self.holes.buffer(0.1, join_style=JOIN_STYLE.mitre)
|
holes = self.holes.buffer(0.1, join_style=JOIN_STYLE.mitre)
|
||||||
shadows = holes.difference(self.holes.buffer(-0.3, join_style=JOIN_STYLE.mitre))
|
shadows = holes.difference(self.holes.buffer(-0.3, join_style=JOIN_STYLE.mitre))
|
||||||
|
|
||||||
qs = self.query('levelconnectors').prefetch_related('levels').filter(levels__altitude__lt=self.level.altitude)
|
qs = self.query('levelconnectors').prefetch_related('levels').filter(levels__altitude__lt=self.section.altitude)
|
||||||
connectors = cascaded_union([levelconnector.geometry for levelconnector in qs])
|
connectors = cascaded_union([levelconnector.geometry for levelconnector in qs])
|
||||||
|
|
||||||
shadows = shadows.difference(connectors.buffer(1.0, join_style=JOIN_STYLE.mitre))
|
shadows = shadows.difference(connectors.buffer(1.0, join_style=JOIN_STYLE.mitre))
|
|
@ -1,11 +1,11 @@
|
||||||
from c3nav.mapdata.models import Level
|
from c3nav.mapdata.models.section import Section
|
||||||
from c3nav.mapdata.render.renderer import LevelRenderer # noqa
|
from c3nav.mapdata.render.renderer import LevelRenderer # noqa
|
||||||
|
|
||||||
|
|
||||||
def render_all_levels(show_accessibles=False):
|
def render_all_levels(show_accessibles=False):
|
||||||
|
|
||||||
renderers = []
|
renderers = []
|
||||||
for level in Level.objects.all():
|
for level in Section.objects.all():
|
||||||
renderers.append(LevelRenderer(level, only_public=False))
|
renderers.append(LevelRenderer(level, only_public=False))
|
||||||
renderers.append(LevelRenderer(level, only_public=True))
|
renderers.append(LevelRenderer(level, only_public=True))
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,17 @@ from django.db.models import Q
|
||||||
from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access
|
from c3nav.access.apply import filter_arealocations_by_access, filter_queryset_by_access
|
||||||
from c3nav.mapdata.models import AreaLocation, LocationGroup
|
from c3nav.mapdata.models import AreaLocation, LocationGroup
|
||||||
from c3nav.mapdata.models.locations import PointLocation
|
from c3nav.mapdata.models.locations import PointLocation
|
||||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
from c3nav.mapdata.utils.cache import get_sections_cached
|
||||||
|
|
||||||
|
|
||||||
def get_location(request, location_id):
|
def get_location(request, location_id):
|
||||||
match = re.match('^c:(?P<level>[a-z0-9-_]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', location_id)
|
match = re.match('^c:(?P<section>[0-9]+):(?P<x>[0-9]+):(?P<y>[0-9]+)$', location_id)
|
||||||
if match:
|
if match:
|
||||||
levels = get_levels_cached()
|
levels = get_sections_cached()
|
||||||
level = levels.get(match.group('level'))
|
section = levels.get(int(match.group('section')))
|
||||||
if level is None:
|
if section is None:
|
||||||
return None
|
return None
|
||||||
return PointLocation(level=level, x=int(match.group('x'))/100, y=int(match.group('y'))/100, request=request)
|
return PointLocation(section=section, x=int(match.group('x')) / 100, y=int(match.group('y')) / 100, request=request)
|
||||||
|
|
||||||
if location_id.startswith('g:'):
|
if location_id.startswith('g:'):
|
||||||
queryset = LocationGroup.objects.filter(Q(slug=location_id[2:], can_search=True))
|
queryset = LocationGroup.objects.filter(Q(slug=location_id[2:], can_search=True))
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from c3nav.mapdata.models import Level, Source
|
from c3nav.mapdata.models.section import Section
|
||||||
|
from c3nav.mapdata.models.source import Source
|
||||||
|
|
||||||
|
|
||||||
class LevelSerializer(serializers.ModelSerializer):
|
class SectionSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Level
|
model = Section
|
||||||
fields = ('id', 'name', 'altitude')
|
fields = ('id', 'name', 'altitude')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -81,10 +81,10 @@ class CachedReadOnlyViewSetMixin():
|
||||||
return super().retrieve(request, *args, **kwargs)
|
return super().retrieve(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@cache_result('c3nav__mapdata__levels')
|
@cache_result('c3nav__mapdata__sections')
|
||||||
def get_levels_cached():
|
def get_sections_cached():
|
||||||
from c3nav.mapdata.models import Level
|
from c3nav.mapdata.models.section import Section
|
||||||
return OrderedDict((level.name, level) for level in Level.objects.all())
|
return OrderedDict((section.id, section) for section in Section.objects.all())
|
||||||
|
|
||||||
|
|
||||||
@cache_result('c3nav__mapdata__bssids')
|
@cache_result('c3nav__mapdata__bssids')
|
||||||
|
|
|
@ -8,8 +8,8 @@ from django.conf import settings
|
||||||
from scipy.sparse.csgraph._shortest_path import shortest_path
|
from scipy.sparse.csgraph._shortest_path import shortest_path
|
||||||
from scipy.sparse.csgraph._tools import csgraph_from_dense
|
from scipy.sparse.csgraph._tools import csgraph_from_dense
|
||||||
|
|
||||||
from c3nav.mapdata.models import Level
|
|
||||||
from c3nav.mapdata.models.locations import AreaLocation, Location, LocationGroup, PointLocation
|
from c3nav.mapdata.models.locations import AreaLocation, Location, LocationGroup, PointLocation
|
||||||
|
from c3nav.mapdata.models.section import Section
|
||||||
from c3nav.routing.connection import GraphConnection
|
from c3nav.routing.connection import GraphConnection
|
||||||
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
|
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
|
||||||
from c3nav.routing.level import GraphLevel
|
from c3nav.routing.level import GraphLevel
|
||||||
|
@ -27,7 +27,7 @@ class Graph:
|
||||||
def __init__(self, mtime=None):
|
def __init__(self, mtime=None):
|
||||||
self.mtime = mtime
|
self.mtime = mtime
|
||||||
self.levels = OrderedDict()
|
self.levels = OrderedDict()
|
||||||
for level in Level.objects.all():
|
for level in Section.objects.all():
|
||||||
self.levels[level.name] = GraphLevel(self, level)
|
self.levels[level.name] = GraphLevel(self, level)
|
||||||
|
|
||||||
self.points = []
|
self.points = []
|
||||||
|
@ -245,7 +245,7 @@ class Graph:
|
||||||
|
|
||||||
def get_location_points(self, location: Location, mode):
|
def get_location_points(self, location: Location, mode):
|
||||||
if isinstance(location, PointLocation):
|
if isinstance(location, PointLocation):
|
||||||
points = self.levels[location.level.name].connected_points(np.array((location.x, location.y)), mode)
|
points = self.levels[location.section.name].connected_points(np.array((location.x, location.y)), mode)
|
||||||
if not points:
|
if not points:
|
||||||
return (), None, None
|
return (), None, None
|
||||||
points, distances, ctypes = zip(*((point, distance, ctype) for point, (distance, ctype) in points.items()))
|
points, distances, ctypes = zip(*((point, distance, ctype) for point, (distance, ctype) in points.items()))
|
||||||
|
|
|
@ -10,9 +10,9 @@ from django.utils import timezone
|
||||||
from c3nav.access.apply import get_visible_areas
|
from c3nav.access.apply import get_visible_areas
|
||||||
from c3nav.mapdata.inclusion import get_includables_avoidables, parse_include_avoid
|
from c3nav.mapdata.inclusion import get_includables_avoidables, parse_include_avoid
|
||||||
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
from c3nav.mapdata.lastupdate import get_last_mapdata_update
|
||||||
from c3nav.mapdata.models import Level
|
from c3nav.mapdata.models.section import Section
|
||||||
from c3nav.mapdata.search import get_location, search_location
|
from c3nav.mapdata.search import get_location, search_location
|
||||||
from c3nav.mapdata.utils.cache import get_levels_cached
|
from c3nav.mapdata.utils.cache import get_sections_cached
|
||||||
from c3nav.mapdata.utils.misc import get_dimensions, get_render_path
|
from c3nav.mapdata.utils.misc import get_dimensions, get_render_path
|
||||||
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
|
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
|
||||||
from c3nav.routing.graph import Graph
|
from c3nav.routing.graph import Graph
|
||||||
|
@ -92,18 +92,18 @@ def main(request, location=None, origin=None, destination=None):
|
||||||
}
|
}
|
||||||
|
|
||||||
width, height = get_dimensions()
|
width, height = get_dimensions()
|
||||||
levels = tuple(name for name, level in get_levels_cached().items() if not level.intermediate)
|
sections = tuple(section for id_, section in get_sections_cached().items())
|
||||||
|
|
||||||
ctx.update({
|
ctx.update({
|
||||||
'width': width,
|
'width': width,
|
||||||
'height': height,
|
'height': height,
|
||||||
'svg_width': int(width * 6),
|
'svg_width': int(width * 6),
|
||||||
'svg_height': int(height * 6),
|
'svg_height': int(height * 6),
|
||||||
'levels': levels,
|
'sections': sections,
|
||||||
})
|
})
|
||||||
|
|
||||||
map_level = request.GET.get('map-level')
|
map_level = request.GET.get('map-level')
|
||||||
if map_level in levels:
|
if map_level in sections:
|
||||||
ctx.update({
|
ctx.update({
|
||||||
'map_level': map_level
|
'map_level': map_level
|
||||||
})
|
})
|
||||||
|
@ -238,7 +238,7 @@ def main(request, location=None, origin=None, destination=None):
|
||||||
|
|
||||||
|
|
||||||
def map_image(request, area, level):
|
def map_image(request, area, level):
|
||||||
level = get_object_or_404(Level, name=level, intermediate=False)
|
level = get_object_or_404(Section, name=level, intermediate=False)
|
||||||
if area == ':base':
|
if area == ':base':
|
||||||
img = get_render_path('png', level.name, 'full', True)
|
img = get_render_path('png', level.name, 'full', True)
|
||||||
elif area == ':full':
|
elif area == ':full':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue