From 5df84bb7a148c8e25a3c4decfdb51d37cc04a9f1 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Thu, 16 Dec 2021 09:58:59 +0100 Subject: [PATCH] #50 Overlaying geometries Tests * adds test for geometry conflicts * refactors rechecking of existing conflicts to avoid recursion in certain cases * adds/updates translations --- konova/admin.py | 2 +- konova/models/geometry.py | 45 +++++++---- konova/models/object.py | 2 +- konova/tests/test_geometries.py | 49 ++++++++++++ locale/de/LC_MESSAGES/django.mo | Bin 28116 -> 28510 bytes locale/de/LC_MESSAGES/django.po | 132 +++++++++++++++++--------------- 6 files changed, 149 insertions(+), 81 deletions(-) create mode 100644 konova/tests/test_geometries.py diff --git a/konova/admin.py b/konova/admin.py index e62a8cff..213e0412 100644 --- a/konova/admin.py +++ b/konova/admin.py @@ -20,7 +20,7 @@ class GeometryAdmin(admin.ModelAdmin): class GeometryConflictAdmin(admin.ModelAdmin): list_display = [ "conflicting_geometry", - "existing_geometry", + "affected_geometry", "detected_on", ] diff --git a/konova/models/geometry.py b/konova/models/geometry.py index 7dddcf0e..8c155732 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -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}" diff --git a/konova/models/object.py b/konova/models/object.py index 764e7079..ded39ad1 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -425,7 +425,7 @@ class GeoReferencedMixin(models.Model): add_message = False conflicts = self.geometry.conflicts_geometries.all() for conflict in conflicts: - instance_objs += conflict.existing_geometry.get_data_objects() + instance_objs += conflict.affected_geometry.get_data_objects() add_message = True conflicts = self.geometry.conflicted_by_geometries.all() for conflict in conflicts: diff --git a/konova/tests/test_geometries.py b/konova/tests/test_geometries.py new file mode 100644 index 00000000..a9a840f5 --- /dev/null +++ b/konova/tests/test_geometries.py @@ -0,0 +1,49 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.12.21 + +""" +from django.contrib.gis.db.models.functions import Translate + +from konova.models import Geometry, GeometryConflict +from konova.tests.test_views import BaseTestCase +from user.models import UserActionLogEntry + + +class GeometryTestCase(BaseTestCase): + @classmethod + def setUpTestData(cls): + super().setUpTestData() + geom = cls.create_dummy_geometry() + action = UserActionLogEntry.get_created_action(cls.superuser) + cls.geom_1 = Geometry.objects.create( + geom=geom, + created=action, + ) + cls.geom_2 = Geometry.objects.create( + geom=geom, + created=action, + ) + + def test_geometry_conflict(self): + """ Tests whether a geometry conflict will be present in case of identical/overlaying geometries and + if the conflict will be resolved if one geometry is edited. + + Returns: + + """ + self.geom_1.check_for_conflicts() + conflict = GeometryConflict.objects.all().first() + self.assertEqual(conflict.conflicting_geometry, self.geom_2) + self.assertEqual(conflict.affected_geometry, self.geom_1) + + # Move geom_2 somewhere else, expect the conflict to be resolved + Geometry.objects.filter(id=self.geom_2.id).update( + geom=Translate('geom', 100000, 100000) + ) + self.geom_2.refresh_from_db() + self.geom_1.check_for_conflicts() + num_conflict = GeometryConflict.objects.all().count() + self.assertEqual(0, num_conflict) diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 94f1f4261103119e00e1404a6d82c66f36b65d81..bd3e82d8ebcb6ae0e59f48644b44c20fb80aa7a9 100644 GIT binary patch delta 9049 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 KvxLl7WBw06Y9a#w delta 8678 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\n" "Language-Team: LANGUAGE \n" @@ -329,7 +329,7 @@ msgstr "Automatisch generiert" #: intervention/templates/intervention/detail/includes/documents.html:28 #: intervention/templates/intervention/detail/view.html:31 #: intervention/templates/intervention/report/report.html:12 -#: konova/forms.py:332 +#: konova/forms.py:334 msgid "Title" msgstr "Bezeichnung" @@ -356,7 +356,7 @@ msgstr "Kompensation XY; Flur ABC" #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:367 konova/templates/konova/comment_card.html:16 +#: konova/forms.py:369 konova/templates/konova/comment_card.html:16 msgid "Comment" msgstr "Kommentar" @@ -472,7 +472,7 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:239 #: compensation/forms/modalForms.py:317 intervention/forms/modalForms.py:152 -#: konova/forms.py:369 +#: konova/forms.py:371 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" @@ -614,7 +614,7 @@ msgstr "" msgid "Pieces" msgstr "Stück" -#: compensation/models/compensation.py:62 konova/utils/message_templates.py:27 +#: compensation/models/compensation.py:63 konova/utils/message_templates.py:27 msgid "Added deadline" msgstr "Frist/Termin hinzugefügt" @@ -793,7 +793,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:385 +#: konova/forms.py:387 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -1056,42 +1056,42 @@ msgstr "Kompensation {} hinzugefügt" msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" -#: compensation/views/compensation.py:229 compensation/views/eco_account.py:308 -#: ema/views.py:182 intervention/views.py:475 +#: compensation/views/compensation.py:228 compensation/views/eco_account.py:307 +#: ema/views.py:181 intervention/views.py:474 msgid "Log" msgstr "Log" -#: compensation/views/compensation.py:252 +#: compensation/views/compensation.py:251 msgid "Compensation removed" msgstr "Kompensation entfernt" -#: compensation/views/compensation.py:273 compensation/views/eco_account.py:460 -#: ema/views.py:349 intervention/views.py:129 +#: compensation/views/compensation.py:272 compensation/views/eco_account.py:459 +#: ema/views.py:348 intervention/views.py:129 msgid "Document added" msgstr "Dokument hinzugefügt" -#: compensation/views/compensation.py:342 compensation/views/eco_account.py:354 -#: ema/views.py:287 +#: compensation/views/compensation.py:341 compensation/views/eco_account.py:353 +#: ema/views.py:286 msgid "State added" msgstr "Zustand hinzugefügt" -#: compensation/views/compensation.py:363 compensation/views/eco_account.py:375 -#: ema/views.py:308 +#: compensation/views/compensation.py:362 compensation/views/eco_account.py:374 +#: ema/views.py:307 msgid "Action added" msgstr "Maßnahme hinzugefügt" -#: compensation/views/compensation.py:384 compensation/views/eco_account.py:440 -#: ema/views.py:329 +#: compensation/views/compensation.py:383 compensation/views/eco_account.py:439 +#: ema/views.py:328 msgid "Deadline added" msgstr "Frist/Termin hinzugefügt" -#: compensation/views/compensation.py:406 compensation/views/eco_account.py:397 -#: ema/views.py:419 +#: compensation/views/compensation.py:405 compensation/views/eco_account.py:396 +#: ema/views.py:418 msgid "State removed" msgstr "Zustand gelöscht" -#: compensation/views/compensation.py:428 compensation/views/eco_account.py:419 -#: ema/views.py:441 +#: compensation/views/compensation.py:427 compensation/views/eco_account.py:418 +#: ema/views.py:440 msgid "Action removed" msgstr "Maßnahme entfernt" @@ -1103,45 +1103,45 @@ msgstr "Ökokonto {} hinzugefügt" msgid "Eco-Account {} edited" msgstr "Ökokonto {} bearbeitet" -#: compensation/views/eco_account.py:256 +#: compensation/views/eco_account.py:255 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: compensation/views/eco_account.py:284 +#: compensation/views/eco_account.py:283 msgid "Deduction removed" msgstr "Abbuchung entfernt" -#: compensation/views/eco_account.py:329 ema/views.py:262 -#: intervention/views.py:517 +#: compensation/views/eco_account.py:328 ema/views.py:261 +#: intervention/views.py:516 msgid "{} unrecorded" msgstr "{} entzeichnet" -#: compensation/views/eco_account.py:329 ema/views.py:262 -#: intervention/views.py:517 +#: compensation/views/eco_account.py:328 ema/views.py:261 +#: intervention/views.py:516 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account.py:530 intervention/views.py:498 +#: compensation/views/eco_account.py:529 intervention/views.py:497 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" -#: compensation/views/eco_account.py:613 ema/views.py:517 -#: intervention/views.py:373 +#: compensation/views/eco_account.py:612 ema/views.py:516 +#: intervention/views.py:372 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: compensation/views/eco_account.py:618 ema/views.py:522 -#: intervention/views.py:378 +#: compensation/views/eco_account.py:617 ema/views.py:521 +#: intervention/views.py:377 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: compensation/views/eco_account.py:625 ema/views.py:529 -#: intervention/views.py:385 +#: compensation/views/eco_account.py:624 ema/views.py:528 +#: intervention/views.py:384 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: compensation/views/eco_account.py:648 ema/views.py:552 -#: intervention/views.py:408 +#: compensation/views/eco_account.py:647 ema/views.py:551 +#: intervention/views.py:407 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" @@ -1185,11 +1185,11 @@ msgstr "Ersatzzahlungsmaßnahme" msgid "EMA {} added" msgstr "EMA {} hinzugefügt" -#: ema/views.py:211 +#: ema/views.py:210 msgid "EMA {} edited" msgstr "EMA {} bearbeitet" -#: ema/views.py:243 +#: ema/views.py:242 msgid "EMA removed" msgstr "EMA entfernt" @@ -1333,7 +1333,7 @@ msgstr "Kompensationen und Zahlungen geprüft" msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms/modalForms.py:196 konova/forms.py:451 +#: intervention/forms/modalForms.py:196 konova/forms.py:453 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -1476,27 +1476,27 @@ msgstr "Eingriff {} hinzugefügt" msgid "This intervention has {} revocations" msgstr "Dem Eingriff liegen {} Widersprüche vor" -#: intervention/views.py:291 +#: intervention/views.py:290 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:326 +#: intervention/views.py:325 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:347 +#: intervention/views.py:346 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:429 +#: intervention/views.py:428 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:451 +#: intervention/views.py:450 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:522 +#: intervention/views.py:521 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1525,11 +1525,11 @@ msgstr "Speichern" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:138 konova/forms.py:305 +#: konova/forms.py:138 konova/forms.py:307 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:150 konova/forms.py:314 +#: konova/forms.py:150 konova/forms.py:316 msgid "Remove" msgstr "Löschen" @@ -1542,56 +1542,56 @@ msgstr "Sie sind dabei {} {} zu löschen" msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:315 +#: konova/forms.py:317 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:342 +#: konova/forms.py:344 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:344 +#: konova/forms.py:346 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:355 +#: konova/forms.py:357 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:357 +#: konova/forms.py:359 msgid "Allowed formats: pdf, jpg, png. Max size 15 MB." msgstr "Formate: pdf, jpg, png. Maximal 15 MB." -#: konova/forms.py:403 +#: konova/forms.py:405 msgid "Unsupported file type" msgstr "Dateiformat nicht unterstützt" -#: konova/forms.py:410 +#: konova/forms.py:412 msgid "File too large" msgstr "Datei zu groß" -#: konova/forms.py:419 +#: konova/forms.py:421 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:442 +#: konova/forms.py:444 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:450 +#: konova/forms.py:452 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:457 +#: konova/forms.py:459 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:458 +#: konova/forms.py:460 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:459 +#: konova/forms.py:461 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1726,6 +1726,8 @@ msgid "" "Action canceled. Eco account is recorded or deductions exist. Only " "conservation office member can perform this action." msgstr "" +"Aktion abgebrochen. Ökokonto ist bereits verzeichnet oder Abbuchungen liegen vor. Nur " +"Eintragungsstellennutzer können diese Aktion jetzt durchführen." #: konova/utils/message_templates.py:25 msgid "Edited general data" @@ -1739,6 +1741,10 @@ msgstr "Zustand hinzugefügt" msgid "Added compensation action" msgstr "Maßnahme hinzufügen" +#: konova/utils/message_templates.py:31 +msgid "Geometry conflict detected with {}" +msgstr "Geometriekonflikt mit folgenden Einträgen erkannt: {}" + #: konova/utils/messenger.py:69 msgid "{} checked" msgstr "{} geprüft"