diff --git a/src/c3nav/mapdata/cache.py b/src/c3nav/mapdata/cache.py index 66dd6aee..5f70696b 100644 --- a/src/c3nav/mapdata/cache.py +++ b/src/c3nav/mapdata/cache.py @@ -1,8 +1,96 @@ +import math +import struct + +import numpy as np +from django.conf import settings from django.db.models.signals import m2m_changed, post_delete +from shapely import prepared +from shapely.geometry import box from c3nav.mapdata.utils.models import get_submodels +class MapHistory: + # binary format (everything little-endian): + # 1 byte (uint8): resolution + # 2 bytes (uint16): origin x + # 2 bytes (uint16): origin y + # 2 bytes (uint16): origin width + # 2 bytes (uint16): origin height + # 2 bytes (uint16): number of updates + # n*16 bytes: update keys as null-terminated strings + # width*height*2 bytes: data (line after line) with uint16 data + + def __init__(self, resolution=settings.CACHE_RESOLUTION, x=None, y=None, updates=None, data=None): + self.resolution = resolution + self.x = None + self.y = None + self.updates = updates + self.data = data + self.unfinished = False + + @classmethod + def open(cls, filename, default_update=None): + try: + with open(filename, 'rb') as f: + resolution, x, y, width, height, num_updates = struct.unpack(' self.x+orig_width or maxy > self.y+orig_height: + new_x, new_y = min(minx, self.x), min(miny, self.y) + new_width = min(maxx, self.x+orig_width)-new_x + new_height = min(maxy, self.y+orig_height)-new_y + new_data = np.zeros((new_height, new_width), dtype=np.uint16) + dx, dy = new_x-self.x, new_y-self.y + new_data[dy:dx, (dy+orig_height):(dx+orig_width)] = data + data = new_data + self.x, self.y = new_x, new_y + + new_val = len(self.updates) + for iy, y in enumerate(range(miny*res, maxy*res, res), start=miny-self.y): + for ix, x in enumerate(range(miny*res, maxy*res, res), start=minx-self.x): + if prep.intersects(box(x, y, x+res, y+res)): + data[iy, ix] = new_val + + self.unfinished = True + + def finish(self, cache_key): + self.unfinished = False + self.updates.append(cache_key) + + class GeometryChangeTracker: def __init__(self): self._geometries_by_level = {} diff --git a/src/c3nav/settings.py b/src/c3nav/settings.py index 422db2fd..76d426b9 100644 --- a/src/c3nav/settings.py +++ b/src/c3nav/settings.py @@ -59,6 +59,7 @@ DEBUG = config.getboolean('django', 'debug', fallback=debug_fallback) RENDER_SCALE = float(config.get('c3nav', 'render_scale', fallback=20.0)) SVG_RENDERER = config.get('c3nav', 'svg_renderer', fallback='rsvg-convert') CACHE_TILES = config.get('c3nav', 'cache_tiles', fallback=not DEBUG) +CACHE_RESOLUTION = config.get('c3nav', 'cache_resolution', fallback=4) db_backend = config.get('database', 'backend', fallback='sqlite3') DATABASES = {