* improves the way parcel-geometry relations are stored on the DB * instead of a numerical sequence we switched to UUID, so no sequence will run out at anytime (new model: ParcelIntersection) * instead of dropping all M2M relations between parcel and geometry on each calculation, we keep the ones that still exist, drop the ones that do not exist and add new ones (if new ones exist)
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
"""
|
|
Author: Michel Peltriaux
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
|
Created on: 16.12.21
|
|
|
|
"""
|
|
from django.db import models
|
|
|
|
from konova.models import UuidModel
|
|
|
|
|
|
class Parcel(UuidModel):
|
|
""" The Parcel model holds administrative data on the covered properties.
|
|
|
|
Due to the unique but relevant naming of the administrative data, we have to use these namings as field
|
|
names in german. Any try to translate them to English result in strange or insufficient translations.
|
|
|
|
All fields have to be CharFields as well, since there are e.g. Flurstücksnummer holding e.g. '123____' which
|
|
can not be realized using numerical fields.
|
|
|
|
To avoid conflicts due to german Umlaute, the field names are shortened and vocals are dropped.
|
|
|
|
"""
|
|
geometries = models.ManyToManyField("konova.Geometry", blank=True, related_name="parcels", through='ParcelIntersection')
|
|
district = models.ForeignKey("konova.District", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels")
|
|
gmrkng = models.CharField(
|
|
max_length=1000,
|
|
help_text="Gemarkung",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
flrstck_nnr = models.CharField(
|
|
max_length=1000,
|
|
help_text="Flurstücksnenner",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
flrstck_zhlr = models.CharField(
|
|
max_length=1000,
|
|
help_text="Flurstückszähler",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
flr = models.CharField(
|
|
max_length=1000,
|
|
help_text="Flur",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
updated_on = models.DateTimeField(auto_now_add=True)
|
|
|
|
def __str__(self):
|
|
return f"{self.gmrkng} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}"
|
|
|
|
|
|
class District(UuidModel):
|
|
""" The model District holds more coarse information, such as Kreis, Verbandsgemeinde and Gemeinde.
|
|
|
|
There might be the case that a geometry lies on a hundred Parcel entries but only on one District entry.
|
|
Therefore a geometry can have a lot of relations to Parcel entries but only a few or only a single one to one
|
|
District.
|
|
|
|
"""
|
|
gmnd = models.CharField(
|
|
max_length=1000,
|
|
help_text="Gemeinde",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
krs = models.CharField(
|
|
max_length=1000,
|
|
help_text="Kreis",
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
|
|
def __str__(self):
|
|
return f"{self.gmnd} | {self.krs}"
|
|
|
|
|
|
class ParcelIntersection(UuidModel):
|
|
""" ParcelIntersection is an intermediary model, which is used to configure the
|
|
M2M relation between Parcel and Geometry.
|
|
|
|
Based on uuids, we will not have (practically) any problems on outrunning primary keys
|
|
and extending the model with calculated_on timestamp, we can 'hide' entries while they
|
|
are being recalculated and keep track on the last time they have been calculated this
|
|
way.
|
|
|
|
Please note: The calculated_on describes when the relation between the Parcel and the Geometry
|
|
has been established. The updated_on field of Parcel describes when this Parcel has been
|
|
changed the last time.
|
|
|
|
"""
|
|
parcel = models.ForeignKey(Parcel, on_delete=models.CASCADE)
|
|
geometry = models.ForeignKey("konova.Geometry", on_delete=models.CASCADE)
|
|
calculated_on = models.DateTimeField(auto_now_add=True, null=True, blank=True)
|