konova/konova/management/commands/update_all_parcels.py
mpeltriaux dd5cbbef10 Merge branch 'master' into 132_Old_entries
# Conflicts:
#	konova/management/commands/update_all_parcels.py
#	konova/urls.py
#	user/admin.py
2022-06-01 13:12:35 +02:00

75 lines
2.8 KiB
Python

"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 04.01.22
"""
import datetime
from pyexpat import ExpatError
from requests.exceptions import ProxyError
from django.contrib.gis.db.models.functions import Area
from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Geometry, Parcel, District
class Command(BaseKonovaCommand):
help = "Checks the database' sanity and removes unused entries"
def handle(self, *args, **options):
try:
self.update_parcels()
except KeyboardInterrupt:
self._break_line()
exit(-1)
def update_parcels(self, ids: list = None):
""" Updates all geometry-parcel relations using an official parcel WFS.
THIS METHOD SHOULD NOT BE RUN IN PARALLEL E.G. USING CELERY DUE TO POSSIBLE PARCEL-CONFLICTS ON THE DB
"""
num_parcels_before = Parcel.objects.count()
num_districts_before = District.objects.count()
self._write_warning("=== Update parcels and districts ===")
# Order geometries by size to process smaller once at first
geometries = Geometry.objects.all().exclude(
geom=None
).annotate(area=Area("geom")).order_by(
'area'
)
if ids is not None:
self._write_warning(f"Retry parcel calculation for {len(ids)} geometry entries now ...")
geometries = geometries.filter(id__in=ids)
total_count = geometries.count()
self._write_warning(f"Process parcels for {total_count} geometry entries now ...")
i = 0
try_again_ids = []
for geometry in geometries:
if i % 500 == 0:
self._write_warning(f"--- {i}/{total_count} processed")
try:
geometry.update_parcels()
except Exception as e:
self._write_error(f"--- {geometry.id} encountered an error: {e}. Geometry added to the retry list.")
try_again_ids.append(geometry.id)
i += 1
if len(try_again_ids) > 0:
self.update_parcels(try_again_ids)
num_parcels_after = Parcel.objects.count()
num_districts_after = District.objects.count()
if num_parcels_after != num_parcels_before:
self._write_error(f"Parcels have changed: {num_parcels_before} to {num_parcels_after} entries. You should run the sanitize command.")
if num_districts_after != num_districts_before:
self._write_error(f"Districts have changed: {num_districts_before} to {num_districts_after} entries. You should run the sanitize command.")
self._write_success("Updating parcels done!")
self._break_line()