add geomtype to GeometryField and remove it from GeometryFeature
This commit is contained in:
parent
dcd7318204
commit
9e79ca74ae
6 changed files with 90 additions and 18 deletions
|
@ -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)))
|
||||||
|
|
||||||
|
|
||||||
|
|
61
src/c3nav/mapdata/migrations/0063_auto_20170508_1404.py
Normal file
61
src/c3nav/mapdata/migrations/0063_auto_20170508_1404.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue