rename Level to Section

This commit is contained in:
Laura Klünder 2017-05-07 12:06:13 +02:00
parent d1fe5bce5c
commit c9661e4edb
22 changed files with 217 additions and 157 deletions

View file

@ -7,10 +7,10 @@ from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
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.register(r'levels', LevelViewSet)
router.register(r'sections', SectionViewSet)
router.register(r'sources', SourceViewSet)
router.register(r'geometrytypes', GeometryTypeViewSet, base_name='geometrytype')

View file

@ -22,22 +22,9 @@ class MapitemFormMixin(ModelForm):
if creating:
self.fields['name'].initial = hex(int(time.time()*1000000))[2:]
if 'level' in self.fields:
# hide level widget and set field_name
self.fields['level'].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 'section' in self.fields:
# hide section widget
self.fields['section'].widget = HiddenInput()
if 'groups' in self.fields:
# set field_name
@ -66,12 +53,6 @@ class MapitemFormMixin(ModelForm):
initial=titles[language].strip(), max_length=50)
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):
if 'geometry' in self.fields:
if not self.cleaned_data.get('geometry'):

View file

@ -7,7 +7,7 @@ urlpatterns = [
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'^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>[^/]+)/edit/(?P<id>[^/]+)/$', edit_mapitem, name='editor.mapitems.edit'),
]

View file

@ -4,54 +4,49 @@ from django.http.response import Http404
from django.shortcuts import get_object_or_404, redirect, render
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
def list_mapitemtypes(request, level):
level = get_object_or_404()
def list_mapitemtypes(request, section):
section = get_object_or_404(Section, pk=section)
def get_item_count(mapitemtype):
if hasattr(mapitemtype, 'level'):
return filter_queryset_by_access(request, mapitemtype.objects.filter(level__name=level)).count()
if hasattr(mapitemtype, 'levels'):
return filter_queryset_by_access(request, mapitemtype.objects.filter(levels__name=level)).count()
if hasattr(mapitemtype, 'section'):
return filter_queryset_by_access(request, mapitemtype.objects.filter(section=section)).count()
return 0
return render(request, 'editor/mapitemtypes.html', {
'level': level,
'section': section,
'mapitemtypes': [
{
'name': name,
'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),
} 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)
if mapitemtype is None:
raise Http404('Unknown mapitemtype.')
has_level = hasattr(mapitemtype, 'level') or hasattr(mapitemtype, 'levels')
if has_level and level is None:
raise Http404('Missing level.')
elif not has_level and level is not None:
has_section = hasattr(mapitemtype, 'section')
if has_section and section is None:
raise Http404('Missing section.')
elif not has_section and section is not None:
return redirect('editor.mapitems', mapitem_type=mapitem_type)
queryset = mapitemtype.objects.all().order_by('name')
if level is not None:
level = get_object_or_404(Level, level)
if hasattr(mapitemtype, 'level'):
queryset = queryset.filter(level=level)
elif hasattr(mapitemtype, 'levels'):
queryset = queryset.filter(levels=level)
if section is not None:
section = get_object_or_404(Section, section)
if hasattr(mapitemtype, 'section'):
queryset = queryset.filter(section=section)
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', {
'mapitem_type': mapitem_type,
'title': mapitemtype._meta.verbose_name_plural,
'has_level': level is not None,
'has_elevator': hasattr(mapitemtype, 'elevator'),
'has_levels': hasattr(mapitemtype, 'levels'),
'has_section': section is not None,
'has_altitude': hasattr(mapitemtype, 'altitude'),
'has_intermediate': hasattr(mapitemtype, 'intermediate'),
'level': level.id,
'section': section.id,
'items': queryset,
})

View file

@ -4,18 +4,18 @@ import mimetypes
from collections import OrderedDict
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.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
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.models import AreaLocation, Level, LocationGroup, Source
from c3nav.mapdata.models.geometry.space import Stair
from c3nav.mapdata.models import AreaLocation, LocationGroup, Source
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.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
@ -37,7 +37,6 @@ class GeometryTypeViewSet(ViewSet):
class GeometryViewSet(ViewSet):
"""
List all geometries.
You can filter by adding a level GET parameter.
"""
def list(self, request):
types = set(request.GET.getlist('type'))
@ -47,45 +46,25 @@ class GeometryViewSet(ViewSet):
else:
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((
','.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
def compare_by_location_type(x: AreaLocation, y: AreaLocation):
return AreaLocation.LOCATION_TYPES.index(x.location_type) - AreaLocation.LOCATION_TYPES.index(y.location_type)
@cache_mapdata_api_response()
def _list(self, request, types, level):
def _list(self, request, types):
results = []
for t in types:
mapitemtype = GEOMETRY_FEATURE_TYPES[t]
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 = 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):
queryset = sorted(queryset, key=AreaLocation.get_sort_key)
@ -97,12 +76,12 @@ class GeometryViewSet(ViewSet):
return Response(results)
class LevelViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
class SectionViewSet(CachedReadOnlyViewSetMixin, ReadOnlyModelViewSet):
"""
List and retrieve levels.
List and retrieve sections.
"""
queryset = Level.objects.all()
serializer_class = LevelSerializer
queryset = Section.objects.all()
serializer_class = SectionSerializer
lookup_field = 'id'

View 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',
),
]

