Geometry simplification
* simplifies geometries on SimpleGeomForm if threshold GEOM_MAX_VERTICES has been exceeded
* geometry is iteratively simplified to find a proper tolerance value which satisfies the GEOM_MAX_VERTICES threshold
This commit is contained in:
@@ -15,6 +15,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.forms.base_form import BaseForm
|
||||
from konova.models import Geometry
|
||||
from konova.settings import GEOM_MAX_VERTICES
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
|
||||
from user.models import UserActionLogEntry
|
||||
@@ -25,6 +26,7 @@ class SimpleGeomForm(BaseForm):
|
||||
|
||||
"""
|
||||
read_only = True
|
||||
geometry_simplified = False
|
||||
geom = MultiPolygonField(
|
||||
srid=DEFAULT_SRID_RLP,
|
||||
label=_("Geometry"),
|
||||
@@ -124,6 +126,38 @@ class SimpleGeomForm(BaseForm):
|
||||
|
||||
return is_valid
|
||||
|
||||
def __is_vertices_num_valid(self):
|
||||
""" Checks whether the number of vertices in the geometry is not too high
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
geom = self.cleaned_data.get("geom")
|
||||
g = gdal.OGRGeometry(geom, srs=DEFAULT_SRID_RLP)
|
||||
num_vertices = g.num_coords
|
||||
|
||||
return num_vertices <= GEOM_MAX_VERTICES
|
||||
|
||||
def __simplify_geometry(self, geom, max_vert: int):
|
||||
""" Simplifies a geometry
|
||||
|
||||
Geometry will be simplified until a threshold of max vertices has been reached.
|
||||
|
||||
Args:
|
||||
geom (MultiPolygon): The geometry
|
||||
max_vert (int): Threshold of maximum vertices in geometry
|
||||
|
||||
Returns:
|
||||
geom (MultiPolygon): The simplified geometry
|
||||
"""
|
||||
tolerance = 0.1
|
||||
n = geom.num_coords
|
||||
while(n > max_vert):
|
||||
geom = geom.simplify(tolerance)
|
||||
n = geom.num_coords
|
||||
tolerance += 0.1
|
||||
return geom
|
||||
|
||||
def save(self, action: UserActionLogEntry):
|
||||
""" Saves the form's geometry
|
||||
|
||||
@@ -149,6 +183,13 @@ class SimpleGeomForm(BaseForm):
|
||||
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP)),
|
||||
created=action,
|
||||
)
|
||||
|
||||
is_vertices_num_valid = self.__is_vertices_num_valid()
|
||||
if not is_vertices_num_valid:
|
||||
geometry.geom = self.__simplify_geometry(geometry.geom, max_vert=GEOM_MAX_VERTICES)
|
||||
geometry.save()
|
||||
self.geometry_simplified = True
|
||||
|
||||
# Start parcel update and geometry conflict checking procedure in a background process
|
||||
celery_update_parcels.delay(geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(geometry.id)
|
||||
|
||||
@@ -44,3 +44,5 @@ STRF_DATE_TIME = "%d.%m.%Y %H:%M:%S"
|
||||
DEFAULT_GROUP = "Default"
|
||||
ZB_GROUP = "Registration office"
|
||||
ETS_GROUP = "Conservation office"
|
||||
|
||||
GEOM_MAX_VERTICES = 10000
|
||||
|
||||
@@ -7,6 +7,8 @@ Created on: 02.08.21
|
||||
"""
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.settings import GEOM_MAX_VERTICES
|
||||
|
||||
NO_DETAILS = _("no further details")
|
||||
UNKNOWN = _("Unknown")
|
||||
UNGROUPED = _("Ungrouped")
|
||||
@@ -79,8 +81,9 @@ DOCUMENT_EDITED = _("Document edited")
|
||||
EDITED_GENERAL_DATA = _("Edited general data")
|
||||
ADDED_DEADLINE = _("Added deadline")
|
||||
|
||||
# Geometry conflicts
|
||||
# Geometry
|
||||
GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}")
|
||||
GEOMETRY_SIMPLIFIED = _("The geometry contained more than {} vertices. It had to be simplified to match the allowed limit of {} vertices.").format(GEOM_MAX_VERTICES, GEOM_MAX_VERTICES)
|
||||
|
||||
# INTERVENTION
|
||||
INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations")
|
||||
|
||||
Reference in New Issue
Block a user