summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_context_records/migrations/0040_auto_20190206_1423.py35
-rw-r--r--archaeological_context_records/models.py17
-rw-r--r--archaeological_finds/migrations/0060_auto_20190206_1423.py35
-rw-r--r--archaeological_finds/models_finds.py15
-rw-r--r--archaeological_operations/migrations/0050_auto_20190206_1423.py55
-rw-r--r--archaeological_operations/models.py36
-rw-r--r--ishtar_common/tests.py4
-rw-r--r--ishtar_common/utils.py84
8 files changed, 256 insertions, 25 deletions
diff --git a/archaeological_context_records/migrations/0040_auto_20190206_1423.py b/archaeological_context_records/migrations/0040_auto_20190206_1423.py
new file mode 100644
index 000000000..b3c5a6837
--- /dev/null
+++ b/archaeological_context_records/migrations/0040_auto_20190206_1423.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2019-02-06 14:23
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_context_records', '0039_auto_20190122_1550'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='contextrecord',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='contextrecord',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ migrations.AddField(
+ model_name='historicalcontextrecord',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='historicalcontextrecord',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ ]
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index 89526076a..4b41fddb7 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -28,7 +28,7 @@ from django.utils.translation import ugettext_lazy as _, pgettext, \
from django.utils.text import slugify
from ishtar_common.utils import cached_label_changed, \
- m2m_historization_changed, post_save_point
+ m2m_historization_changed, post_save_geo
from ishtar_common.models import Document, GeneralType, \
BaseHistorizedItem, HistoricalRecords, OwnPerms, ShortMenuItem, \
@@ -485,8 +485,16 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,
blank=True, null=True)
point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True)
point = models.PointField(_(u"Point (3D)"), blank=True, null=True, dim=3)
+ point_source = models.CharField(
+ _(u"Point source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,
null=True)
+ multi_polygon_source = models.CharField(
+ _(u"Multi-polygon source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
documents = models.ManyToManyField(
Document, related_name='context_records', verbose_name=_(u"Documents"),
blank=True)
@@ -528,6 +536,11 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,
return self.town.center
return self.operation.get_town_centroid()
+ def get_town_polygons(self):
+ if self.town:
+ return self.town.limit
+ return self.operation.get_town_polygon()
+
@classmethod
def cached_label_bulk_update(cls, operation_id=None, parcel_id=None,
transaction_id=None):
@@ -752,7 +765,7 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,
def context_record_post_save(sender, **kwargs):
cached_label_changed(sender=sender, **kwargs)
- post_save_point(sender=sender, **kwargs)
+ post_save_geo(sender=sender, **kwargs)
post_save.connect(context_record_post_save, sender=ContextRecord)
diff --git a/archaeological_finds/migrations/0060_auto_20190206_1423.py b/archaeological_finds/migrations/0060_auto_20190206_1423.py
new file mode 100644
index 000000000..6ddfa5145
--- /dev/null
+++ b/archaeological_finds/migrations/0060_auto_20190206_1423.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2019-02-06 14:23
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0059_auto_20190204_1134'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='basefind',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='basefind',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ migrations.AddField(
+ model_name='historicalbasefind',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='historicalbasefind',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ ]
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index da872ab53..3f0ade1df 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -30,7 +30,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _, pgettext_lazy\
from ishtar_common.data_importer import post_importer_action, ImporterError
-from ishtar_common.utils import cached_label_changed, post_save_point, \
+from ishtar_common.utils import cached_label_changed, post_save_geo, \
m2m_historization_changed
from ishtar_common.alternative_configs import ALTERNATE_CONFIGS
@@ -306,9 +306,17 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):
blank=True, null=True)
point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True)
point = models.PointField(_(u"Point (3D)"), blank=True, null=True, dim=3)
+ point_source = models.CharField(
+ _(u"Point source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
line = models.LineStringField(_(u"Line"), blank=True, null=True)
multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,
null=True)
+ multi_polygon_source = models.CharField(
+ _(u"Multi-polygon source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
cache_short_id = models.TextField(
_(u"Short ID"), blank=True, null=True, db_index=True,
help_text=_(u"Cached value - do not edit"))
@@ -357,6 +365,9 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):
def get_town_centroid(self):
return self.context_record.get_town_centroid()
+ def get_town_polygons(self):
+ return self.context_record.get_town_polygons()
+
def generate_index(self):
"""
Generate index based on operation or context record (based on
@@ -592,7 +603,7 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):
def post_save_basefind(sender, **kwargs):
cached_label_changed(sender, **kwargs)
- post_save_point(sender, **kwargs)
+ post_save_geo(sender, **kwargs)
post_save.connect(post_save_basefind, sender=BaseFind)
diff --git a/archaeological_operations/migrations/0050_auto_20190206_1423.py b/archaeological_operations/migrations/0050_auto_20190206_1423.py
new file mode 100644
index 000000000..a632b6059
--- /dev/null
+++ b/archaeological_operations/migrations/0050_auto_20190206_1423.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2019-02-06 14:23
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_operations', '0049_auto_20190122_1621'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='archaeologicalsite',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='archaeologicalsite',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ migrations.AddField(
+ model_name='historicalarchaeologicalsite',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='historicalarchaeologicalsite',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ migrations.AddField(
+ model_name='historicaloperation',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='historicaloperation',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ migrations.AddField(
+ model_name='operation',
+ name='multi_polygon_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Multi-polygon source'),
+ ),
+ migrations.AddField(
+ model_name='operation',
+ name='point_source',
+ field=models.CharField(blank=True, choices=[(b'T', 'Commune'), (b'P', 'Precise')], max_length=1, null=True, verbose_name='Point source'),
+ ),
+ ]
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index a8f1d4faf..2335155ed 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -41,7 +41,7 @@ from ishtar_common.models import BaseHistorizedItem, Dashboard, \
document_attached_changed, HistoryModel, SearchAltName, \
SpatialReferenceSystem
from ishtar_common.utils import cached_label_changed, \
- force_cached_label_changed, mode, m2m_historization_changed, post_save_point
+ force_cached_label_changed, mode, m2m_historization_changed, post_save_geo
class RemainType(GeneralType):
@@ -277,8 +277,16 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
blank=True, null=True)
point = models.PointField(_(u"Point"), blank=True, null=True, dim=3)
point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True)
+ point_source = models.CharField(
+ _(u"Point source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,
null=True)
+ multi_polygon_source = models.CharField(
+ _(u"Multi-polygon source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
documents = models.ManyToManyField(
Document, related_name="sites", verbose_name=_(u"Documents"),
@@ -392,6 +400,13 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
return None
return q.all()[0].centroid
+ def get_town_polygons(self):
+ q = self.towns.filter(limit__isnull=False).annotate(
+ poly=Union('limit')).all()
+ if not q.count():
+ return None
+ return q.all()[0].poly
+
def _get_base_image_path(self):
return u"{}/{}".format(self.SLUG, self.reference)
@@ -447,7 +462,7 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,
def site_post_save(sender, **kwargs):
cached_label_changed(sender=sender, **kwargs)
- post_save_point(sender=sender, **kwargs)
+ post_save_geo(sender=sender, **kwargs)
post_save.connect(site_post_save, sender=ArchaeologicalSite)
@@ -940,8 +955,16 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
blank=True, null=True)
point = models.PointField(_(u"Point"), blank=True, null=True, dim=3)
point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True)
+ point_source = models.CharField(
+ _(u"Point source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,
null=True)
+ multi_polygon_source = models.CharField(
+ _(u"Multi-polygon source"),
+ choices=(('T', _(u"Town")), ('P', _(u"Precise"))), max_length=1,
+ blank=True, null=True)
history = HistoricalRecords(bases=[HistoryModel])
class Meta:
@@ -1115,6 +1138,13 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
return None
return q.all()[0].centroid
+ def get_town_polygons(self):
+ q = self.towns.filter(limit__isnull=False).annotate(
+ poly=Union('limit')).all()
+ if not q.count():
+ return None
+ return q.all()[0].poly
+
def context_record_relations_q(self):
from archaeological_context_records.models \
import RecordRelations as CRRL
@@ -1464,7 +1494,7 @@ for attr in Operation.HISTORICAL_M2M:
def operation_post_save(sender, **kwargs):
if not kwargs['instance']:
return
- post_save_point(sender=sender, **kwargs)
+ post_save_geo(sender=sender, **kwargs)
operation = kwargs['instance']
operation.skip_history_when_saving = True
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index 8ecf98255..53ad67faa 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -45,7 +45,7 @@ from django.test.runner import DiscoverRunner
from ishtar_common import models
from ishtar_common import views
from ishtar_common.apps import admin_site
-from ishtar_common.utils import post_save_point, update_data, move_dict_data, \
+from ishtar_common.utils import post_save_geo, update_data, move_dict_data, \
rename_and_simplify_media_name, try_fix_file
@@ -1589,7 +1589,7 @@ class GeomaticTest(TestCase):
x=2, y=3, z=4,
spatial_reference_system=srs)
self.assertIsNone(obj.point_2d)
- post_save_point(None, instance=obj)
+ post_save_geo(None, instance=obj)
self.assertIsNotNone(obj.point_2d)
self.assertIsNotNone(obj.point)
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 20957c43e..0f33fd30d 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -469,10 +469,11 @@ def convert_coordinates_to_point(x, y, z=None, srid=4326):
return geom
-def post_save_point(sender, **kwargs):
+def post_save_geo(sender, **kwargs):
"""
Convert raw x, y, z point to real geo field
"""
+ from ishtar_common.models import SpatialReferenceSystem
if not kwargs.get('instance'):
return
instance = kwargs.get('instance')
@@ -481,21 +482,72 @@ def post_save_point(sender, **kwargs):
from ishtar_common.models import get_current_profile # not clean but utils
# must be loaded before models
profile = get_current_profile()
- if instance.x and instance.y and \
- instance.spatial_reference_system and \
- instance.spatial_reference_system.auth_name == 'EPSG' and \
- instance.spatial_reference_system.srid != 0:
- point_2d = convert_coordinates_to_point(
- instance.x, instance.y, srid=instance.spatial_reference_system.srid)
- if instance.z:
- point = convert_coordinates_to_point(
- instance.x, instance.y, instance.z,
- srid=instance.spatial_reference_system.srid)
- elif profile.use_town_for_geo:
- point_2d = instance.get_town_centroid()
- if point_2d != instance.point_2d or point != instance.point:
- instance.point = point
- instance.point_2d = point_2d
+ modified = False
+
+ if (point or point_2d) and instance.x is None: # db source
+ if point:
+ current_point = point
+ instance.z = point.z
+ else:
+ current_point = point_2d
+ instance.x = current_point.x
+ instance.y = current_point.y
+ try:
+ srs = SpatialReferenceSystem.objects.get(
+ srid=int(current_point.srid))
+ except SpatialReferenceSystem.DoesNotExist:
+ srs = SpatialReferenceSystem.objects.create(
+ srid=int(current_point.srid),
+ auth_name='EPSG',
+ label=u"EPSG-{}".format(current_point.srid),
+ txt_idx=u"epsg-{}".format(current_point.srid),
+ )
+ instance.spatial_reference_system = srs
+ instance.point_source = 'P'
+ if not point_2d:
+ instance.point_2d = convert_coordinates_to_point(
+ instance.point.x, instance.point.y,
+ srid=current_point.srid)
+ elif not point_2d:
+ source = None
+ if instance.x and instance.y and \
+ instance.spatial_reference_system and \
+ instance.spatial_reference_system.auth_name == 'EPSG' and \
+ instance.spatial_reference_system.srid != 0: # form input
+ try:
+ point_2d = convert_coordinates_to_point(
+ instance.x, instance.y,
+ srid=instance.spatial_reference_system.srid)
+ except forms.ValidationError:
+ return # irrelevant data in DB
+ if point_2d:
+ source = 'P' # precise
+ if instance.z:
+ point = convert_coordinates_to_point(
+ instance.x, instance.y, instance.z,
+ srid=instance.spatial_reference_system.srid)
+ elif profile.use_town_for_geo: #
+ point_2d = instance.get_town_centroid()
+ source = 'T' # town
+
+ if point_2d != instance.point_2d or point != instance.point:
+ instance.point = point
+ instance.point_2d = point_2d
+ instance.point_source = source
+ modified = True
+
+ if instance.multi_polygon and not instance.multi_polygon_source:
+ # should be a db source
+ instance.multi_polygon_source = 'P'
+ modified = True
+ elif profile.use_town_for_geo and instance.multi_polygon_source != 'P':
+ poly = instance.get_town_polygons()
+ if poly and poly != instance.multi_polygon:
+ instance.multi_polygon_source = 'T' # town
+ instance.multi_polygon = poly
+ modified = True
+
+ if modified:
instance.skip_history_when_saving = True
instance.save()
return