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.utils.translation import ugettext_lazy as _
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 c3nav.mapdata.utils.geometry import clean_geometry
@ -26,6 +26,18 @@ def validate_geometry(geometry):
class GeometryField(models.TextField):
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):
if value is None:
return value
@ -35,6 +47,10 @@ class GeometryField(models.TextField):
return clean_geometry(shape(json.loads(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)))

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

View file

@ -3,6 +3,7 @@ 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
LEVEL_FEATURE_TYPES = OrderedDict()
@ -35,7 +36,7 @@ class Building(SectionFeature):
"""
The outline of a building on a specific level
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
class Meta:
verbose_name = _('Building')
@ -47,7 +48,7 @@ class Space(SectionFeature):
"""
An accessible space. Shouldn't overlap.
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
CATEGORIES = (
('', _('normal')),
@ -82,7 +83,7 @@ class Door(SectionFeature):
"""
A connection between two rooms
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
class Meta:
verbose_name = _('Door')
@ -94,7 +95,7 @@ class Hole(SectionFeature):
"""
A hole in the ground of a room, e.g. for stairs.
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
class Meta:
verbose_name = _('Hole')

View file

@ -4,6 +4,7 @@ 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.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
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
class Meta:
verbose_name = _('Stuffed Area')
@ -49,7 +50,7 @@ class Stair(SpaceFeature):
"""
A stair
"""
geomtype = 'polyline'
geometry = GeometryField('polyline')
class Meta:
verbose_name = _('Stair')
@ -83,7 +84,7 @@ class Obstacle(SpaceFeature):
"""
An obstacle
"""
geomtype = 'polygon'
geometry = GeometryField('polygon')
class Meta:
verbose_name = _('Obstacle')
@ -95,10 +96,9 @@ class LineObstacle(SpaceFeature):
"""
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)
geomtype = 'polyline'
class Meta:
verbose_name = _('Line Obstacle')
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 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.models.base import Feature
from c3nav.mapdata.models.geometry.section import SectionFeature
@ -118,6 +118,7 @@ class AreaLocation(LocationModelMixin, SectionFeature):
('needs_permission', _('Excluded, needs permission to include')),
)
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'))
titles = JSONField()
@ -132,8 +133,6 @@ class AreaLocation(LocationModelMixin, SectionFeature):
verbose_name=_('Routing Inclusion'))
bssids = models.TextField(blank=True, validators=[validate_bssid_lines], verbose_name=_('BSSIDs'))
geomtype = 'polygon'
class Meta:
verbose_name = _('Area Location')
verbose_name_plural = _('Area Locations')