Features: store titles as a JSONField and add loadmap and dumpmap support

This commit is contained in:
Laura Klünder 2016-09-26 11:18:56 +02:00
parent 49c2270b84
commit be62b14669
11 changed files with 101 additions and 27 deletions

View file

@ -1,10 +1,13 @@
import os
from collections import OrderedDict, namedtuple
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import get_language
from shapely.geometry import mapping, shape
from ..fields import GeometryField
from c3nav.mapdata.utils import sort_geojson
from ..fields import GeometryField, JSONField
class FeatureType(namedtuple('FeatureType', ('name', 'title', 'title_plural', 'geomtype', 'color'))):
@ -38,28 +41,54 @@ class Feature(models.Model):
feature_type = models.CharField(max_length=50, choices=TYPES)
level = models.ForeignKey('mapdata.Level', on_delete=models.CASCADE, related_name='features',
verbose_name=_('level'))
titles = JSONField()
geometry = GeometryField()
path_regex = r'^features/('+'|'.join(name for name, title in TYPES)+')/'
@property
def titles(self):
return {title.language: title.title for title in self.featuretitles.all()}
@property
def title(self):
titles = self.titles
lang = get_language()
if lang in titles:
return titles[lang]
return next(iter(titles.values())) if titles else self.name
if lang in self.titles:
return self.titles[lang]
return next(iter(self.titles.values())) if self.titles else self.name
def tofilename(self):
return 'features/%s/%s.json' % (self.feature_type, self.name)
class FeatureTitle(models.Model):
feature = models.ForeignKey('Feature', on_delete=models.CASCADE, related_name='featuretitles',
verbose_name=_('map package'))
language = models.CharField(max_length=50)
title = models.CharField(max_length=50)
@classmethod
def fromfile(cls, data, file_path):
kwargs = {}
kwargs['feature_type'] = file_path.split(os.path.sep)[1]
class Meta:
unique_together = ('feature', 'language')
if 'geometry' not in data:
raise ValueError('missing geometry.')
try:
kwargs['geometry'] = shape(data['geometry'])
except:
raise ValueError(_('Invalid GeoJSON.'))
if 'level' not in data:
raise ValueError('missing level.')
kwargs['level'] = data['level']
if 'titles' not in data:
raise ValueError('missing titles.')
titles = data['titles']
if not isinstance(titles, dict):
raise ValueError('Invalid titles format.')
if any(not isinstance(lang, str) for lang in titles.keys()):
raise ValueError('titles: All languages have to be strings.')
if any(not isinstance(title, str) for title in titles.values()):
raise ValueError('titles: All titles have to be strings.')
if any(not title for title in titles.values()):
raise ValueError('titles: Titles must not be empty strings.')
kwargs['titles'] = titles
return kwargs
def tofile(self):
return OrderedDict((
('titles', OrderedDict(sorted(self.titles.items()))),
('level', self.level.name),
('geometry', sort_geojson(mapping(self.geometry)))
))