add geomtype to GeometryField and remove it from GeometryFeature

This commit is contained in:
Laura Klünder 2017-05-08 16:05:44 +02:00
parent dcd7318204
commit 9e79ca74ae
6 changed files with 90 additions and 18 deletions

View file

@ -5,7 +5,7 @@ from django.core.validators import RegexValidator
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 import validation from shapely import validation
from shapely.geometry import mapping, shape from shapely.geometry import mapping, shape, Polygon, LineString
from shapely.geometry.base import BaseGeometry from shapely.geometry.base import BaseGeometry
from c3nav.mapdata.utils.geometry import clean_geometry from c3nav.mapdata.utils.geometry import clean_geometry
@ -26,6 +26,18 @@ def validate_geometry(geometry):
class GeometryField(models.TextField): class GeometryField(models.TextField):
default_validators = [validate_geometry] default_validators = [validate_geometry]
def __init__(self, geomtype=None, *args, **kwargs):
self.geomtype = geomtype
if geomtype not in (None, 'polygon', 'polyline'):
raise ValueError(_('GeometryField.geomtype has to be None, "polygon" or "polyline"'))
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if self.geomtype is not None:
kwargs['geomtype'] = self.geomtype
return name, path, args, kwargs
def from_db_value(self, value, expression, connection, context): def from_db_value(self, value, expression, connection, context):
if value is None: if value is None:
return value return value
@ -35,6 +47,10 @@ class GeometryField(models.TextField):
return clean_geometry(shape(json.loads(value))) return clean_geometry(shape(json.loads(value)))
def get_prep_value(self, value): def get_prep_value(self, value):
if self.geomtype == 'polygon' and not isinstance(value, Polygon):
raise TypeError(_('Expected Polygon instance, got %s instead.') % repr(value))
elif self.geomtype == 'polyline' and not isinstance(value, LineString):
raise TypeError(_('Expected LineString instance, got %s instead.') % repr(value))
return json.dumps(format_geojson(mapping(value))) return json.dumps(format_geojson(mapping(value)))