View 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',
),
]

View 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'),
),
]

View file

@ -1,3 +1,3 @@
from .level import Level # noqa
from .section import Section # noqa
from .source import Source # noqa
from .locations import AreaLocation, LocationGroup # noqa

View file

@ -1,4 +1,5 @@
from collections import OrderedDict
from django.db import models
from django.db.models.base import ModelBase
from django.utils.translation import get_language
@ -38,5 +39,3 @@ class Feature(models.Model, metaclass=FeatureBase):
class Meta:
abstract = True

View file

@ -1,3 +0,0 @@

View file

@ -1,5 +1,6 @@
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.models.base import Feature, FeatureBase

View file

@ -1,4 +1,5 @@
from collections import OrderedDict
from django.db import models
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()
class LevelFeatureBase(GeometryFeatureBase):
class SectionFeatureBase(GeometryFeatureBase):
def __new__(mcs, name, bases, attrs):
cls = super().__new__(mcs, name, bases, attrs)
if not cls._meta.abstract:
@ -15,22 +16,22 @@ class LevelFeatureBase(GeometryFeatureBase):
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:
abstract = True
def get_geojson_properties(self):
result = super().get_geojson_properties()
result['level'] = self.level.id
result['section'] = self.section.id
return result
class Building(LevelFeature):
class Building(SectionFeature):
"""
The outline of a building on a specific level
"""
@ -42,7 +43,7 @@ class Building(LevelFeature):
default_related_name = 'buildings'
class Space(LevelFeature):
class Space(SectionFeature):
"""
An accessible space. Shouldn't overlap.
"""
@ -77,7 +78,7 @@ class Space(LevelFeature):
return result
class Door(LevelFeature):
class Door(SectionFeature):
"""
A connection between two rooms
"""
@ -89,7 +90,7 @@ class Door(LevelFeature):
default_related_name = 'doors'
class Hole(LevelFeature):
class Hole(SectionFeature):
"""
A hole in the ground of a room, e.g. for stairs.
"""

View file

@ -1,12 +1,12 @@
from collections import OrderedDict
from django.db import models
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.utils.json import format_geojson
SPACE_FEATURE_TYPES = OrderedDict()

View file

@ -9,9 +9,9 @@ from django.utils.translation import ungettext_lazy
from c3nav.mapdata.fields import JSONField, validate_bssid_lines
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.geometry.level import LevelFeature
from c3nav.mapdata.models.geometry.section import SectionFeature
from c3nav.mapdata.models.section import Section
class Location:
@ -85,7 +85,7 @@ class LocationGroup(LocationModelMixin, Feature):
level_ids.add(area.id)
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
@property
@ -102,7 +102,7 @@ class LocationGroup(LocationModelMixin, Feature):
return result
class AreaLocation(LocationModelMixin, LevelFeature):
class AreaLocation(LocationModelMixin, SectionFeature):
LOCATION_TYPES = (
('level', _('Level')),
('area', _('General Area')),
@ -162,7 +162,7 @@ class AreaLocation(LocationModelMixin, LevelFeature):
in_areas = []
area_location_i = self.get_sort_key(self)
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
if intersection_area and intersection_area / my_area > 0.99:
in_areas.append(arealocation)
@ -196,15 +196,15 @@ class AreaLocation(LocationModelMixin, LevelFeature):
class PointLocation(Location):
def __init__(self, level: Level, x: int, y: int, request):
self.level = level
def __init__(self, section: Section, x: int, y: int, request):
self.section = section
self.x = x
self.y = y
self.request = request
@cached_property
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
def xy(self):
@ -214,7 +214,7 @@ class PointLocation(Location):
def description(self):
from c3nav.routing.graph import Graph
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
not len(set(self.request.c3nav_access_list) & set(point.arealocations))):
@ -239,14 +239,14 @@ class PointLocation(Location):
@property
def subtitle(self) -> str:
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:
subtitle += ' - '+add_subtitle
return subtitle
def to_location_json(self):
result = super().to_location_json()
result['level'] = self.level.name
result['section'] = self.section.id
result['x'] = self.x
result['y'] = self.y
return result

View file

