#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
This commit is contained in:
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…
Reference in New Issue
Block a user