From 62f582a650ed211030042e11d2f46cfd24f808de Mon Sep 17 00:00:00 2001
From: Helge Jung <hej@c3pb.de>
Date: Mon, 25 Dec 2023 02:33:51 +0100
Subject: [PATCH] add Assembly.location_data to store location data as-is

This is intended as a temporary solution to deal with the CRS of c3nav/leaflet which does not bode well with PostGIS by default.
---
 src/api/views/maps.py                         |  5 ++--
 .../backoffice/assemblyteam_editposition.html |  4 ++--
 src/backoffice/views/assemblyteam.py          | 23 ++++++++++++++-----
 .../migrations/0142_assembly_location_data.py | 18 +++++++++++++++
 src/core/models/assemblies.py                 |  6 +++++
 5 files changed, 46 insertions(+), 10 deletions(-)
 create mode 100644 src/core/migrations/0142_assembly_location_data.py

diff --git a/src/api/views/maps.py b/src/api/views/maps.py
index 6b90e250e..2a7d70b34 100644
--- a/src/api/views/maps.py
+++ b/src/api/views/maps.py
@@ -142,6 +142,7 @@ class C3NavExportView(ConferenceSlugMixin, APIView):
         if request.GET.get('all') != '1':
             qs = qs.exclude(location_point=None, location_boundaries=None)
         for assembly in qs:  # type: Assembly
+            loc_data = assembly.location_data or {}
             data.append(
                 {
                     'type': 'assembly',
@@ -154,8 +155,8 @@ class C3NavExportView(ConferenceSlugMixin, APIView):
                     'parent_id': assembly.parent_id,
                     'children': assembly.children.filter(state_assembly__in=exportable_states).values_list('slug', flat=True) if assembly.is_cluster else None,
                     'floor': assembly.get_location_floor_index(),
-                    'location': assembly.get_location_point_xy(),
-                    'polygons': assembly.get_location_boundaries_xy(),
+                    'location': loc_data.get('point'),  # assembly.get_location_point_xy(),
+                    'polygons': loc_data.get('boundaries'),  # assembly.get_location_boundaries_xy(),
                 }
             )
 
diff --git a/src/backoffice/templates/backoffice/assemblyteam_editposition.html b/src/backoffice/templates/backoffice/assemblyteam_editposition.html
index c95ee4247..af394b8dc 100644
--- a/src/backoffice/templates/backoffice/assemblyteam_editposition.html
+++ b/src/backoffice/templates/backoffice/assemblyteam_editposition.html
@@ -37,13 +37,13 @@
               <div class="row mb-3">
                 <label class="col-sm-2 col-form-label text-muted" for="poi">{% trans "Assembly__location_point" %}</label>
                 <div class="col-sm-10">
-                  <input class="form-control" readonly type="text" name="location_point" id="poi" value="{{ assembly.get_location_point_as_json }}">
+                  <input class="form-control" readonly type="text" name="location_point" id="poi" value="{{ map_location|default:"" }}">
               </div>
               </div>
               <div class="row mb-3">
                 <label class="col-sm-2 col-form-label text-muted" for="areas">{% trans "Assembly__location_boundaries" %}</label>
                 <div class="col-sm-10">
-                  <input class="form-control" readonly type="text" name="location_boundaries" id="areas" value="{{ assembly.get_location_boundaries_as_json }}">
+                  <input class="form-control" readonly type="text" name="location_boundaries" id="areas" value="{{ map_boundaries|default:"" }}">
               </div>
               </div>
             </div>
diff --git a/src/backoffice/views/assemblyteam.py b/src/backoffice/views/assemblyteam.py
index e2be56602..3f583a72d 100644
--- a/src/backoffice/views/assemblyteam.py
+++ b/src/backoffice/views/assemblyteam.py
@@ -6,7 +6,6 @@ from io import BytesIO
 from pandas import DataFrame, ExcelWriter
 
 from django.contrib import messages
-from django.contrib.gis.geos import MultiPolygon, Point, Polygon
 from django.contrib.postgres.aggregates import StringAgg
 from django.db.models import OuterRef, Q, Subquery
 from django.http import Http404, HttpResponse
@@ -555,6 +554,8 @@ class AssemblyEditHierarchyView(SingleAssemblyTeamMixin, View):
 
 
 class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
+    SRID = 0
+
     def post(self, *args, **kwargs):
         request = self.request
         assembly = self.assembly
@@ -574,24 +575,30 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
         }
         changes = {}
         try:
+            assembly.location_data = assembly.location_data or {}
+
             if poi and poi != '""':
                 parsed = json.loads(poi)
                 assert isinstance(parsed, list) and len(parsed) == 2
 
-                assembly.location_point = Point(parsed[0], parsed[1])
+                # assembly.location_point = Point(x=parsed[0], y=parsed[1], srid=self.SRID)
+                assembly.location_data['point'] = parsed
                 changes['location_point'] = str(assembly.location_point)
             else:
-                assembly.location_point = None
+                # assembly.location_point = None
+                assembly.location_data['point'] = None
                 changes['location_point'] = str(None)
 
             if boundaries and boundaries != '""':
                 parsed = json.loads(boundaries)
                 assert isinstance(parsed, list)
 
-                assembly.location_boundaries = MultiPolygon([Polygon(item) for item in parsed])
+                # assembly.location_boundaries = MultiPolygon([Polygon(item) for item in parsed], srid=self.SRID)
+                assembly.location_data['boundaries'] = parsed
                 changes['location_boundaries'] = str(assembly.location_boundaries)
             else:
-                assembly.location_boundaries = None
+                # assembly.location_boundaries = None
+                assembly.location_data['boundaries'] = None
                 changes['location_boundaries'] = str(None)
 
             if floor and floor != '""':
@@ -604,6 +611,7 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
                 changes['location_floor'] = str(None)
 
         except ValueError:
+            logger.exception('Failed to update position of assembly %s', assembly.pk)
             messages.error(request, gettext('assemblyedit_position_error'))
             return redirect('backoffice:assemblyteam-editposition', pk=assembly.pk)
 
@@ -625,7 +633,7 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
         elif action != 'save':
             messages.warning(request, gettext('assemblyedit_position_unknownaction'))
 
-        assembly.save(update_fields=['state_assembly', 'location_point', 'location_boundaries', 'location_floor'])
+        assembly.save(update_fields=['state_assembly', 'location_point', 'location_boundaries', 'location_floor', 'location_data'])
 
         # log the action
         messages.success(request, gettext('assemblyedit_changedposition'))
@@ -672,6 +680,9 @@ class AssemblyEditPlacementView(SingleAssemblyTeamMixin, View):
     def get(self, *args, **kwargs):
         context = self.get_context_data()
         context['uses_map'] = True
+        loc_data = context['assembly'].location_data or {}
+        context['map_location'] = loc_data.get('point')  # context['assembly'].get_location_point_as_json()
+        context['map_boundaries'] = loc_data.get('boundaries')  # context['assembly'].get_location_boundaries_as_json()
         return render(self.request, 'backoffice/assemblyteam_editposition.html', context)
 
 
diff --git a/src/core/migrations/0142_assembly_location_data.py b/src/core/migrations/0142_assembly_location_data.py
new file mode 100644
index 000000000..7e2e23afd
--- /dev/null
+++ b/src/core/migrations/0142_assembly_location_data.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.6 on 2023-12-25 00:44
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0141_event_recording_event_streaming_room_recording_state_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='assembly',
+            name='location_data',
+            field=models.JSONField(blank=True, null=True),
+        ),
+    ]
diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py
index a7bc9e058..15d162e04 100644
--- a/src/core/models/assemblies.py
+++ b/src/core/models/assemblies.py
@@ -251,6 +251,12 @@ class Assembly(TaggedItemMixin, models.Model):
         verbose_name=_('Assembly__location_boundaries'),
     )
 
+    location_data = models.JSONField(
+        blank=True,
+        null=True,
+    )
+    """temporary work-around field for c3nav x/y coordinate scheme"""
+
     created = models.DateTimeField(
         auto_now_add=True,
         help_text=_('Assembly__created__help'),
-- 
GitLab