add support for grid and display grid cell for custom locations already

This commit is contained in:
Laura Klünder 2018-12-10 18:52:32 +01:00
parent 600900bb58
commit 875b18c730
3 changed files with 72 additions and 3 deletions

61
src/c3nav/mapdata/grid.py Normal file
View file

@ -0,0 +1,61 @@
import bisect
import string
from abc import ABC, abstractmethod
from typing import Optional
from django.conf import settings
class AbstractGrid(ABC):
@abstractmethod
def get_cell_for_point(self, x, y) -> Optional[str]:
pass
class Grid(AbstractGrid):
def __init__(self, rows, cols):
rows = tuple(float(y) for y in rows)
cols = tuple(float(x) for x in cols)
self.rows = tuple(sorted(rows))
self.cols = tuple(sorted(cols))
if self.rows == rows:
self.invert_y = False
elif self.rows == tuple(reversed(rows)):
self.invert_y = True
else:
raise ValueError('row coordinates are not ordered')
if self.cols == cols:
self.invert_x = False
elif self.cols == tuple(reversed(cols)):
self.invert_x = True
else:
raise ValueError('column coordinates are not ordered')
def get_cell_for_point(self, x, y):
x = bisect.bisect(self.cols, x)
if x <= 0 or x >= len(self.cols):
return None
y = bisect.bisect(self.rows, y)
if y <= 0 or y >= len(self.rows):
return None
if self.invert_x:
x = len(self.cols) - x
if self.invert_y:
y = len(self.rows) - y
return '%s%d' % (string.ascii_uppercase[x-1], y)
class DummyGrid(AbstractGrid):
def get_cell_for_point(self, x, y):
return None
if settings.GRID_COLS and settings.GRID_ROWS:
grid = Grid(settings.GRID_ROWS.split(','), settings.GRID_COLS.split(','))
else:
grid = DummyGrid()

View file

@ -13,6 +13,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 shapely.ops import cascaded_union from shapely.ops import cascaded_union
from c3nav.mapdata.grid import grid
from c3nav.mapdata.models import Level, Location, LocationGroup, MapUpdate from c3nav.mapdata.models import Level, Location, LocationGroup, MapUpdate
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.base import GeometryMixin
@ -367,9 +368,12 @@ class CustomLocation:
@cached_property @cached_property
def title_subtitle(self): def title_subtitle(self):
grid_cell = grid.get_cell_for_point(self.x, self.y)
level_subtitle = self.level.title if grid_cell is None else ','.join((grid_cell, str(self.level.title)))
title = _('In %(level)s') % {'level': self.level.title} title = _('In %(level)s') % {'level': self.level.title}
if not self.space: if not self.space:
return title, self.level.title, return title, level_subtitle
subtitle = () subtitle = ()
if self.near_poi: if self.near_poi:
@ -385,9 +389,10 @@ class CustomLocation:
elif self.near_area: elif self.near_area:
title = _('Near %(area)s') % {'area': self.near_area.title} title = _('Near %(area)s') % {'area': self.near_area.title}
else: else:
return _('In %(space)s') % {'space': self.space.title}, self.level.title return _('In %(space)s') % {'space': self.space.title}, level_subtitle
subtitle = ', '.join(str(title) for title in chain(subtitle, (self.space.title, self.level.title))) subtitle_segments = chain((grid_cell, ), subtitle, (self.space.title, self.level.title))
subtitle = ', '.join(str(title) for title in subtitle_segments if title is not None)
return title, subtitle return title, subtitle
@cached_property @cached_property

View file

@ -90,6 +90,9 @@ CACHE_RESOLUTION = config.get('c3nav', 'cache_resolution', fallback=4)
INITIAL_LEVEL = config.get('c3nav', 'initial_level', fallback=None) INITIAL_LEVEL = config.get('c3nav', 'initial_level', fallback=None)
INITIAL_BOUNDS = config.get('c3nav', 'initial_bounds', fallback='').split(' ') INITIAL_BOUNDS = config.get('c3nav', 'initial_bounds', fallback='').split(' ')
GRID_ROWS = config.get('c3nav', 'grid_rows', fallback=None)
GRID_COLS = config.get('c3nav', 'grid_cols', fallback=None)
if len(INITIAL_BOUNDS) == 4: if len(INITIAL_BOUNDS) == 4:
try: try:
INITIAL_BOUNDS = tuple(float(i) for i in INITIAL_BOUNDS) INITIAL_BOUNDS = tuple(float(i) for i in INITIAL_BOUNDS)