turn abstract models into mixins

This commit is contained in:
Laura Klünder 2017-05-08 16:40:22 +02:00
parent 9e79ca74ae
commit 963694395e
8 changed files with 33 additions and 87 deletions

View file

@ -9,15 +9,7 @@ from c3nav.mapdata.lastupdate import set_last_mapdata_update
FEATURE_TYPES = OrderedDict()
class FeatureBase(ModelBase):
def __new__(mcs, name, bases, attrs):
cls = super().__new__(mcs, name, bases, attrs)
if not cls._meta.abstract and name != 'Source':
FEATURE_TYPES[name.lower()] = cls
return cls
class Feature(models.Model, metaclass=FeatureBase):
class EditorFormMixin():
EditorForm = None
@property
@ -28,14 +20,3 @@ class Feature(models.Model, metaclass=FeatureBase):
if lang in self.titles:
return self.titles[lang]
return next(iter(self.titles.values())) if self.titles else self.name
def save(self, *args, **kwargs):
with set_last_mapdata_update():
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
with set_last_mapdata_update():
super().delete(*args, **kwargs)
class Meta:
abstract = True

View file

@ -0,0 +1 @@
from c3nav.mapdata.models.geometry.section import Space # noqa

View file

@ -1,25 +1,16 @@
from collections import OrderedDict
from shapely.geometry import Point, mapping
from c3nav.mapdata.models.base import Feature, FeatureBase
from c3nav.mapdata.models.base import EditorFormMixin
from c3nav.mapdata.utils.json import format_geojson
GEOMETRY_FEATURE_TYPES = OrderedDict()
class GeometryFeatureBase(FeatureBase):
def __new__(mcs, name, bases, attrs):
cls = super().__new__(mcs, name, bases, attrs)
if not cls._meta.abstract:
GEOMETRY_FEATURE_TYPES[name.lower()] = cls
return cls
class GeometryFeature(Feature, metaclass=GeometryFeatureBase):
class GeometryMixin(EditorFormMixin):
"""
A map feature with a geometry
"""
class Meta:
abstract = True

View file

@ -1,41 +1,25 @@
from collections import OrderedDict
from django.db import models
from django.utils.translation import ugettext_lazy as _
from c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase
from c3nav.mapdata.models.geometry.base import GeometryMixin
LEVEL_FEATURE_TYPES = OrderedDict()
class SectionFeatureBase(GeometryFeatureBase):
def __new__(mcs, name, bases, attrs):
cls = super().__new__(mcs, name, bases, attrs)
if not cls._meta.abstract:
LEVEL_FEATURE_TYPES[name.lower()] = cls
return cls
class SectionFeature(GeometryFeature, metaclass=SectionFeatureBase):
"""
a map feature that has a geometry and belongs to a section
"""
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
class Meta:
abstract = True
class SectionGeometryMixin(GeometryMixin):
def get_geojson_properties(self):
result = super().get_geojson_properties()
result['section'] = self.section.id
return result
class Building(SectionFeature):
class Building(SectionGeometryMixin, models.Model):
"""
The outline of a building on a specific level
"""
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
geometry = GeometryField('polygon')
class Meta:
@ -44,10 +28,11 @@ class Building(SectionFeature):
default_related_name = 'buildings'
class Space(SectionFeature):
class Space(SectionGeometryMixin, models.Model):
"""
An accessible space. Shouldn't overlap.
"""
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
geometry = GeometryField('polygon')
CATEGORIES = (
@ -79,10 +64,11 @@ class Space(SectionFeature):
return result
class Door(SectionFeature):
class Door(SectionGeometryMixin, models.Model):
"""
A connection between two rooms
"""
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
geometry = GeometryField('polygon')
class Meta:
@ -91,10 +77,11 @@ class Door(SectionFeature):
default_related_name = 'doors'
class Hole(SectionFeature):
class Hole(SectionGeometryMixin, models.Model):
"""
A hole in the ground of a room, e.g. for stairs.
"""
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
geometry = GeometryField('polygon')
class Meta:

View file

@ -1,43 +1,27 @@
from collections import OrderedDict
from django.db import models
from django.utils.translation import ugettext_lazy as _
from shapely.geometry import CAP_STYLE, JOIN_STYLE, mapping
from c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase
from c3nav.mapdata.models.geometry.base import GeometryMixin
from c3nav.mapdata.utils.json import format_geojson
SPACE_FEATURE_TYPES = OrderedDict()
class SpaceFeatureBase(GeometryFeatureBase):
def __new__(mcs, name, bases, attrs):
cls = super().__new__(mcs, name, bases, attrs)
if not cls._meta.abstract:
SPACE_FEATURE_TYPES[name.lower()] = cls
return cls
class SpaceFeature(GeometryFeature, metaclass=SpaceFeatureBase):
"""
a map feature that has a geometry and belongs to a space
"""
space = models.ForeignKey('mapdata.Space', on_delete=models.CASCADE, verbose_name=_('space'))
class Meta:
abstract = True
class SpaceGeometryMixin(GeometryMixin):
def get_geojson_properties(self):
result = super().get_geojson_properties()
result['space'] = self.space.id
return result
class StuffedArea(SpaceFeature):
class StuffedArea(SpaceGeometryMixin, models.Model):
"""
A slow area with many tables or similar. Avoid it from routing by slowing it a bit down
"""
space = models.ForeignKey('mapdata.Space', on_delete=models.CASCADE, verbose_name=_('space'))
geometry = GeometryField('polygon')
class Meta:
@ -46,10 +30,11 @@ class StuffedArea(SpaceFeature):
default_related_name = 'stuffedareas'
class Stair(SpaceFeature):
class Stair(SpaceGeometryMixin, models.Model):
"""
A stair
"""
space = models.ForeignKey('mapdata.Space', on_delete=models.CASCADE, verbose_name=_('space'))
geometry = GeometryField('polyline')
class Meta:
@ -80,10 +65,11 @@ class Stair(SpaceFeature):
))
class Obstacle(SpaceFeature):
class Obstacle(SpaceGeometryMixin, models.Model):
"""
An obstacle
"""
space = models.ForeignKey('mapdata.Space', on_delete=models.CASCADE, verbose_name=_('space'))
geometry = GeometryField('polygon')
class Meta:
@ -92,10 +78,11 @@ class Obstacle(SpaceFeature):
default_related_name = 'obstacles'
class LineObstacle(SpaceFeature):
class LineObstacle(SpaceGeometryMixin, models.Model):
"""
An obstacle that is a line with a specific width
"""
space = models.ForeignKey('mapdata.Space', on_delete=models.CASCADE, verbose_name=_('space'))
geometry = GeometryField('polyline')
width = models.DecimalField(_('obstacle width'), max_digits=4, decimal_places=2, default=0.15)

View file

@ -1,6 +1,5 @@
from collections import OrderedDict
import numpy as np
from collections import OrderedDict
from django.core.cache import cache
from django.db import models
from django.utils.functional import cached_property
@ -9,8 +8,7 @@ from django.utils.translation import ungettext_lazy
from c3nav.mapdata.fields import JSONField, validate_bssid_lines, GeometryField
from c3nav.mapdata.lastupdate import get_last_mapdata_update
from c3nav.mapdata.models.base import Feature
from c3nav.mapdata.models.geometry.section import SectionFeature
from c3nav.mapdata.models.base import EditorFormMixin
from c3nav.mapdata.models.section import Section
@ -45,7 +43,7 @@ class LocationModelMixin(Location):
return self._meta.verbose_name
class LocationGroup(LocationModelMixin, Feature):
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'))
@ -102,7 +100,7 @@ class LocationGroup(LocationModelMixin, Feature):
return result
class AreaLocation(LocationModelMixin, SectionFeature):
class AreaLocation(models.Model):
LOCATION_TYPES = (
('level', _('Level')),
('area', _('General Area')),
@ -118,6 +116,7 @@ class AreaLocation(LocationModelMixin, SectionFeature):
('needs_permission', _('Excluded, needs permission to include')),
)
section = models.ForeignKey('mapdata.Section', on_delete=models.CASCADE, verbose_name=_('section'))
geometry = GeometryField('polygon')
slug = models.SlugField(_('Name'), unique=True, max_length=50)
location_type = models.CharField(max_length=20, choices=LOCATION_TYPES, verbose_name=_('Location Type'))

View file

@ -4,11 +4,11 @@ from django.utils.translation import ugettext_lazy as _
from shapely.geometry import CAP_STYLE, JOIN_STYLE
from shapely.ops import cascaded_union
from c3nav.mapdata.models.base import Feature
from c3nav.mapdata.models.base import EditorFormMixin
from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon
class Section(Feature):
class Section(EditorFormMixin, models.Model):
"""
A map section like a level
"""

View file

@ -1,10 +1,10 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from c3nav.mapdata.models.base import Feature
from c3nav.mapdata.models.base import EditorFormMixin
class Source(Feature):
class Source(EditorFormMixin, models.Model):
"""
A map source, images of levels that can be useful as backgrounds for the map editor
"""