team-3/src/c3nav/mapdata/models/geometry/base.py

82 lines
2.8 KiB
Python
Raw Normal View History

from collections import OrderedDict
2017-05-08 21:55:45 +02:00
from django.db import models
from django.utils.translation import ugettext_lazy as _
2017-05-07 12:06:13 +02:00
from shapely.geometry import Point, mapping
from c3nav.mapdata.models.base import SerializableMixin
from c3nav.mapdata.utils.json import format_geojson
2017-10-10 17:49:30 +02:00
class GeometryManager(models.Manager):
def within(self, minx, miny, maxx, maxy):
return self.get_queryset().filter(minx__lte=maxx, maxx__gte=minx, miny__lte=maxy, maxy__gte=miny)
class GeometryMixin(SerializableMixin):
"""
A map feature with a geometry
"""
geometry = None
minx = models.DecimalField(_('min x coordinate'), max_digits=6, decimal_places=2, db_index=True)
miny = models.DecimalField(_('min y coordinate'), max_digits=6, decimal_places=2, db_index=True)
maxx = models.DecimalField(_('max x coordinate'), max_digits=6, decimal_places=2, db_index=True)
maxy = models.DecimalField(_('max y coordinate'), max_digits=6, decimal_places=2, db_index=True)
2017-10-10 17:49:30 +02:00
objects = GeometryManager()
class Meta:
abstract = True
2017-10-10 17:49:30 +02:00
base_manager_name = 'objects'
def get_geojson_properties(self, *args, **kwargs) -> dict:
2017-05-27 16:19:49 +02:00
result = OrderedDict((
('type', self.__class__.__name__.lower()),
2017-06-16 18:19:52 +02:00
('id', self.pk),
))
2017-05-27 16:19:49 +02:00
if getattr(self, 'bounds', False):
result['bounds'] = True
return result
def to_geojson(self, instance=None) -> dict:
result = OrderedDict((
('type', 'Feature'),
('properties', self.get_geojson_properties(instance=instance)),
('geometry', format_geojson(mapping(self.geometry), round=False)),
))
original_geometry = getattr(self, 'original_geometry', None)
if original_geometry:
result['original_geometry'] = format_geojson(mapping(original_geometry), round=False)
return result
2017-05-11 21:30:29 +02:00
@classmethod
def serialize_type(cls, geomtype=True, **kwargs):
result = super().serialize_type()
if geomtype:
result['geomtype'] = cls._meta.get_field('geometry').geomtype
return result
2017-05-11 19:36:49 +02:00
def serialize(self, geometry=True, **kwargs):
result = super().serialize(geometry=geometry, **kwargs)
if geometry:
result.move_to_end('geometry')
return result
def _serialize(self, geometry=True, **kwargs):
result = super()._serialize(**kwargs)
if geometry:
result['geometry'] = format_geojson(mapping(self.geometry), round=False)
return result
def get_shadow_geojson(self):
2017-05-09 09:36:08 +02:00
pass
2017-05-09 13:16:36 +02:00
def contains(self, x, y) -> bool:
return self.geometry.contains(Point(x, y))
def recalculate_bounds(self):
self.minx, self.miny, self.maxx, self.maxy = self.geometry.bounds
def save(self, *args, **kwargs):
self.recalculate_bounds()
super().save(*args, **kwargs)