@ -8,18 +8,17 @@ from c3nav.mapdata.models.base import Feature
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,
help_text=_('Usually just an integer (e.g. -1, 0, 1, 2)'))
altitude = models.DecimalField(_('level altitude'), null=False, unique=True, max_digits=6, decimal_places=2)
name = models.SlugField(_('section name'), unique=True, max_length=50)
altitude = models.DecimalField(_('section altitude'), null=False, unique=True, max_digits=6, decimal_places=2)
class Meta:
verbose_name = _('Level')
verbose_name_plural = _('Levels')
default_related_name = 'levels'
verbose_name = _('Section')
verbose_name_plural = _('Sections')
default_related_name = 'sections'
ordering = ['altitude']
def __init__(self, *args, **kwargs):
@ -27,35 +26,35 @@ class Level(Feature):
@cached_property
def public_geometries(self):
return LevelGeometries.by_level(self, only_public=True)
return SectionGeometries.by_section(self, only_public=True)
@cached_property
def geometries(self):
return LevelGeometries.by_level(self, only_public=False)
return SectionGeometries.by_section(self, only_public=False)
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):
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):
return self.name
class LevelGeometries():
by_level_name = {}
class SectionGeometries():
by_section_id = {}
@classmethod
def by_level(cls, level, only_public=True):
return cls.by_level_name.setdefault((level.name, only_public), cls(level, only_public=only_public))
def by_section(cls, section, only_public=True):
return cls.by_section_id.setdefault((section.id, only_public), cls(section, only_public=only_public))
def __init__(self, level, only_public=True):
self.level = level
def __init__(self, section, only_public=True):
self.section = section
self.only_public = only_public
def query(self, name):
queryset = getattr(self.level, name)
queryset = getattr(self.section, name)
if not self.only_public:
return queryset.all()
return queryset.filter(public=True)
@ -67,7 +66,7 @@ class LevelGeometries():
@cached_property
def buildings(self):
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])
return result
@ -181,7 +180,7 @@ class LevelGeometries():
@cached_property
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])
shadows = self.buildings.difference(connectors.buffer(0.4, join_style=JOIN_STYLE.mitre))
shadows = shadows.buffer(0.3)
@ -192,7 +191,7 @@ class LevelGeometries():
holes = self.holes.buffer(0.1, 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])
shadows = shadows.difference(connectors.buffer(1.0, join_style=JOIN_STYLE.mitre))

View file

@ -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
def render_all_levels(show_accessibles=False):
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=True))

View file

@ -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.mapdata.models import AreaLocation, LocationGroup
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):
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:
levels = get_levels_cached()
level = levels.get(match.group('level'))
if level is None:
levels = get_sections_cached()
section = levels.get(int(match.group('section')))
if section is 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:'):
queryset = LocationGroup.objects.filter(Q(slug=location_id[2:], can_search=True))

View file

@ -1,11 +1,12 @@
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:
model = Level
model = Section
fields = ('id', 'name', 'altitude')

View file

@ -81,10 +81,10 @@ class CachedReadOnlyViewSetMixin():
return super().retrieve(request, *args, **kwargs)
@cache_result('c3nav__mapdata__levels')
def get_levels_cached():
from c3nav.mapdata.models import Level
return OrderedDict((level.name, level) for level in Level.objects.all())
@cache_result('c3nav__mapdata__sections')
def get_sections_cached():
from c3nav.mapdata.models.section import Section
return OrderedDict((section.id, section) for section in Section.objects.all())
@cache_result('c3nav__mapdata__bssids')

View file

@ -8,8 +8,8 @@ from django.conf import settings
from scipy.sparse.csgraph._shortest_path import shortest_path
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.section import Section
from c3nav.routing.connection import GraphConnection
from c3nav.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
from c3nav.routing.level import GraphLevel
@ -27,7 +27,7 @@ class Graph:
def __init__(self, mtime=None):
self.mtime = mtime
self.levels = OrderedDict()
for level in Level.objects.all():
for level in Section.objects.all():
self.levels[level.name] = GraphLevel(self, level)
self.points = []
@ -245,7 +245,7 @@ class Graph:
def get_location_points(self, location: Location, mode):
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:
return (), None, None
points, distances, ctypes = zip(*((point, distance, ctype) for point, (distance, ctype) in points.items()))

View file

@ -10,9 +10,9 @@ from django.utils import timezone
from c3nav.access.apply import get_visible_areas
from c3nav.mapdata.inclusion import get_includables_avoidables, parse_include_avoid
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.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.routing.exceptions import AlreadyThere, NoRouteFound, NotYetRoutable
from c3nav.routing.graph import Graph
@ -92,18 +92,18 @@ def main(request, location=None, origin=None, destination=None):
}
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({
'width': width,
'height': height,
'svg_width': int(width * 6),
'svg_height': int(height * 6),
'levels': levels,
'sections': sections,
})
map_level = request.GET.get('map-level')
if map_level in levels:
if map_level in sections:
ctx.update({
'map_level': map_level
})
@ -238,7 +238,7 @@ def main(request, location=None, origin=None, destination=None):
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':
img = get_render_path('png', level.name, 'full', True)
elif area == ':full':