diff --git a/src/c3nav/mapdata/models/geometry/space.py b/src/c3nav/mapdata/models/geometry/space.py index 6fe162e2..a81dc63b 100644 --- a/src/c3nav/mapdata/models/geometry/space.py +++ b/src/c3nav/mapdata/models/geometry/space.py @@ -214,6 +214,8 @@ class Obstacle(SpaceGeometryMixin, models.Model): """ An obstacle """ + new_serialize = True + group = models.ForeignKey(ObstacleGroup, null=True, blank=True, on_delete=models.SET_NULL) geometry = GeometryField('polygon') height = models.DecimalField(_('height'), max_digits=6, decimal_places=2, default=0.8, @@ -235,13 +237,10 @@ class Obstacle(SpaceGeometryMixin, models.Model): result['color'] = color return result - def _serialize(self, geometry=True, **kwargs): - result = super()._serialize(geometry=geometry, **kwargs) - result['height'] = float(str(self.height)) - result['altitude'] = float(str(self.altitude)) + @property + def color(self): from c3nav.mapdata.render.theme import ColorManager - result['color'] = self.get_color(ColorManager.for_theme(None)) - return result + return self.get_color(ColorManager.for_theme(None)) def get_color(self, color_manager: 'ThemeColorManager'): return ( @@ -255,6 +254,8 @@ class LineObstacle(SpaceGeometryMixin, models.Model): """ An obstacle that is a line with a specific width """ + new_serialize = True + group = models.ForeignKey(ObstacleGroup, null=True, blank=True, on_delete=models.SET_NULL) geometry = GeometryField('linestring') width = models.DecimalField(_('width'), max_digits=4, decimal_places=2, default=0.15) @@ -288,6 +289,11 @@ class LineObstacle(SpaceGeometryMixin, models.Model): result['buffered_geometry'] = format_geojson(mapping(self.buffered_geometry)) return result + @property + def color(self): + from c3nav.mapdata.render.theme import ColorManager + return self.get_color(ColorManager.for_theme(None)) + def get_color(self, color_manager: 'ThemeColorManager'): # TODO: should line obstacles use border color? return ( diff --git a/src/c3nav/mapdata/schemas/models.py b/src/c3nav/mapdata/schemas/models.py index 34be2f74..6d6d88f3 100644 --- a/src/c3nav/mapdata/schemas/models.py +++ b/src/c3nav/mapdata/schemas/models.py @@ -5,9 +5,10 @@ from pydantic import Discriminator, Tag from pydantic import Field as APIField from pydantic import NonNegativeFloat, PositiveFloat, PositiveInt -from c3nav.api.schema import BaseSchema, GeometrySchema, PointSchema, AnyGeometrySchema +from c3nav.api.schema import BaseSchema, GeometrySchema, PointSchema, AnyGeometrySchema, PolygonSchema from c3nav.api.utils import NonEmptyStr from c3nav.mapdata.models import LocationGroup +from c3nav.mapdata.models.geometry.base import GeometryMixin from c3nav.mapdata.schemas.model_base import (AnyLocationID, AnyPositionID, CustomLocationID, DjangoModelSchema, LabelSettingsSchema, LocationSchema, PositionID, SimpleGeometryLocationsSchema, SimpleGeometryPointAndBoundsSchema, @@ -16,6 +17,8 @@ from c3nav.mapdata.schemas.model_base import (AnyLocationID, AnyPositionID, Cust WithLineStringGeometrySchema, WithPointGeometrySchema, WithPolygonGeometrySchema, WithSpaceSchema, schema_definitions, schema_description) +from c3nav.mapdata.utils.geometry import smart_mapping +from c3nav.mapdata.utils.json import format_geojson class LevelSchema(SpecificLocationSchema, DjangoModelSchema): @@ -141,11 +144,37 @@ class LineObstacleSchema(WithLineStringGeometrySchema, BaseObstacleSchema): """ An obstacle to be subtracted from the accessible surface of a space, defined as a line with width. """ + buffered_geometry: Union[ + PolygonSchema, + Annotated[None, APIField(title="null", description="geometry not available of excluded from endpoint")] + ] = APIField( + None, + title="buffered geometry", + description="line turned into a polygon with the given width, " + "can be null if not available or excluded from endpoint", + ) width: PositiveFloat = APIField( title="width", description="width of the line" ) + @classmethod + def get_overrides(cls, value) -> dict: + # todo: move into model + value: GeometryMixin + if "geometry" in value.get_deferred_fields() or value.geometry is None: + return { + **super().get_overrides(value), + "buffered_geometry": None, + } + return { + **super().get_overrides(value), + "buffered_geometry": ( + format_geojson(smart_mapping(value.buffered_geometry), rounded=False) + if not getattr(value, '_hide_geometry', False) else None + ), + } + class ColumnSchema(WithPolygonGeometrySchema, WithSpaceSchema, DjangoModelSchema): """