#50 Overlaying geometries KOM + OEK

* removes unused messages
* adds geometry conflict message rendering for KOM and OEK
* removes unused methods in GeoReferencedMixin
* generalizes geometrical lookup for conflicts from overlaps to intersects
pull/52/head
mpeltriaux 3 years ago
parent 2bd94a7618
commit 286ed609da

@ -7,6 +7,7 @@ Created on: 16.11.21
""" """
import shutil import shutil
from django.contrib import messages
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models, transaction from django.db import models, transaction
from django.db.models import QuerySet, Sum from django.db.models import QuerySet, Sum
@ -19,6 +20,7 @@ from compensation.utils.quality import CompensationQualityChecker
from konova.models import BaseObject, AbstractDocument, Deadline, generate_document_file_upload_path, \ from konova.models import BaseObject, AbstractDocument, Deadline, generate_document_file_upload_path, \
GeoReferencedMixin GeoReferencedMixin
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE
from konova.utils.message_templates import DATA_UNSHARED_EXPLANATION
from user.models import UserActionLogEntry from user.models import UserActionLogEntry
@ -155,6 +157,22 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin):
checker.run_check() checker.run_check()
return checker return checker
def set_status_messages(self, request: HttpRequest):
""" Setter for different information that need to be rendered
Adds messages to the given HttpRequest
Args:
request (HttpRequest): The incoming request
Returns:
request (HttpRequest): The modified request
"""
if not self.is_shared_with(request.user):
messages.info(request, DATA_UNSHARED_EXPLANATION)
request = self._set_geometry_conflict_message(request)
return request
class CEFMixin(models.Model): class CEFMixin(models.Model):
""" Provides CEF flag as Mixin """ Provides CEF flag as Mixin

@ -184,8 +184,7 @@ def detail_view(request: HttpRequest, id: str):
sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0 sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
diff_states = abs(sum_before_states - sum_after_states) diff_states = abs(sum_before_states - sum_after_states)
if not is_data_shared: request = comp.set_status_messages(request)
messages.info(request, DATA_UNSHARED_EXPLANATION)
context = { context = {
"obj": comp, "obj": comp,

@ -202,8 +202,7 @@ def detail_view(request: HttpRequest, id: str):
) )
actions = acc.actions.all() actions = acc.actions.all()
if not is_data_shared: request = acc.set_status_messages(request)
messages.info(request, DATA_UNSHARED_EXPLANATION)
context = { context = {
"obj": acc, "obj": acc,

@ -94,10 +94,19 @@ class Ema(AbstractCompensation, ShareableObjectMixin, RecordableObjectMixin):
return docs return docs
def set_status_messages(self, request: HttpRequest): def set_status_messages(self, request: HttpRequest):
""" Setter for different information that need to be rendered
Adds messages to the given HttpRequest
Args:
request (HttpRequest): The incoming request
Returns:
request (HttpRequest): The modified request
"""
if not self.is_shared_with(request.user): if not self.is_shared_with(request.user):
messages.info(request, DATA_UNSHARED_EXPLANATION) messages.info(request, DATA_UNSHARED_EXPLANATION)
self._set_overlapped_by_message(request) self._set_geometry_conflict_message(request)
self._set_overlapping_message(request)
return request return request

@ -266,10 +266,19 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
self.set_unchecked() self.set_unchecked()
def set_status_messages(self, request: HttpRequest): def set_status_messages(self, request: HttpRequest):
""" Setter for different information that need to be rendered
Adds messages to the given HttpRequest
Args:
request (HttpRequest): The incoming request
Returns:
request (HttpRequest): The modified request
"""
if not self.is_shared_with(request.user): if not self.is_shared_with(request.user):
messages.info(request, DATA_UNSHARED_EXPLANATION) messages.info(request, DATA_UNSHARED_EXPLANATION)
request = self._set_overlapping_message(request) request = self._set_geometry_conflict_message(request)
request = self._set_overlapped_by_message(request)
return request return request

@ -282,11 +282,13 @@ class SimpleGeomForm(BaseForm):
""" """
try: try:
if self.instance is None or self.instance.geometry is None:
raise LookupError
geometry = self.instance.geometry geometry = self.instance.geometry
geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)) geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID))
geometry.modified = action geometry.modified = action
geometry.save() geometry.save()
except AttributeError: except LookupError:
# No geometry or linked instance holding a geometry exist --> create a new one! # No geometry or linked instance holding a geometry exist --> create a new one!
geometry = Geometry.objects.create( geometry = Geometry.objects.create(
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)), geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)),

