summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
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
commit1205622c9acfef772a73c15352a4fa812ca7e358 (patch)
tree00b6f9ca825f89ba76900c3095e9191410c5451f /ishtar_common/models.py
parentb93a677cc30d92a0efa0ca8be52614ed1eb67329 (diff)
downloadIshtar-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.py65
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)]