add simple_geometry to location api

This commit is contained in:
Laura Klünder 2017-10-28 21:36:52 +02:00
parent f83b77ed8b
commit 5fe03c4c8e
5 changed files with 30 additions and 12 deletions

View file

@ -17,6 +17,7 @@ from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet, ViewSe
from c3nav.mapdata.models import AccessRestriction, Building, Door, Hole, LocationGroup, MapUpdate, Source, Space from c3nav.mapdata.models import AccessRestriction, Building, Door, Hole, LocationGroup, MapUpdate, Source, Space
from c3nav.mapdata.models.access import AccessPermission from c3nav.mapdata.models.access import AccessPermission
from c3nav.mapdata.models.geometry.base import GeometryMixin
from c3nav.mapdata.models.geometry.level import LevelGeometryMixin from c3nav.mapdata.models.geometry.level import LevelGeometryMixin
from c3nav.mapdata.models.geometry.space import POI, Area, Column, LineObstacle, Obstacle, SpaceGeometryMixin, Stair from c3nav.mapdata.models.geometry.space import POI, Area, Column, LineObstacle, Obstacle, SpaceGeometryMixin, Stair
from c3nav.mapdata.models.level import Level from c3nav.mapdata.models.level import Level
@ -300,10 +301,14 @@ class LocationViewSet(RetrieveModelMixin, GenericViewSet):
for obj in queryset: for obj in queryset:
# noinspection PyStatementEffect # noinspection PyStatementEffect
obj.subtitle, obj.order obj.subtitle, obj.order
if isinstance(obj, GeometryMixin):
# noinspection PyStatementEffect
obj.centroid
cache.set(queryset_cache_key, queryset, 300) cache.set(queryset_cache_key, queryset, 300)
result = tuple(obj.serialize(include_type=True, detailed=detailed, geometry=geometry) for obj in queryset) result = tuple(obj.serialize(include_type=True, detailed=detailed, geometry=geometry, simple_geometry=True)
for obj in queryset)
cache.set(cache_key, result, 300) cache.set(cache_key, result, 300)
return Response(result) return Response(result)

View file

@ -1,6 +1,8 @@
import math
from collections import OrderedDict from collections import OrderedDict
from django.db import models from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from shapely.geometry import Point, mapping from shapely.geometry import Point, mapping
@ -59,16 +61,25 @@ class GeometryMixin(SerializableMixin):
result['geomtype'] = cls._meta.get_field('geometry').geomtype result['geomtype'] = cls._meta.get_field('geometry').geomtype
return result return result
@cached_property
def centroid(self):
return self.geometry.centroid
def serialize(self, geometry=True, **kwargs): def serialize(self, geometry=True, **kwargs):
result = super().serialize(geometry=geometry, **kwargs) result = super().serialize(geometry=geometry, **kwargs)
if geometry: if geometry:
result.move_to_end('geometry') result.move_to_end('geometry')
return result return result
def _serialize(self, geometry=True, **kwargs): def _serialize(self, geometry=True, simple_geometry=False, **kwargs):
result = super()._serialize(**kwargs) result = super()._serialize(simple_geometry=simple_geometry, **kwargs)
if geometry: if geometry:
result['geometry'] = format_geojson(mapping(self.geometry), round=False) result['geometry'] = format_geojson(mapping(self.geometry), round=False)
if simple_geometry:
result['point'] = (self.level_id, ) + tuple(round(i, 2) for i in self.centroid.coords[0])
if not isinstance(self.geometry, Point):
result['bounds'] = ((int(math.floor(self.miny)), int(math.floor(self.minx))),
(int(math.ceil(self.maxy)), int(math.ceil(self.maxx))))
return result return result
def get_shadow_geojson(self): def get_shadow_geojson(self):

View file

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.utils.functional import cached_property
from django.utils.text import format_lazy from django.utils.text import format_lazy
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
@ -16,11 +17,9 @@ class SpaceGeometryMixin(GeometryMixin):
class Meta: class Meta:
abstract = True abstract = True
def _serialize(self, space=True, **kwargs): @cached_property
result = super()._serialize(**kwargs) def level_id(self):
if space: return self.space.level_id
result['space'] = self.space_id
return result
def get_geojson_properties(self, *args, **kwargs) -> dict: def get_geojson_properties(self, *args, **kwargs) -> dict:
result = super().get_geojson_properties(*args, **kwargs) result = super().get_geojson_properties(*args, **kwargs)

View file

@ -83,7 +83,8 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
result = super().serialize(detailed=detailed, **kwargs) result = super().serialize(detailed=detailed, **kwargs)
if not detailed: if not detailed:
result = OrderedDict(( result = OrderedDict((
(name, result[name]) for name in ('slug', 'title', 'subtitle') (name, result[name]) for name in ('id', 'slug', 'title', 'subtitle', 'point', 'bounds', 'locations')
if name in result
)) ))
return result return result
@ -246,10 +247,12 @@ class LocationGroup(Location, models.Model):
self.orig_category_id = self.category_id self.orig_category_id = self.category_id
self.orig_color = self.color self.orig_color = self.color
def _serialize(self, **kwargs): def _serialize(self, simple_geometry=False, **kwargs):
result = super()._serialize(**kwargs) result = super()._serialize(simple_geometry=simple_geometry, **kwargs)
result['category'] = self.category_id result['category'] = self.category_id
result['color'] = self.color result['color'] = self.color
if simple_geometry:
result['locations'] = tuple(obj.pk for obj in getattr(self, 'locations', ()))
return result return result
@property @property

View file

@ -6,7 +6,7 @@ def _preencode(data, magic_marker, in_coords=False, in_groups=False):
if isinstance(data, dict): if isinstance(data, dict):
data = data.copy() data = data.copy()
for name, value in tuple(data.items()): for name, value in tuple(data.items()):
if name == 'bounds' and isinstance(value, (tuple, list)): if name in ('bounds', 'point', 'locations') and isinstance(value, (tuple, list)):
data[name] = magic_marker+json.dumps(value)+magic_marker data[name] = magic_marker+json.dumps(value)+magic_marker
else: else:
data[name] = _preencode(value, magic_marker, data[name] = _preencode(value, magic_marker,