diff options
| -rw-r--r-- | archaeological_context_records/forms.py | 16 | ||||
| -rw-r--r-- | archaeological_context_records/migrations/0038_auto_20190122_1550.py | 87 | ||||
| -rw-r--r-- | archaeological_context_records/models.py | 29 | ||||
| -rw-r--r-- | archaeological_finds/models_finds.py | 5 | ||||
| -rw-r--r-- | archaeological_operations/forms.py | 30 | ||||
| -rw-r--r-- | archaeological_operations/migrations/0046_auto_20190122_1550.py | 178 | ||||
| -rw-r--r-- | archaeological_operations/migrations/0047_point_to_point_2d.py | 27 | ||||
| -rw-r--r-- | archaeological_operations/migrations/0048_auto_20190122_1621.py | 36 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 60 | ||||
| -rw-r--r-- | ishtar_common/migrations/0084_ishtarsiteprofile_use_town_for_geo.py | 20 | ||||
| -rw-r--r-- | ishtar_common/models.py | 2 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 9 | 
12 files changed, 487 insertions, 12 deletions
diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py index ae25e0abe..7566dcc71 100644 --- a/archaeological_context_records/forms.py +++ b/archaeological_context_records/forms.py @@ -33,7 +33,7 @@ from archaeological_context_records import models  from ishtar_common.forms import FinalForm, FormSet, \      reverse_lazy, get_form_selection, TableSelect, ManageOldType, CustomForm, \ -    FieldType, CustomFormSearch, IshtarForm, HistorySelect +    FieldType, CustomFormSearch, IshtarForm, FormHeader, HistorySelect  from ishtar_common.forms_common import get_town_field  from archaeological_operations.forms import OperationSelect, ParcelField, \      RecordRelationsForm as OpeRecordRelationsForm, RecordRelationsFormSetBase @@ -135,6 +135,7 @@ class RecordFormSelection(CustomFormSearch):  class RecordFormGeneral(CustomForm, ManageOldType): +    HEADERS = {}      form_label = _("General")      form_admin_name = _(u"Context record - 020 - General")      form_slug = "contextrecord-020-general" @@ -182,6 +183,19 @@ class RecordFormGeneral(CustomForm, ManageOldType):          label=_(u"Location"), widget=forms.Textarea,          required=False, validators=[validators.MaxLengthValidator(200)]) +    HEADERS['x'] = FormHeader(_(u"Coordinates")) +    x = forms.FloatField(label=_(u"X"), required=False) +    estimated_error_x = forms.FloatField(label=_(u"Estimated error for X"), +                                         required=False) +    y = forms.FloatField(label=_(u"Y"), required=False) +    estimated_error_y = forms.FloatField(label=_(u"Estimated error for Y"), +                                         required=False) +    z = forms.FloatField(label=_(u"Z"), required=False) +    estimated_error_z = forms.FloatField(label=_(u"Estimated error for Z"), +                                         required=False) +    spatial_reference_system = forms.ChoiceField( +        label=_(u"Spatial Reference System"), required=False, choices=[]) +      TYPES = [          FieldType('unit', models.Unit),          FieldType('excavation_technic', models.ExcavationTechnicType), diff --git a/archaeological_context_records/migrations/0038_auto_20190122_1550.py b/archaeological_context_records/migrations/0038_auto_20190122_1550.py new file mode 100644 index 000000000..c7777dfd8 --- /dev/null +++ b/archaeological_context_records/migrations/0038_auto_20190122_1550.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2019-01-22 15:50 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0084_ishtarsiteprofile_use_town_for_geo'), +        ('archaeological_context_records', '0037_auto_20190118_1203'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='contextrecord', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SpatialReferenceSystem', verbose_name='Syst\xe8me de r\xe9f\xe9rence spatiale'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='contextrecord', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SpatialReferenceSystem'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +    ] diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index cb6dbc635..89526076a 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -27,14 +27,15 @@ from django.utils.translation import ugettext_lazy as _, pgettext, \      activate, pgettext_lazy, deactivate  from django.utils.text import slugify -from ishtar_common.utils import cached_label_changed, m2m_historization_changed +from ishtar_common.utils import cached_label_changed, \ +    m2m_historization_changed, post_save_point  from ishtar_common.models import Document, GeneralType, \      BaseHistorizedItem, HistoricalRecords, OwnPerms, ShortMenuItem, \      GeneralRelationType, GeneralRecordRelations, post_delete_record_relation,\      post_save_cache, ValueGetter, BulkUpdatedItem, ExternalIdManager, \      RelationItem, Town, get_current_profile, document_attached_changed, \ -    HistoryModel, SearchAltName +    HistoryModel, SearchAltName, SpatialReferenceSystem  from archaeological_operations.models import Operation, Period, Parcel, \      ArchaeologicalSite @@ -470,6 +471,18 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,          verbose_name=_(u"Excavation technique"))      related_context_records = models.ManyToManyField(          'ContextRecord', through='RecordRelations', blank=True) +    x = models.FloatField(_(u'X'), blank=True, null=True) +    y = models.FloatField(_(u'Y'), blank=True, null=True) +    z = models.FloatField(_(u'Z'), blank=True, null=True) +    estimated_error_x = models.FloatField(_(u'Estimated error for X'), +                                          blank=True, null=True) +    estimated_error_y = models.FloatField(_(u'Estimated error for Y'), +                                          blank=True, null=True) +    estimated_error_z = models.FloatField(_(u'Estimated error for Z'), +                                          blank=True, null=True) +    spatial_reference_system = models.ForeignKey( +        SpatialReferenceSystem, verbose_name=_(u"Spatial Reference System"), +        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)      multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True, @@ -510,6 +523,11 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,      def __unicode__(self):          return self.short_label +    def get_town_centroid(self): +        if self.town: +            return self.town.center +        return self.operation.get_town_centroid() +      @classmethod      def cached_label_bulk_update(cls, operation_id=None, parcel_id=None,                                   transaction_id=None): @@ -732,7 +750,12 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem,              self.save() -post_save.connect(cached_label_changed, sender=ContextRecord) +def context_record_post_save(sender, **kwargs): +    cached_label_changed(sender=sender, **kwargs) +    post_save_point(sender=sender, **kwargs) + + +post_save.connect(context_record_post_save, sender=ContextRecord)  m2m_changed.connect(document_attached_changed,                      sender=ContextRecord.documents.through) diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 15b6451d6..fce9548ba 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -354,6 +354,11 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):                  return find          return +    def get_town_centroid(self): +        if self.context_record.town: +            return self.context_record.town.get_town_centroid() +        return self.context_record.operation.get_town_centroid() +      def generate_index(self):          """          Generate index based on operation or context record (based on diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index b093b383c..f964375c7 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -40,7 +40,7 @@ from bootstrap_datepicker.widgets import DateField  from ishtar_common import widgets  from ishtar_common.forms import FinalForm, FormSet, get_now, \      reverse_lazy, TableSelect, get_data_from_formset, \ -    ManageOldType, IshtarForm, CustomForm, FieldType, HistorySelect +    ManageOldType, IshtarForm, CustomForm, FieldType, FormHeader, HistorySelect  from ishtar_common.forms_common import TownFormSet, get_town_field, TownForm  from ishtar_common.models import valid_id, Person, Town, \      DocumentTemplate, Organization, get_current_profile, \ @@ -741,6 +741,7 @@ class DashboardForm(IshtarForm):  class OperationFormGeneral(CustomForm, ManageOldType): +    HEADERS = {}      form_label = _(u"General")      form_admin_name = _(u"Operation - 010 - General")      form_slug = "operation-010-general" @@ -856,6 +857,19 @@ class OperationFormGeneral(CustomForm, ManageOldType):      virtual_operation = forms.BooleanField(required=False,                                             label=_(u"Virtual operation")) +    HEADERS['x'] = FormHeader(_(u"Coordinates")) +    x = forms.FloatField(label=_(u"X"), required=False) +    estimated_error_x = forms.FloatField(label=_(u"Estimated error for X"), +                                         required=False) +    y = forms.FloatField(label=_(u"Y"), required=False) +    estimated_error_y = forms.FloatField(label=_(u"Estimated error for Y"), +                                         required=False) +    z = forms.FloatField(label=_(u"Z"), required=False) +    estimated_error_z = forms.FloatField(label=_(u"Estimated error for Z"), +                                         required=False) +    spatial_reference_system = forms.ChoiceField( +        label=_(u"Spatial Reference System"), required=False, choices=[]) +      FILE_FIELDS = [          'report_delivery_date',          'report_processing', @@ -1154,6 +1168,7 @@ class PeriodForm(CustomForm, ManageOldType, forms.Form):  class ArchaeologicalSiteForm(ManageOldType): +    HEADERS = {}      reference = forms.CharField(label=_(u"Reference"), max_length=200)      name = forms.CharField(label=_(u"Name"), max_length=200, required=False)      periods = forms.MultipleChoiceField( @@ -1162,6 +1177,19 @@ class ArchaeologicalSiteForm(ManageOldType):      remains = forms.MultipleChoiceField(          label=_("Remains"), choices=[], widget=widgets.Select2Multiple,          required=False) +    HEADERS['x'] = FormHeader(_(u"Coordinates")) +    x = forms.FloatField(label=_(u"X"), required=False) +    estimated_error_x = forms.FloatField(label=_(u"Estimated error for X"), +                                         required=False) +    y = forms.FloatField(label=_(u"Y"), required=False) +    estimated_error_y = forms.FloatField(label=_(u"Estimated error for Y"), +                                         required=False) +    z = forms.FloatField(label=_(u"Z"), required=False) +    estimated_error_z = forms.FloatField(label=_(u"Estimated error for Z"), +                                         required=False) +    spatial_reference_system = forms.ChoiceField( +        label=_(u"Spatial Reference System"), required=False, choices=[]) +      TYPES = [          FieldType('periods', models.Period, True), diff --git a/archaeological_operations/migrations/0046_auto_20190122_1550.py b/archaeological_operations/migrations/0046_auto_20190122_1550.py new file mode 100644 index 000000000..4a352a970 --- /dev/null +++ b/archaeological_operations/migrations/0046_auto_20190122_1550.py @@ -0,0 +1,178 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2019-01-22 15:50 +from __future__ import unicode_literals + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0084_ishtarsiteprofile_use_town_for_geo'), +        ('archaeological_operations', '0045_auto_20190118_1203'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='archaeologicalsite', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='point_2d', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='Point (2D)'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SpatialReferenceSystem', verbose_name='Syst\xe8me de r\xe9f\xe9rence spatiale'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='point_2d', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='Point (2D)'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SpatialReferenceSystem'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='historicalarchaeologicalsite', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='point_2d', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='Point (2D)'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='ishtar_common.SpatialReferenceSystem'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +        migrations.AddField( +            model_name='operation', +            name='estimated_error_x', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour X'), +        ), +        migrations.AddField( +            model_name='operation', +            name='estimated_error_y', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Y'), +        ), +        migrations.AddField( +            model_name='operation', +            name='estimated_error_z', +            field=models.FloatField(blank=True, null=True, verbose_name='Erreur estim\xe9e pour Z'), +        ), +        migrations.AddField( +            model_name='operation', +            name='point_2d', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326, verbose_name='Point (2D)'), +        ), +        migrations.AddField( +            model_name='operation', +            name='spatial_reference_system', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.SpatialReferenceSystem', verbose_name='Syst\xe8me de r\xe9f\xe9rence spatiale'), +        ), +        migrations.AddField( +            model_name='operation', +            name='x', +            field=models.FloatField(blank=True, null=True, verbose_name='X'), +        ), +        migrations.AddField( +            model_name='operation', +            name='y', +            field=models.FloatField(blank=True, null=True, verbose_name='Y'), +        ), +        migrations.AddField( +            model_name='operation', +            name='z', +            field=models.FloatField(blank=True, null=True, verbose_name='Z'), +        ), +    ] diff --git a/archaeological_operations/migrations/0047_point_to_point_2d.py b/archaeological_operations/migrations/0047_point_to_point_2d.py new file mode 100644 index 000000000..7750fb88a --- /dev/null +++ b/archaeological_operations/migrations/0047_point_to_point_2d.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2019-01-22 15:54 +from __future__ import unicode_literals + +from django.db import migrations + + +def point_to_point_2d(apps, schema_editor): +    ArchaeologicalSite = apps.get_model( +        'archaeological_operations', 'ArchaeologicalSite') +    Operation = apps.get_model('archaeological_operations', 'Operation') +    for kls in [ArchaeologicalSite, Operation]: +        for item in kls.objects.exclude(point__isnull=True).all(): +            item.point_2d = item.point +            item.point = None +            item.save() + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0046_auto_20190122_1550'), +    ] + +    operations = [ +        migrations.RunPython(point_to_point_2d) +    ] diff --git a/archaeological_operations/migrations/0048_auto_20190122_1621.py b/archaeological_operations/migrations/0048_auto_20190122_1621.py new file mode 100644 index 000000000..c7d2d8cb1 --- /dev/null +++ b/archaeological_operations/migrations/0048_auto_20190122_1621.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2019-01-22 16:21 +from __future__ import unicode_literals + +import django.contrib.gis.db.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0047_point_to_point_2d'), +    ] + +    operations = [ +        migrations.AlterField( +            model_name='archaeologicalsite', +            name='point', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, dim=3, null=True, srid=4326, verbose_name='Point'), +        ), +        migrations.AlterField( +            model_name='historicalarchaeologicalsite', +            name='point', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, dim=3, null=True, srid=4326, verbose_name='Point'), +        ), +        migrations.AlterField( +            model_name='historicaloperation', +            name='point', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, dim=3, null=True, srid=4326, verbose_name='Point'), +        ), +        migrations.AlterField( +            model_name='operation', +            name='point', +            field=django.contrib.gis.db.models.fields.PointField(blank=True, dim=3, null=True, srid=4326, verbose_name='Point'), +        ), +    ] diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 7bb27ab6c..a8f1d4faf 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -22,6 +22,8 @@ from itertools import groupby  from django.conf import settings  from django.contrib.gis.db import models +from django.contrib.gis.db.models.aggregates import Union +from django.contrib.gis.db.models.functions import Centroid  from django.core.urlresolvers import reverse  from django.db import IntegrityError, transaction  from django.db.models import Q, Count, Sum, Max, Avg @@ -36,9 +38,10 @@ from ishtar_common.models import BaseHistorizedItem, Dashboard, \      OperationType, Organization, OwnPerms, Person, PersonType, \      post_delete_record_relation, post_save_cache, RelationItem, \      ShortMenuItem, SourceType, Town, ValueGetter, get_current_profile, \ -    document_attached_changed, HistoryModel, SearchAltName +    document_attached_changed, HistoryModel, SearchAltName, \ +    SpatialReferenceSystem  from ishtar_common.utils import cached_label_changed, \ -    force_cached_label_changed, mode, m2m_historization_changed +    force_cached_label_changed, mode, m2m_historization_changed, post_save_point  class RemainType(GeneralType): @@ -260,7 +263,20 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,                                       null=True, blank=True)      # gis -    point = models.PointField(_(u"Point"), blank=True, null=True) +    x = models.FloatField(_(u'X'), blank=True, null=True) +    y = models.FloatField(_(u'Y'), blank=True, null=True) +    z = models.FloatField(_(u'Z'), blank=True, null=True) +    estimated_error_x = models.FloatField(_(u'Estimated error for X'), +                                          blank=True, null=True) +    estimated_error_y = models.FloatField(_(u'Estimated error for Y'), +                                          blank=True, null=True) +    estimated_error_z = models.FloatField(_(u'Estimated error for Z'), +                                          blank=True, null=True) +    spatial_reference_system = models.ForeignKey( +        SpatialReferenceSystem, verbose_name=_(u"Spatial Reference System"), +        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)      multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,                                               null=True) @@ -369,6 +385,13 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,      def towns_label(self):          return u" - ".join(self.towns_codes()) +    def get_town_centroid(self): +        q = self.towns.filter(center__isnull=False).annotate( +                centroid=Centroid(Union('center'))).all() +        if not q.count(): +            return None +        return q.all()[0].centroid +      def _get_base_image_path(self):          return u"{}/{}".format(self.SLUG, self.reference) @@ -422,7 +445,12 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter,              ) -post_save.connect(cached_label_changed, sender=ArchaeologicalSite) +def site_post_save(sender, **kwargs): +    cached_label_changed(sender=sender, **kwargs) +    post_save_point(sender=sender, **kwargs) + + +post_save.connect(site_post_save, sender=ArchaeologicalSite)  m2m_changed.connect(document_attached_changed,                      sender=ArchaeologicalSite.documents.through) @@ -898,7 +926,20 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,                                                 blank=True, null=True)      # gis -    point = models.PointField(_(u"Point"), blank=True, null=True) +    x = models.FloatField(_(u'X'), blank=True, null=True) +    y = models.FloatField(_(u'Y'), blank=True, null=True) +    z = models.FloatField(_(u'Z'), blank=True, null=True) +    estimated_error_x = models.FloatField(_(u'Estimated error for X'), +                                          blank=True, null=True) +    estimated_error_y = models.FloatField(_(u'Estimated error for Y'), +                                          blank=True, null=True) +    estimated_error_z = models.FloatField(_(u'Estimated error for Z'), +                                          blank=True, null=True) +    spatial_reference_system = models.ForeignKey( +        SpatialReferenceSystem, verbose_name=_(u"Spatial Reference System"), +        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)      multi_polygon = models.MultiPolygonField(_(u"Multi polygon"), blank=True,                                               null=True)      history = HistoricalRecords(bases=[HistoryModel]) @@ -1067,6 +1108,13 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,      def render_parcels(self):          return Parcel.render_parcels(list(self.parcels.all())) +    def get_town_centroid(self): +        q = self.towns.filter(center__isnull=False).annotate( +            centroid=Centroid(Union('center'))).all() +        if not q.count(): +            return None +        return q.all()[0].centroid +      def context_record_relations_q(self):          from archaeological_context_records.models \              import RecordRelations as CRRL @@ -1416,6 +1464,8 @@ for attr in Operation.HISTORICAL_M2M:  def operation_post_save(sender, **kwargs):      if not kwargs['instance']:          return +    post_save_point(sender=sender, **kwargs) +      operation = kwargs['instance']      operation.skip_history_when_saving = True      if operation.fnap_financing and operation.cost: diff --git a/ishtar_common/migrations/0084_ishtarsiteprofile_use_town_for_geo.py b/ishtar_common/migrations/0084_ishtarsiteprofile_use_town_for_geo.py new file mode 100644 index 000000000..182187e8b --- /dev/null +++ b/ishtar_common/migrations/0084_ishtarsiteprofile_use_town_for_geo.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2019-01-22 15:44 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('ishtar_common', '0083_document_index_external_id'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='ishtarsiteprofile', +            name='use_town_for_geo', +            field=models.BooleanField(default=True, verbose_name='Use town to locate when coordinates are missing'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 6a4a0930e..76e415368 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2151,6 +2151,8 @@ class IshtarSiteProfile(models.Model, Cached):      preservation = models.BooleanField(_(u"Preservation module"),                                         default=False)      mapping = models.BooleanField(_(u"Mapping module"), default=False) +    use_town_for_geo = models.BooleanField( +        _(u"Use town to locate when coordinates are missing"), default=True)      underwater = models.BooleanField(_(u"Underwater module"), default=False)      parcel_mandatory = models.BooleanField(          _(u"Parcel are mandatory for context records"), default=True) diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 55e3a3a75..20957c43e 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -476,8 +476,11 @@ def post_save_point(sender, **kwargs):      if not kwargs.get('instance'):          return      instance = kwargs.get('instance') -    point = None -    point_2d = None +    point = instance.point +    point_2d = instance.point_2d +    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 \ @@ -488,6 +491,8 @@ def post_save_point(sender, **kwargs):              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  | 