View file

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-08 14:04
from __future__ import unicode_literals
import c3nav.mapdata.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('mapdata', '0062_auto_20170508_1400'),
]
operations = [
migrations.AlterField(
model_name='arealocation',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='building',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='door',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='hole',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='lineobstacle',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polyline'),
),
migrations.AlterField(
model_name='obstacle',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='space',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
migrations.AlterField(
model_name='stair',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polyline'),
),
migrations.AlterField(
model_name='stuffedarea',
name='geometry',
field=c3nav.mapdata.fields.GeometryField(geomtype='polygon'),
),
]

View file

@ -1,8 +1,6 @@
from collections import OrderedDict from collections import OrderedDict
from shapely.geometry import Point, mapping from shapely.geometry import Point, mapping
from c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.base import Feature, FeatureBase from c3nav.mapdata.models.base import Feature, FeatureBase
from c3nav.mapdata.utils.json import format_geojson from c3nav.mapdata.utils.json import format_geojson
@ -21,9 +19,6 @@ class GeometryFeature(Feature, metaclass=GeometryFeatureBase):
""" """
A map feature with a geometry A map feature with a geometry
""" """
geometry = GeometryField()
geomtype = None
class Meta: class Meta:
abstract = True abstract = True

View file

@ -3,6 +3,7 @@ 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 c3nav.mapdata.fields import GeometryField
from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase from c3nav.mapdata.models.geometry.base import GeometryFeature, GeometryFeatureBase
LEVEL_FEATURE_TYPES = OrderedDict() LEVEL_FEATURE_TYPES = OrderedDict()
@ -35,7 +36,7 @@ class Building(SectionFeature):
""" """
The outline of a building on a specific level The outline of a building on a specific level
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
class Meta: class Meta:
verbose_name = _('Building') verbose_name = _('Building')
@ -47,7 +48,7 @@ class Space(SectionFeature):
""" """
An accessible space. Shouldn't overlap. An accessible space. Shouldn't overlap.
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
CATEGORIES = ( CATEGORIES = (
('', _('normal')), ('', _('normal')),
@ -82,7 +83,7 @@ class Door(SectionFeature):
""" """
A connection between two rooms A connection between two rooms
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
class Meta: class Meta:
verbose_name = _('Door') verbose_name = _('Door')
@ -94,7 +95,7 @@ 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.
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
class Meta: class Meta:
verbose_name = _('Hole') verbose_name = _('Hole')

View file

@ -4,6 +4,7 @@ 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 CAP_STYLE, JOIN_STYLE, mapping 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 GeometryFeature, GeometryFeatureBase
from c3nav.mapdata.utils.json import format_geojson from c3nav.mapdata.utils.json import format_geojson
@ -37,7 +38,7 @@ class StuffedArea(SpaceFeature):
""" """
A slow area with many tables or similar. Avoid it from routing by slowing it a bit down A slow area with many tables or similar. Avoid it from routing by slowing it a bit down
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
class Meta: class Meta:
verbose_name = _('Stuffed Area') verbose_name = _('Stuffed Area')
@ -49,7 +50,7 @@ class Stair(SpaceFeature):
""" """
A stair A stair
""" """
geomtype = 'polyline' geometry = GeometryField('polyline')
class Meta: class Meta:
verbose_name = _('Stair') verbose_name = _('Stair')
@ -83,7 +84,7 @@ class Obstacle(SpaceFeature):
""" """
An obstacle An obstacle
""" """
geomtype = 'polygon' geometry = GeometryField('polygon')
class Meta: class Meta:
verbose_name = _('Obstacle') verbose_name = _('Obstacle')
@ -95,10 +96,9 @@ class LineObstacle(SpaceFeature):
""" """
An obstacle that is a line with a specific width An obstacle that is a line with a specific width
""" """
geometry = GeometryField('polyline')
width = models.DecimalField(_('obstacle width'), max_digits=4, decimal_places=2, default=0.15) width = models.DecimalField(_('obstacle width'), max_digits=4, decimal_places=2, default=0.15)
geomtype = 'polyline'
class Meta: class Meta:
verbose_name = _('Line Obstacle') verbose_name = _('Line Obstacle')
verbose_name_plural = _('Line Obstacles') verbose_name_plural = _('Line Obstacles')

View file

@ -7,7 +7,7 @@ from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy 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, GeometryField
from c3nav.mapdata.lastupdate import get_last_mapdata_update from c3nav.mapdata.lastupdate import get_last_mapdata_update
from c3nav.mapdata.models.base import Feature from c3nav.mapdata.models.base import Feature
from c3nav.mapdata.models.geometry.section import SectionFeature from c3nav.mapdata.models.geometry.section import SectionFeature
@ -118,6 +118,7 @@ class AreaLocation(LocationModelMixin, SectionFeature):
('needs_permission', _('Excluded, needs permission to include')), ('needs_permission', _('Excluded, needs permission to include')),
) )
geometry = GeometryField('polygon')
slug = models.SlugField(_('Name'), unique=True, max_length=50) slug = models.SlugField(_('Name'), unique=True, max_length=50)
location_type = models.CharField(max_length=20, choices=LOCATION_TYPES, verbose_name=_('Location Type')) location_type = models.CharField(max_length=20, choices=LOCATION_TYPES, verbose_name=_('Location Type'))
titles = JSONField() titles = JSONField()
@ -132,8 +133,6 @@ class AreaLocation(LocationModelMixin, SectionFeature):
verbose_name=_('Routing Inclusion')) verbose_name=_('Routing Inclusion'))
bssids = models.TextField(blank=True, validators=[validate_bssid_lines], verbose_name=_('BSSIDs')) bssids = models.TextField(blank=True, validators=[validate_bssid_lines], verbose_name=_('BSSIDs'))
geomtype = 'polygon'
class Meta: class Meta:
verbose_name = _('Area Location') verbose_name = _('Area Location')
verbose_name_plural = _('Area Locations') verbose_name_plural = _('Area Locations')