@ -7,6 +7,7 @@ Created on: 15.11.21
""" """
from django.contrib.gis.db.models import MultiPolygonField from django.contrib.gis.db.models import MultiPolygonField
from django.db import models from django.db import models
from django.db.models import Q
from konova.models import BaseResource, UuidModel from konova.models import BaseResource, UuidModel
@ -37,9 +38,12 @@ class Geometry(BaseResource):
check_timestamp_obj = self.modified or self.created check_timestamp_obj = self.modified or self.created
ts = check_timestamp_obj.timestamp ts = check_timestamp_obj.timestamp
overlapping_geoms = Geometry.objects.filter( overlapping_geoms = Geometry.objects.filter(
modified__timestamp__lte=ts, Q(modified__timestamp__lte=ts) |
geom__overlaps=self.geom, 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 # Drop known conflicts for this object to replace with new ones
self.conflicts_geometries.all().delete() self.conflicts_geometries.all().delete()

@ -21,8 +21,7 @@ from ema.settings import EMA_ACCOUNT_IDENTIFIER_LENGTH, EMA_ACCOUNT_IDENTIFIER_T
from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE
from konova.utils import generators from konova.utils import generators
from konova.utils.generators import generate_random_string from konova.utils.generators import generate_random_string
from konova.utils.message_templates import CHECKED_RECORDED_RESET, GEOMETRY_OVERLAPS_WITH_TEMPLATE, \ from konova.utils.message_templates import CHECKED_RECORDED_RESET, GEOMETRY_CONFLICT_WITH_TEMPLATE
GEOMETRY_OVERLAPPED_BY_TEMPLATE
from user.models import UserActionLogEntry, UserAction from user.models import UserActionLogEntry, UserAction
@ -421,26 +420,21 @@ class GeoReferencedMixin(models.Model):
class Meta: class Meta:
abstract = True abstract = True
def _set_overlapping_message(self, request: HttpRequest): def _set_geometry_conflict_message(self, request: HttpRequest):
geom_conflicts = self.geometry.conflicts_geometries.all() instance_objs = []
if geom_conflicts: add_message = False
data_objs = [] conflicts = self.geometry.conflicts_geometries.all()
for conflict in geom_conflicts: for conflict in conflicts:
data_objs += conflict.existing_geometry.get_data_objects() instance_objs += conflict.existing_geometry.get_data_objects()
data_identifiers = [x.identifier for x in data_objs] add_message = True
data_identifiers = ", ".join(data_identifiers) conflicts = self.geometry.conflicted_by_geometries.all()
message_str = GEOMETRY_OVERLAPS_WITH_TEMPLATE.format(data_identifiers) for conflict in conflicts:
instance_objs += conflict.conflicting_geometry.get_data_objects()
add_message = True
if add_message:
instance_identifiers = [x.identifier for x in instance_objs]
instance_identifiers = ", ".join(instance_identifiers)
message_str = GEOMETRY_CONFLICT_WITH_TEMPLATE.format(instance_identifiers)
messages.info(request, message_str) messages.info(request, message_str)
return request return request
def _set_overlapped_by_message(self, request: HttpRequest):
geom_conflicts = self.geometry.conflicted_by_geometries.all()
if geom_conflicts:
data_objs = []
for conflict in geom_conflicts:
data_objs += conflict.conflicting_geometry.get_data_objects()
data_identifiers = [x.identifier for x in data_objs]
data_identifiers = ", ".join(data_identifiers)
message_str = GEOMETRY_OVERLAPPED_BY_TEMPLATE.format(data_identifiers)
messages.info(request, message_str)
return request

@ -28,5 +28,4 @@ ADDED_DEADLINE = _("Added deadline")
ADDED_COMPENSATION_ACTION = _("Added compensation action") ADDED_COMPENSATION_ACTION = _("Added compensation action")
# Geometry conflicts # Geometry conflicts
GEOMETRY_OVERLAPS_WITH_TEMPLATE = _("Geometry overlaps {}") GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}")
GEOMETRY_OVERLAPPED_BY_TEMPLATE = _("Geometry overlapped by {}")

Loading…
Cancel
Save