diff --git a/src/c3nav/mapdata/cache.py b/src/c3nav/mapdata/cache.py index 24eaa974..1cd0a059 100644 --- a/src/c3nav/mapdata/cache.py +++ b/src/c3nav/mapdata/cache.py @@ -256,13 +256,23 @@ class GeometryChangeTracker: self._geometries_by_level = {} self._deleted_levels = set() - def save(self, last_update, new_update): + def finalize(self): for level_id in self._deleted_levels: try: os.remove(MapHistory.level_filename(level_id, mode='base')) except FileNotFoundError: pass self._geometries_by_level.pop(level_id, None) + self._deleted_levels = set() + + def combine(self, other): + self.finalize() + other.finalize() + for level_id, geometries in other._geometries_by_level.items(): + self._geometries_by_level.setdefault(level_id, []).extend(geometries) + + def save(self, last_update, new_update): + self.finalize() for level_id, geometries in self._geometries_by_level.items(): geometries = unary_union(geometries) diff --git a/src/c3nav/mapdata/models/geometry/base.py b/src/c3nav/mapdata/models/geometry/base.py index d57519dc..55018cc3 100644 --- a/src/c3nav/mapdata/models/geometry/base.py +++ b/src/c3nav/mapdata/models/geometry/base.py @@ -5,9 +5,10 @@ from django.db import models from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ from shapely.geometry import LineString, Point, mapping +from shapely.ops import unary_union from c3nav.mapdata.models.base import SerializableMixin -from c3nav.mapdata.utils.geometry import assert_multilinestring +from c3nav.mapdata.utils.geometry import assert_multilinestring, assert_multipolygon from c3nav.mapdata.utils.json import format_geojson @@ -117,7 +118,12 @@ class GeometryMixin(SerializableMixin): return False def get_changed_geometry(self): - return self.geometry if self.orig_geometry is None else self.geometry.symmetric_difference(self.orig_geometry) + if self.orig_geometry is None: + return self.geometry + difference = self.geometry.symmetric_difference(self.orig_geometry) + if self._meta.get_field('geomety').geomtype in ('polygon', 'multipolygon'): + difference = unary_union(assert_multipolygon(difference)) + return difference def save(self, *args, **kwargs): self.recalculate_bounds() diff --git a/src/c3nav/mapdata/models/update.py b/src/c3nav/mapdata/models/update.py index 1c19eaa6..048fce7a 100644 --- a/src/c3nav/mapdata/models/update.py +++ b/src/c3nav/mapdata/models/update.py @@ -9,6 +9,7 @@ from django.utils.http import int_to_base36 from django.utils.timezone import make_naive from django.utils.translation import ugettext_lazy as _ +from c3nav.mapdata.cache import changed_geometries from c3nav.mapdata.tasks import process_map_updates @@ -89,17 +90,29 @@ class MapUpdate(models.Model): if not new_updates: return () - last_processed_update = cls.objects.filter(processed=True).latest().to_tuple - for new_update in new_updates: - with suppress(FileNotFoundError): - changed_geometries = pickle.load(open(new_update._changed_geometries_filename(), 'rb')) - changed_geometries.save(last_processed_update, new_update.to_tuple) - new_update.processed = True - new_update.save() + changed_geometries.reset() from c3nav.mapdata.models import AltitudeArea AltitudeArea.recalculate() + for new_update in new_updates: + print(new_update) + try: + changed_geometries.combine( + pickle.load(open(new_update._changed_geometries_filename(), 'rb')) + ) + except FileNotFoundError: + print('Changed geometries file not found. File not found!') + with suppress(FileNotFoundError): + + print('done') + new_update.processed = True + new_update.save() + + last_processed_update = cls.objects.filter(processed=True).latest().to_tuple + + changed_geometries.save(last_processed_update, new_updates[-1].to_tuple) + from c3nav.mapdata.render.data import LevelRenderData LevelRenderData.rebuild()