diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-02-17 13:03:40 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-12-12 12:21:00 +0100 |
commit | 1205622c9acfef772a73c15352a4fa812ca7e358 (patch) | |
tree | 00b6f9ca825f89ba76900c3095e9191410c5451f /ishtar_common/models.py | |
parent | b93a677cc30d92a0efa0ca8be52614ed1eb67329 (diff) | |
download | Ishtar-1205622c9acfef772a73c15352a4fa812ca7e358.tar.bz2 Ishtar-1205622c9acfef772a73c15352a4fa812ca7e358.zip |
Geodata redesign: operation migrations (1/2) - operation geo post save - town area creation
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r-- | ishtar_common/models.py | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py index a03b90434..a1f91282e 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -52,6 +52,7 @@ from django.contrib.auth.models import User, Group from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.contrib.gis.db import models +from django.contrib.gis.db.models.aggregates import Union from django.contrib.postgres.fields import JSONField from django.contrib.postgres.indexes import GinIndex from django.contrib.sites.models import Site @@ -141,6 +142,8 @@ from ishtar_common.models_common import ( SearchAltName, DynamicRequest, GeoItem, + GeoDataType, + GeoVectorData, CompleteIdentifierItem, SearchVectorConfig, DocumentItem, @@ -2251,8 +2254,8 @@ class Area(HierarchicalType): ) class Meta: - verbose_name = _("Area") - verbose_name_plural = _("Areas") + verbose_name = _("Town - Area") + verbose_name_plural = _("Town - Areas") ordering = ("label",) def __str__(self): @@ -2260,6 +2263,64 @@ class Area(HierarchicalType): return self.label return "{} ({})".format(self.label, self.reference) + @classmethod + def get_or_create_by_towns(cls, towns, get_geo=False): + if hasattr(towns, "all"): # queryset + if not towns.count(): + return + towns = towns.all() + elif not len(towns): + return + name = [] + reference = [] + for town in sorted(towns, key=lambda x: (x.numero_insee, x.name)): + name.append(town._generate_cached_label()) + reference.append(town.numero_insee or slugify(town.name)) + name = " / ".join(name) + reference = f"{_('area')}-{'/'.join(reference)}" + area, created = cls.objects.get_or_create( + reference=reference, + defaults={"label": name} + ) + + area_content_type = ContentType.objects.get(app_label="ishtar_common", + model="area") + attrs = { + "source_content_type": area_content_type, + "source_id": area.pk, + } + q = GeoVectorData.objects.filter(**attrs) + if created or not q.count(): + data_type, __ = GeoDataType.objects.get_or_create( + txt_idx="area-limit", + defaults={"label": str(_("Communal area boundaries"))} + ) + attrs["data_type"] = data_type + geo = GeoVectorData.objects.create(**attrs) + else: + geo = q.all()[0] + + q_poly_towns = GeoVectorData.objects.filter( + source_content_type__app_label="ishtar_common", + source_content_type__model="town", + source_id__in=[t.pk for t in towns]) + q_poly = q_poly_towns.annotate(poly=Union("multi_polygon")) + poly = q_poly.all()[0].poly + if not geo.multi_polygon or not geo.multi_polygon.equals_exact(poly, 0.001): + origins, providers = [], [] + for g in q_poly_towns: + origins.append(g.origin) + providers.append(g.provider) + if len(set(origins)) == 1: # no ambiguous origin + geo.origin = origins[0] + if len(set(providers)) == 1: # no ambiguous provider + geo.provider = providers[0] + geo.multi_polygon = poly + geo.save() + if get_geo: + return geo + return area + @property def full_label(self): label = [str(self)] |