#50 Overlaying geometries Tests

* adds test for geometry conflicts
* refactors rechecking of existing conflicts to avoid recursion in certain cases
* adds/updates translations
This commit is contained in:
2021-12-16 09:58:59 +01:00
parent 41af455d09
commit 6021e2f1bc
6 changed files with 149 additions and 81 deletions

View File

@@ -24,7 +24,7 @@ class Geometry(BaseResource):
self.check_for_conflicts()
def check_for_conflicts(self):
""" Checks for geometry overlaps
""" Checks for new geometry overlaps
Creates a new GeometryConflict entry for each overlap to another geometry, which has already been there before
@@ -35,27 +35,40 @@ class Geometry(BaseResource):
if self.geom is None or (self.created is None and self.modified is None):
return None
check_timestamp_obj = self.modified or self.created
ts = check_timestamp_obj.timestamp
self.recheck_existing_conflicts()
overlapping_geoms = Geometry.objects.filter(
Q(modified__timestamp__lte=ts) |
Q(created__timestamp__lte=ts),
geom__intersects=self.geom,
).exclude(
id=self.id
).distinct()
# Drop known conflicts for this object to replace with new ones
self.conflicts_geometries.all().delete()
for match in overlapping_geoms:
GeometryConflict.objects.get_or_create(conflicting_geometry=self, existing_geometry=match)
GeometryConflict.objects.get_or_create(conflicting_geometry=self, affected_geometry=match)
def recheck_existing_conflicts(self):
""" Rechecks GeometryConflict entries
If a conflict seems to be resolved due to no longer intersection between the two geometries, the entry
will be deleted.
Returns:
"""
all_conflicts_as_conflicting = self.conflicts_geometries.all()
still_conflicting_conflicts = all_conflicts_as_conflicting.filter(
affected_geometry__geom__intersects=self.geom
)
resolved_conflicts = all_conflicts_as_conflicting.exclude(id__in=still_conflicting_conflicts)
resolved_conflicts.delete()
all_conflicted_by_conflicts = self.conflicted_by_geometries.all()
still_conflicting_conflicts = all_conflicted_by_conflicts.filter(
conflicting_geometry__geom__intersects=self.geom
)
resolved_conflicts = all_conflicted_by_conflicts.exclude(id__in=still_conflicting_conflicts)
resolved_conflicts.delete()
# Rerun the conflict check for all conflicts where this object is not the cause but the one that already existed.
# It may be possible that this object has been edited, so the conflicts would be resolved in the newer entries.
existing_conflicts = self.conflicted_by_geometries.all()
for conflict in existing_conflicts:
conflicting_geom = conflict.conflicting_geometry
conflicting_geom.check_for_conflicts()
def get_data_objects(self):
""" Getter for all objects which are related to this geometry
@@ -90,7 +103,7 @@ class GeometryConflict(UuidModel):
help_text="The geometry which came second",
related_name="conflicts_geometries"
)
existing_geometry = models.ForeignKey(
affected_geometry = models.ForeignKey(
Geometry,
on_delete=models.CASCADE,
help_text="The geometry which came first",
@@ -99,4 +112,4 @@ class GeometryConflict(UuidModel):
detected_on = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return f"{self.conflicting_geometry.id} conflicts with {self.existing_geometry.id}"
return f"{self.conflicting_geometry.id} conflicts with {self.affected_geometry.id}"