# Conflicts: # konova/management/commands/update_all_parcels.py # konova/urls.py # user/admin.py
75 lines
2.8 KiB
Python
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()
|