add Obstacle and Door Features
This commit is contained in:
parent
0ffdde5492
commit
dd215e3f3d
5 changed files with 138 additions and 10 deletions
|
@ -8,7 +8,7 @@ from django.forms.widgets import HiddenInput
|
||||||
from shapely.geometry.geo import mapping
|
from shapely.geometry.geo import mapping
|
||||||
|
|
||||||
from c3nav.mapdata.models import Package
|
from c3nav.mapdata.models import Package
|
||||||
from c3nav.mapdata.models.features import Inside, Room
|
from c3nav.mapdata.models.features import Door, Inside, Obstacle, Room
|
||||||
from c3nav.mapdata.permissions import get_unlocked_packages
|
from c3nav.mapdata.permissions import get_unlocked_packages
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,3 +82,5 @@ def create_editor_form(feature_model, add_fields=None):
|
||||||
def create_editor_forms():
|
def create_editor_forms():
|
||||||
create_editor_form(Inside)
|
create_editor_form(Inside)
|
||||||
create_editor_form(Room)
|
create_editor_form(Room)
|
||||||
|
create_editor_form(Obstacle, ['height'])
|
||||||
|
create_editor_form(Door)
|
||||||
|
|
|
@ -5,8 +5,9 @@ from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
from rest_framework.viewsets import ReadOnlyModelViewSet, ViewSet
|
||||||
|
|
||||||
from c3nav.mapdata.models import FEATURE_TYPES
|
from c3nav.mapdata.models import FEATURE_TYPES
|
||||||
from c3nav.mapdata.models.features import Inside, Room
|
from c3nav.mapdata.models.features import Door, Inside, Obstacle, Room
|
||||||
from c3nav.mapdata.serializers.features import FeatureTypeSerializer, InsideSerializer, RoomSerializer
|
from c3nav.mapdata.serializers.features import (DoorSerializer, FeatureTypeSerializer, InsideSerializer,
|
||||||
|
ObstacleSerializer, RoomSerializer)
|
||||||
|
|
||||||
|
|
||||||
class FeatureTypeViewSet(ViewSet):
|
class FeatureTypeViewSet(ViewSet):
|
||||||
|
@ -58,3 +59,23 @@ class RoomViewSet(ReadOnlyModelViewSet):
|
||||||
serializer_class = RoomSerializer
|
serializer_class = RoomSerializer
|
||||||
lookup_field = 'name'
|
lookup_field = 'name'
|
||||||
lookup_value_regex = '[^/]+'
|
lookup_value_regex = '[^/]+'
|
||||||
|
|
||||||
|
|
||||||
|
class ObstacleViewSet(ReadOnlyModelViewSet):
|
||||||
|
"""
|
||||||
|
List and retrieve Obstcales
|
||||||
|
"""
|
||||||
|
queryset = Obstacle.objects.all()
|
||||||
|
serializer_class = ObstacleSerializer
|
||||||
|
lookup_field = 'name'
|
||||||
|
lookup_value_regex = '[^/]+'
|
||||||
|
|
||||||
|
|
||||||
|
class DoorViewSet(ReadOnlyModelViewSet):
|
||||||
|
"""
|
||||||
|
List and retrieve Doors
|
||||||
|
"""
|
||||||
|
queryset = Door.objects.all()
|
||||||
|
serializer_class = DoorSerializer
|
||||||
|
lookup_field = 'name'
|
||||||
|
lookup_value_regex = '[^/]+'
|
||||||
|
|
48
src/c3nav/mapdata/migrations/0002_door_obstacle.py
Normal file
48
src/c3nav/mapdata/migrations/0002_door_obstacle.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.2 on 2016-10-16 11:13
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import c3nav.mapdata.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mapdata', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Door',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.SlugField(unique=True, verbose_name='Name')),
|
||||||
|
('geometry', c3nav.mapdata.fields.GeometryField()),
|
||||||
|
('level', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doors', to='mapdata.Level', verbose_name='level')),
|
||||||
|
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doors', to='mapdata.Package', verbose_name='map package')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name_plural': 'Doors',
|
||||||
|
'verbose_name': 'Door',
|
||||||
|
'default_related_name': 'doors',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Obstacle',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.SlugField(unique=True, verbose_name='Name')),
|
||||||
|
('geometry', c3nav.mapdata.fields.GeometryField()),
|
||||||
|
('height', models.DecimalField(decimal_places=2, max_digits=4, null=True, verbose_name='height of the obstacle')),
|
||||||
|
('level', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='obstacles', to='mapdata.Level', verbose_name='level')),
|
||||||
|
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='obstacles', to='mapdata.Package', verbose_name='map package')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name_plural': 'Obstacles',
|
||||||
|
'verbose_name': 'Obstacle',
|
||||||
|
'default_related_name': 'obstacles',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -82,3 +82,50 @@ class Room(Feature):
|
||||||
verbose_name = _('Room')
|
verbose_name = _('Room')
|
||||||
verbose_name_plural = _('Rooms')
|
verbose_name_plural = _('Rooms')
|
||||||
default_related_name = 'rooms'
|
default_related_name = 'rooms'
|
||||||
|
|
||||||
|
|
||||||
|
@register_featuretype
|
||||||
|
class Obstacle(Feature):
|
||||||
|
"""
|
||||||
|
An obstacle
|
||||||
|
"""
|
||||||
|
height = models.DecimalField(_('height of the obstacle'), null=True, max_digits=4, decimal_places=2)
|
||||||
|
|
||||||
|
geomtype = 'polygon'
|
||||||
|
color = '#999999'
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Obstacle')
|
||||||
|
verbose_name_plural = _('Obstacles')
|
||||||
|
default_related_name = 'obstacles'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def fromfile(cls, data, file_path):
|
||||||
|
kwargs = super().fromfile(data, file_path)
|
||||||
|
|
||||||
|
if 'height' in data:
|
||||||
|
if not isinstance(data['height'], (int, float)):
|
||||||
|
raise ValueError('altitude has to be int or float.')
|
||||||
|
kwargs['height'] = data['height']
|
||||||
|
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def tofile(self):
|
||||||
|
result = super().tofile()
|
||||||
|
if self.height is not None:
|
||||||
|
result['height'] = float(self.level.name)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@register_featuretype
|
||||||
|
class Door(Feature):
|
||||||
|
"""
|
||||||
|
A connection between two rooms
|
||||||
|
"""
|
||||||
|
geomtype = 'polygon'
|
||||||
|
color = '#FF00FF'
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Door')
|
||||||
|
verbose_name_plural = _('Doors')
|
||||||
|
default_related_name = 'doors'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from c3nav.mapdata.models.features import Inside, Room
|
from c3nav.mapdata.models.features import Door, Inside, Obstacle, Room
|
||||||
from c3nav.mapdata.serializers.fields import GeometryField
|
from c3nav.mapdata.serializers.fields import GeometryField
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,21 +25,31 @@ class FeatureTypeSerializer(serializers.Serializer):
|
||||||
return obj._meta.default_related_name
|
return obj._meta.default_related_name
|
||||||
|
|
||||||
|
|
||||||
class InsideSerializer(serializers.ModelSerializer):
|
class FeatureSerializer(serializers.ModelSerializer):
|
||||||
level = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
level = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
||||||
package = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
package = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
||||||
geometry = GeometryField()
|
geometry = GeometryField()
|
||||||
|
|
||||||
|
|
||||||
|
class InsideSerializer(FeatureSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Inside
|
model = Inside
|
||||||
fields = ('name', 'level', 'package', 'geometry')
|
fields = ('name', 'level', 'package', 'geometry')
|
||||||
|
|
||||||
|
|
||||||
class RoomSerializer(serializers.ModelSerializer):
|
class RoomSerializer(FeatureSerializer):
|
||||||
level = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
|
||||||
package = serializers.SlugRelatedField(slug_field='name', read_only=True)
|
|
||||||
geometry = GeometryField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Room
|
model = Room
|
||||||
fields = ('name', 'level', 'package', 'geometry')
|
fields = ('name', 'level', 'package', 'geometry')
|
||||||
|
|
||||||
|
|
||||||
|
class ObstacleSerializer(FeatureSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Obstacle
|
||||||
|
fields = ('name', 'level', 'package', 'geometry')
|
||||||
|
|
||||||
|
|
||||||
|
class DoorSerializer(FeatureSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Door
|
||||||
|
fields = ('name', 'level', 'package', 'geometry')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue