Create new Location model structure

This commit is contained in:
Laura Klünder 2017-05-10 18:03:57 +02:00
parent e8e4e9fd40
commit 8290083fd4
18 changed files with 640 additions and 28 deletions

View file

@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 14: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', '0070_point'),
]
operations = [
migrations.CreateModel(
name='LocationSlug',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('slug', models.SlugField(unique=True, verbose_name='name')),
],
options={
'verbose_name': 'Slug for Location',
'verbose_name_plural': 'Slugs für Locations',
'default_related_name': 'locationslugs',
},
),
migrations.AddField(
model_name='area',
name='can_describe',
field=models.BooleanField(default=True, verbose_name='can be used to describe a position'),
),
migrations.AddField(
model_name='area',
name='can_search',
field=models.BooleanField(default=True, verbose_name='can be searched'),
),
migrations.AddField(
model_name='area',
name='color',
field=models.CharField(blank=True, help_text='if set, has to be a valid color for svg images', max_length=16, null=True, verbose_name='background color'),
),
migrations.AddField(
model_name='area',
name='groups',
field=models.ManyToManyField(blank=True, related_name='areas', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AddField(
model_name='area',
name='public',
field=models.BooleanField(default=True, verbose_name='public'),
),
migrations.AddField(
model_name='area',
name='titles',
field=c3nav.mapdata.fields.JSONField(default={}),
),
migrations.AddField(
model_name='locationgroup',
name='public',
field=models.BooleanField(default=True, verbose_name='public'),
),
migrations.AddField(
model_name='point',
name='can_describe',
field=models.BooleanField(default=True, verbose_name='can be used to describe a position'),
),
migrations.AddField(
model_name='point',
name='can_search',
field=models.BooleanField(default=True, verbose_name='can be searched'),
),
migrations.AddField(
model_name='point',
name='color',
field=models.CharField(blank=True, help_text='if set, has to be a valid color for svg images', max_length=16, null=True, verbose_name='background color'),
),
migrations.AddField(
model_name='point',
name='groups',
field=models.ManyToManyField(blank=True, related_name='points', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AddField(
model_name='point',
name='public',
field=models.BooleanField(default=True, verbose_name='public'),
),
migrations.AddField(
model_name='point',
name='titles',
field=c3nav.mapdata.fields.JSONField(default={}),
),
migrations.AddField(
model_name='section',
name='can_describe',
field=models.BooleanField(default=True, verbose_name='can be used to describe a position'),
),
migrations.AddField(
model_name='section',
name='can_search',
field=models.BooleanField(default=True, verbose_name='can be searched'),
),
migrations.AddField(
model_name='section',
name='color',
field=models.CharField(blank=True, help_text='if set, has to be a valid color for svg images', max_length=16, null=True, verbose_name='background color'),
),
migrations.AddField(
model_name='section',
name='groups',
field=models.ManyToManyField(blank=True, related_name='sections', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AddField(
model_name='section',
name='public',
field=models.BooleanField(default=True, verbose_name='public'),
),
migrations.AddField(
model_name='section',
name='titles',
field=c3nav.mapdata.fields.JSONField(default={}),
),
migrations.AddField(
model_name='space',
name='can_describe',
field=models.BooleanField(default=True, verbose_name='can be used to describe a position'),
),
migrations.AddField(
model_name='space',
name='can_search',
field=models.BooleanField(default=True, verbose_name='can be searched'),
),
migrations.AddField(
model_name='space',
name='color',
field=models.CharField(blank=True, help_text='if set, has to be a valid color for svg images', max_length=16, null=True, verbose_name='background color'),
),
migrations.AddField(
model_name='space',
name='groups',
field=models.ManyToManyField(blank=True, related_name='spaces', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AddField(
model_name='space',
name='titles',
field=c3nav.mapdata.fields.JSONField(default={}),
),
migrations.AlterField(
model_name='locationgroup',
name='titles',
field=c3nav.mapdata.fields.JSONField(default={}),
),
migrations.AddField(
model_name='area',
name='slug_ptr',
field=models.OneToOneField(db_column='slug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='areas', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AddField(
model_name='locationgroup',
name='slug_ptr',
field=models.OneToOneField(db_column='slug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='locationgroups', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AddField(
model_name='point',
name='slug_ptr',
field=models.OneToOneField(db_column='slug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='points', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AddField(
model_name='section',
name='slug_ptr',
field=models.OneToOneField(db_column='slug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AddField(
model_name='space',
name='slug_ptr',
field=models.OneToOneField(db_column='slug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='spaces', to='mapdata.LocationSlug', verbose_name='location slug'),
),
]

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 15:40
from __future__ import unicode_literals
from django.db import migrations, models
def create_locationslugs(apps, schema_editor):
LocationSlug = apps.get_model('mapdata', 'LocationSlug')
for model in ('Section', 'Space', 'Area', 'Point', 'LocationGroup'):
Model = apps.get_model('mapdata', model)
for obj in Model.objects.all():
slug = LocationSlug.objects.create(slug=getattr(obj, 'slug', None))
obj.slug_ptr = slug
obj.save()
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0071_auto_20170510_1413'),
]
operations = [
migrations.AlterField(
model_name='locationslug',
name='slug',
field=models.SlugField(null=True, unique=True, verbose_name='name'),
),
migrations.RunPython(create_locationslugs),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 15:51
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0072_auto_20170510_1540'),
]
operations = [
migrations.RemoveField(
model_name='locationgroup',
name='slug',
),
]

View file

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 15:56
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0073_remove_locationgroup_slug'),
]
operations = [
migrations.AlterField(
model_name='area',
name='slug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='areas', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AlterField(
model_name='locationgroup',
name='slug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='locationgroups', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AlterField(
model_name='point',
name='slug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='points', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AlterField(
model_name='section',
name='slug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='mapdata.LocationSlug', verbose_name='location slug'),
),
migrations.AlterField(
model_name='space',
name='slug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='spaces', to='mapdata.LocationSlug', verbose_name='location slug'),
),
]

View file

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 15:57
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0074_auto_20170510_1556'),
]
operations = [
migrations.RenameField(
model_name='area',
old_name='slug_ptr',
new_name='locationslug_ptr',
),
migrations.RenameField(
model_name='locationgroup',
old_name='slug_ptr',
new_name='locationslug_ptr',
),
migrations.RenameField(
model_name='point',
old_name='slug_ptr',
new_name='locationslug_ptr',
),
migrations.RenameField(
model_name='section',
old_name='slug_ptr',
new_name='locationslug_ptr',
),
migrations.RenameField(
model_name='space',
old_name='slug_ptr',
new_name='locationslug_ptr',
),
]

View file

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:29
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0075_auto_20170510_1557'),
]
operations = [
migrations.RemoveField(
model_name='area',
name='id',
),
migrations.RemoveField(
model_name='point',
name='id',
),
migrations.RemoveField(
model_name='section',
name='id',
),
migrations.RemoveField(
model_name='space',
name='id',
),
migrations.AlterField(
model_name='area',
name='locationslug_ptr',
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='areas', serialize=False, to='mapdata.LocationSlug'),
),
migrations.AlterField(
model_name='locationgroup',
name='id',
field=models.AutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='locationgroup',
name='locationslug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', on_delete=django.db.models.deletion.CASCADE, related_name='locationgroups', to='mapdata.LocationSlug'),
),
migrations.AlterField(
model_name='point',
name='locationslug_ptr',
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='points', serialize=False, to='mapdata.LocationSlug'),
),
migrations.AlterField(
model_name='section',
name='locationslug_ptr',
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='sections', serialize=False, to='mapdata.LocationSlug'),
),
migrations.AlterField(
model_name='space',
name='locationslug_ptr',
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='spaces', serialize=False, to='mapdata.LocationSlug'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:37
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0076_auto_20170510_1629'),
]
operations = [
migrations.AlterField(
model_name='locationgroup',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:39
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0077_auto_20170510_1637'),
]
operations = [
migrations.RenameModel(
old_name='LocationGroup',
new_name='LegacyLocationGroup',
),
]

View file

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:41
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', '0078_auto_20170510_1639'),
]
operations = [
migrations.CreateModel(
name='LocationGroup',
fields=[
('locationslug_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='locationgroups', serialize=False, to='mapdata.LocationSlug')),
('titles', c3nav.mapdata.fields.JSONField(default={})),
('can_search', models.BooleanField(default=True, verbose_name='can be searched')),
('can_describe', models.BooleanField(default=True, verbose_name='can be used to describe a position')),
('color', models.CharField(blank=True, help_text='if set, has to be a valid color for svg images', max_length=16, null=True, verbose_name='background color')),
('public', models.BooleanField(default=True, verbose_name='public')),
('compiled_room', models.BooleanField(default=False, verbose_name='is a compiled room')),
],
options={
'verbose_name': 'Location Group',
'verbose_name_plural': 'Location Groups',
'default_related_name': 'locationgroups',
},
bases=('mapdata.locationslug', models.Model),
),
migrations.AlterField(
model_name='legacylocationgroup',
name='locationslug_ptr',
field=models.OneToOneField(db_column='locationslug_ptr', on_delete=django.db.models.deletion.CASCADE, related_name='legacylocationgroups', to='mapdata.LocationSlug'),
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:42
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0079_auto_20170510_1641'),
]
operations = [
migrations.RenameField(
model_name='arealocation',
old_name='groups',
new_name='legacygroups',
),
]

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0080_auto_20170510_1642'),
]
operations = [
migrations.AddField(
model_name='arealocation',
name='groups',
field=models.ManyToManyField(blank=True, related_name='arealocations', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
]

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:44
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0081_arealocation_groups'),
]
operations = [
migrations.AlterField(
model_name='area',
name='groups',
field=models.ManyToManyField(blank=True, related_name='areas', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AlterField(
model_name='point',
name='groups',
field=models.ManyToManyField(blank=True, related_name='points', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AlterField(
model_name='section',
name='groups',
field=models.ManyToManyField(blank=True, related_name='sections', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
migrations.AlterField(
model_name='space',
name='groups',
field=models.ManyToManyField(blank=True, related_name='spaces', to='mapdata.LocationGroup', verbose_name='Location Groups'),
),
]

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 16:45
from __future__ import unicode_literals
from django.db import migrations
def copy_locationgroups(apps, schema_editor):
LegacyLocationGroup = apps.get_model('mapdata', 'LegacyLocationGroup')
LocationGroup = apps.get_model('mapdata', 'LocationGroup')
for legacyobj in LegacyLocationGroup.objects.all():
obj = LocationGroup()
obj.slug = legacyobj.locationslug_ptr.slug
slug_ptr = legacyobj.locationslug_ptr
slug_ptr.slug = None
slug_ptr.save()
obj.titles = legacyobj.titles
obj.can_search = legacyobj.can_search
obj.can_describe = legacyobj.can_describe
obj.color = legacyobj.color
obj.public = legacyobj.public
obj.compiled_room = legacyobj.compiled_room
obj.save()
obj.arealocations.add(*legacyobj.arealocations.all())
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0082_auto_20170510_1644'),
]
operations = [
migrations.RunPython(copy_locationgroups),
]

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-10 17:01
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0083_auto_20170510_1645'),
]
operations = [
migrations.RemoveField(
model_name='legacylocationgroup',
name='locationslug_ptr',
),
migrations.RemoveField(
model_name='arealocation',
name='legacygroups',
),
migrations.DeleteModel(
name='LegacyLocationGroup',
),
]

View file

@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
from c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.geometry.base import GeometryMixin
from c3nav.mapdata.models.locations import SpecificLocation
SECTION_MODELS = OrderedDict()
@ -50,7 +51,7 @@ class Building(SectionGeometryMixin, models.Model):
default_related_name = 'buildings'
class Space(LevelSectionGeometryMixin, models.Model):
class Space(SpecificLocation, LevelSectionGeometryMixin, models.Model):
"""
An accessible space. Shouldn't overlap with spaces on same secion and level.
"""

View file

@ -6,6 +6,7 @@ from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
from c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.geometry.base import GeometryMixin
from c3nav.mapdata.models.locations import SpecificLocation
from c3nav.mapdata.utils.json import format_geojson
SPACE_MODELS = OrderedDict()
@ -23,7 +24,7 @@ class SpaceGeometryMixin(GeometryMixin):
return result
class Area(SpaceGeometryMixin, models.Model):
class Area(SpecificLocation, SpaceGeometryMixin, models.Model):
"""
An area in a space.
"""
@ -112,7 +113,7 @@ class LineObstacle(SpaceGeometryMixin, models.Model):
return result
class Point(SpaceGeometryMixin, models.Model):
class Point(SpecificLocation, SpaceGeometryMixin, models.Model):
"""
An point in a space.
"""

View file

@ -10,10 +10,51 @@ from django.utils.translation import ungettext_lazy
from c3nav.mapdata.fields import GeometryField, JSONField, validate_bssid_lines
from c3nav.mapdata.lastupdate import get_last_mapdata_update
from c3nav.mapdata.models.base import EditorFormMixin
from c3nav.mapdata.models.section import Section
class Location:
class LocationSlug(models.Model):
slug = models.SlugField(_('name'), unique=True, null=True, max_length=50)
class Meta:
verbose_name = _('Slug for Location')
verbose_name_plural = _('Slugs für Locations')
default_related_name = 'locationslugs'
class LocationModelMixin:
pass
class Location(LocationSlug, models.Model):
titles = JSONField(default={})
can_search = models.BooleanField(default=True, verbose_name=_('can be searched'))
can_describe = models.BooleanField(default=True, verbose_name=_('can be used to describe a position'))
color = models.CharField(null=True, blank=True, max_length=16, verbose_name=_('background color'),
help_text=_('if set, has to be a valid color for svg images'))
public = models.BooleanField(verbose_name=_('public'), default=True)
class Meta:
abstract = True
def get_geojson_properties(self):
result = super().get_geojson_properties()
result['slug'] = self.slug_ptr.slug
result['titles'] = OrderedDict(sorted(self.titles.items()))
return result
@property
def subtitle(self):
return self._meta.verbose_name
class SpecificLocation(Location, models.Model):
groups = models.ManyToManyField('mapdata.LocationGroup', verbose_name=_('Location Groups'), blank=True)
class Meta:
abstract = True
class LegacyLocation:
@property
def location_id(self):
raise NotImplementedError
@ -31,26 +72,7 @@ class Location:
))
# noinspection PyUnresolvedReferences
class LocationModelMixin(Location):
def get_geojson_properties(self):
result = super().get_geojson_properties()
result['slug'] = self.slug
result['titles'] = OrderedDict(sorted(self.titles.items()))
return result
@property
def subtitle(self):
return self._meta.verbose_name
class LocationGroup(LocationModelMixin, EditorFormMixin, models.Model):
slug = models.SlugField(_('Name'), unique=True, max_length=50)
titles = JSONField()
can_search = models.BooleanField(default=True, verbose_name=_('can be searched'))
can_describe = models.BooleanField(default=True, verbose_name=_('can be used to describe a position'))
color = models.CharField(null=True, blank=True, max_length=16, verbose_name=_('background color'),
help_text=_('if set, has to be a valid color for svg images'))
class LocationGroup(Location, EditorFormMixin, models.Model):
compiled_room = models.BooleanField(default=False, verbose_name=_('is a compiled room'))
class Meta:
@ -194,8 +216,8 @@ class AreaLocation(models.Model):
return self.title
class PointLocation(Location):
def __init__(self, section: Section, x: int, y: int, request):
class PointLocation(LegacyLocation):
def __init__(self, section: 'Section', x: int, y: int, request):
self.section = section
self.x = x
self.y = y

View file

@ -5,10 +5,11 @@ from shapely.geometry import CAP_STYLE, JOIN_STYLE
from shapely.ops import cascaded_union
from c3nav.mapdata.models.base import EditorFormMixin
from c3nav.mapdata.models.locations import SpecificLocation
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
class Section(EditorFormMixin, models.Model):
class Section(SpecificLocation, EditorFormMixin, models.Model):
"""
A map section like a level
"""