diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-09-09 12:38:46 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2022-12-12 12:23:18 +0100 | 
| commit | a8d8513c6c365d09eb663722b29740d3231d2c56 (patch) | |
| tree | 44dd6b9849a9bdfbfb6b1c22c78cf3ad0992d7c6 | |
| parent | 16aa1615cfdfdf96104b8654bb7caa463a5c95e0 (diff) | |
| download | Ishtar-a8d8513c6c365d09eb663722b29740d3231d2c56.tar.bz2 Ishtar-a8d8513c6c365d09eb663722b29740d3231d2c56.zip  | |
Geo: display associated context records and associated finds on sheet map (refactor and fixes)
| -rw-r--r-- | CHANGES.md | 10 | ||||
| -rw-r--r-- | archaeological_context_records/models.py | 30 | ||||
| -rw-r--r-- | archaeological_finds/templates/ishtar/sheet_basefind.html | 2 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 53 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 46 | ||||
| -rw-r--r-- | ishtar_common/static/js/ishtar-map.js | 2 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/sheet_map.html | 46 | 
7 files changed, 102 insertions, 87 deletions
diff --git a/CHANGES.md b/CHANGES.md index de2b73b93..3d8c14c33 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,11 +1,19 @@  ---  title: Ishtar changelog -date: 2022-08-05 +date: 2022-09-09  ---  Ishtar changelog  ================ +### Features ### + +- Geo: display associated context records and associated finds on sheet map + +### Bug fix ### + +- Fix safe_or template tags +  v4.0.15 - 2022-08-30  -------------------- diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 12d203a7c..1209a11cb 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -25,6 +25,7 @@ from django.conf import settings  from django.contrib.gis.db import models  from django.contrib.gis.geos import Point  from django.contrib.postgres.indexes import GinIndex +from django.contrib.sites.models import Site  from django.db import connection  from django.db.models import Q  from django.db.models.signals import post_delete, post_save, m2m_changed @@ -66,7 +67,7 @@ from ishtar_common.models import (      QuickAction,      RelationsViews,  ) -from ishtar_common.models_common import HistoricalRecords, SerializeItem +from ishtar_common.models_common import GeoVectorData, HistoricalRecords, SerializeItem  from archaeological_operations.models import (      Operation,      Period, @@ -961,17 +962,24 @@ class ContextRecord(      def get_geo_items(self, rounded=True):          dct = super(ContextRecord, self).get_geo_items(rounded=rounded) -        BaseFind = apps.get_model("archaeological_finds", "BaseFind") -        collection_base_finds = [] -        for bf in self.base_finds.distinct().all(): -            try: -                geo_item = bf.get_geo_items(rounded=rounded) -                collection_base_finds.append(geo_item) -            except BaseFind.DoesNotExist: -                pass -        dct["properties"]["base-finds"] = { +        site = Site.objects.get_current() +        scheme = "https" if settings.ISHTAR_SECURE else "http" +        base_url = scheme + "://" + site.domain + +        profile = get_current_profile() +        precision = profile.point_precision +         +        current_geodata = list(self.geodata.values_list("id", flat=True)) +         +        q = self.base_finds.filter(main_geodata__isnull=False) +        url = base_url + "/show-basefind/{}/" +        collection_finds = GeoVectorData._get_geo_item_list( +            q, current_geodata, url, precision, rounded +        ) +         +        dct["finds"] = {              "type": "FeatureCollection", -            "features": collection_base_finds, +            "features": collection_finds,          }          return dct diff --git a/archaeological_finds/templates/ishtar/sheet_basefind.html b/archaeological_finds/templates/ishtar/sheet_basefind.html index 81705aaae..ae4dde731 100644 --- a/archaeological_finds/templates/ishtar/sheet_basefind.html +++ b/archaeological_finds/templates/ishtar/sheet_basefind.html @@ -16,7 +16,7 @@      <div class='row'>          {% field_flex_detail "Operation" base_find.context_record.operation first %}          {% field_flex_detail "Archaeological site" base_find.context_record.archaeological_site first %} -        {% field_flex_detail "Context record" base_find.context_record.short_label first %} +        {% field_flex_detail "Context record" base_find.context_record first %}          {% field_flex "Town" base_find.context_record.town_label_with_areas '' '' first %}          {% field_flex "Parcel" base_find.context_record.parcel '' '' first %} diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 69b24fecd..370b3c9b2 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -75,7 +75,7 @@ from ishtar_common.models import (      MainItem,      HierarchicalType,  ) -from ishtar_common.models_common import Department, HistoricalRecords +from ishtar_common.models_common import Department, GeoVectorData, HistoricalRecords  from ishtar_common.model_managers import UUIDModelManager  from ishtar_common.utils import (      cached_label_changed, @@ -1732,53 +1732,6 @@ class Operation(              return None          return q.all()[0].poly, self._meta.verbose_name - -    def _get_geo_item_list(self, q, current_geodata, url, precision, rounded): -        collection_id = [] -        items_id = [] -        q = q.values("main_geodata", "id") -        for item in q.distinct().all(): -            geodata_id = item["main_geodata"] -            if geodata_id not in current_geodata: -                collection_id.append(geodata_id) -                items_id.append(item["id"]) -                current_geodata.append(geodata_id) - -        collection = [] -        for idx in range(len(collection_id)): -            geo = json.loads(GeoVectorData.objects.get(pk=collection_id[idx]).geojson) -            geo_type = geo.get("type", None) -            url_geo = url.format(items_id[idx]) -            if geo_type == "FeatureCollection": -                for feat in geo["features"]: -                    if "properties" in feat: -                        feat["properties"]["url"] = url_geo -                collection += geo["features"] -            elif geo_type: -                if "properties" in geo: -                    geo["properties"]["url"] = url_geo -                collection.append(geo) - -        if not precision and rounded: -            precision = 6 -        r = re.compile(r"(\d+)\.(\d{6})(\d*)") -        new_collection = [] -        for feat in collection: -            geom_type = feat["geometry"].get("type", None) -            if geom_type == "Point": -                if precision is not None: -                    feat["geometry"]["coordinates"] = [ -                        round(feat["geometry"]["coordinates"][0], precision), -                        round(feat["geometry"]["coordinates"][1], precision), -                    ] -                if not (-90 <= feat["geometry"]["coordinates"][1] <= 90) or not ( -                        -180 <= feat["geometry"]["coordinates"][0] <= 180): -                    # probably a bad projection -                    continue -            new_collection.append(feat) -        return new_collection - -      def get_geo_items(self, rounded=True):          dct = super(Operation, self).get_geo_items(rounded=rounded)          site = Site.objects.get_current() @@ -1792,7 +1745,7 @@ class Operation(          q = self.context_record.filter(main_geodata__isnull=False)          url = base_url + "/show-contextrecord/{}/" -        collection_context_records = self._get_geo_item_list( +        collection_context_records = GeoVectorData._get_geo_item_list(              q, current_geodata, url, precision, rounded          ) @@ -1800,7 +1753,7 @@ class Operation(          q = BaseFind.objects.filter(context_record__operation_id=self.pk,                                      main_geodata__isnull=False)          url = base_url + "/show-basefind/{}/" -        collection_finds = self._get_geo_item_list( +        collection_finds = GeoVectorData._get_geo_item_list(              q, current_geodata, url, precision, rounded          ) diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 9d71ae0dc..b72251f02 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -2359,6 +2359,52 @@ class GeoVectorData(Imported, OwnPerms):          profile = get_current_profile()          return profile.srs +    @classmethod +    def _get_geo_item_list(cls, q, current_geodata, url, precision, rounded): +        collection_id = [] +        items_id = [] +        q = q.values("main_geodata", "id") +        for item in q.distinct().all(): +            geodata_id = item["main_geodata"] +            if geodata_id not in current_geodata: +                collection_id.append(geodata_id) +                items_id.append(item["id"]) +                current_geodata.append(geodata_id) + +        collection = [] +        for idx in range(len(collection_id)): +            geo = json.loads(GeoVectorData.objects.get(pk=collection_id[idx]).geojson) +            geo_type = geo.get("type", None) +            url_geo = url.format(items_id[idx]) +            if geo_type == "FeatureCollection": +                for feat in geo["features"]: +                    if "properties" in feat: +                        feat["properties"]["url"] = url_geo +                collection += geo["features"] +            elif geo_type: +                if "properties" in geo: +                    geo["properties"]["url"] = url_geo +                collection.append(geo) + +        if not precision and rounded: +            precision = 6 +        r = re.compile(r"(\d+)\.(\d{6})(\d*)") +        new_collection = [] +        for feat in collection: +            geom_type = feat["geometry"].get("type", None) +            if geom_type == "Point": +                if precision is not None: +                    feat["geometry"]["coordinates"] = [ +                        round(feat["geometry"]["coordinates"][0], precision), +                        round(feat["geometry"]["coordinates"][1], precision), +                    ] +                if not (-90 <= feat["geometry"]["coordinates"][1] <= 90) or not ( +                        -180 <= feat["geometry"]["coordinates"][0] <= 180): +                    # probably a bad projection +                    continue +            new_collection.append(feat) +        return new_collection +      def get_geo_items(self, rounded=5):          dct = {"type": "Feature", "geometry": {},                 "properties": {"label": str(self)}} diff --git a/ishtar_common/static/js/ishtar-map.js b/ishtar_common/static/js/ishtar-map.js index 8ffe399d6..67d29cc48 100644 --- a/ishtar_common/static/js/ishtar-map.js +++ b/ishtar_common/static/js/ishtar-map.js @@ -716,7 +716,7 @@ var display_map = function(map_id, points, lines_and_polys, layers){      } else {          initialize_base_map(map_id, layers);      } -    display_points(map_id, points); +    display_points(map_id, points, true);      init_popup(map_id); diff --git a/ishtar_common/templates/ishtar/blocks/sheet_map.html b/ishtar_common/templates/ishtar/blocks/sheet_map.html index 11780ae8a..4a380ed13 100644 --- a/ishtar_common/templates/ishtar/blocks/sheet_map.html +++ b/ishtar_common/templates/ishtar/blocks/sheet_map.html @@ -9,40 +9,40 @@      <h4>{% trans "Geographic data" %}</h4>      <ul>{% for geodata in geodata_list %}          <li> -            <input type="checkbox" name="map-ol-{{item.SLUG}}-{{item.pk}}-{{geodata.pk}}" -                   class="map-ol-{{item.SLUG}}-{{item.pk}}" -                   id="map-ol-{{item.SLUG}}-{{item.pk}}-{{geodata.pk}}" +            <input type="checkbox" name="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-{{geodata.pk}}" +                   class="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}" +                   id="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-{{geodata.pk}}"                     {% if not forloop.counter0 %}checked{% endif %}              > -              <label for="map-ol-{{item.SLUG}}-{{item.pk}}-{{geodata.pk}}"> +              <label for="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-{{geodata.pk}}">                  <strong>{{geodata.data_type}}</strong></label><br/>              {{geodata.name}}          </li>{% endfor %} -        {% if geo_item.SLUG == "operation" %} +        {% if geo_item.SLUG == "operation" and display_context_records %}          <li> -            <input type="checkbox" name="map-ol-{{item.SLUG}}-{{item.pk}}-crs" -                   class="map-ol-{{item.SLUG}}-{{item.pk}}" -                   id="map-ol-{{item.SLUG}}-{{item.pk}}-crs"> -              <label for="map-ol-{{item.SLUG}}-{{item.pk}}-crs"> +            <input type="checkbox" name="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-crs" +                   class="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}" +                   id="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-crs"> +              <label for="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-crs">                  <strong>{% trans "Associated context records" %}</strong></label>              </li>          {% endif %} -        {% if geo_item.SLUG == "operation" or geo_item.SLUG == "contextrecord" %} +        {% if display_finds %}{% if geo_item.SLUG == "operation" or geo_item.SLUG == "contextrecord" %}          <li> -            <input type="checkbox" name="map-ol-{{item.SLUG}}-{{item.pk}}-finds" -                   class="map-ol-{{item.SLUG}}-{{item.pk}}" -                   id="map-ol-{{item.SLUG}}-{{item.pk}}-finds"> -              <label for="map-ol-{{item.SLUG}}-{{item.pk}}-finds"> +            <input type="checkbox" name="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-finds" +                   class="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}" +                   id="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-finds"> +              <label for="map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}-finds">                  <strong>{% trans "Associated finds" %}</strong></label>              </li> -        {% endif %} +        {% endif %}{% endif %}      </ul>  </div>  <script type="text/javascript"> -const refresh_map_{{item.SLUG}}_{{item.pk}} = function(first_init) { -    let idx = "{{item.SLUG}}-{{item.pk}}"; +const refresh_map_{{geo_item.SLUG}}_{{geo_item.pk}} = function(first_init) { +    let idx = "{{geo_item.SLUG}}-{{geo_item.pk}}";      let geodata_list = { {% for geodata in geodata_list %} -        "{{item.SLUG}}-{{item.pk}}-{{geodata.pk}}": ["{{geodata.geometry_type}}", {{geodata.geojson|safe}}]{% if not forloop.last %},{% endif %} +        "{{geo_item.SLUG}}-{{geo_item.pk}}-{{geodata.pk}}": ["{{geodata.geometry_type}}", {{geodata.geojson|safe}}]{% if not forloop.last %},{% endif %}      {% endfor %} };      let url{% if geo_item.SLUG == "operation" or geo_item.SLUG == "contextrecord" %} = "{% url 'api-get-geo' %}"{% endif %};      let attrs{% if geo_item.SLUG == "operation" %} = {"operation_id": "{{geo_item.pk}}"}{% elif geo_item.SLUG == "contextrecord" %} = {"context_record_id": "{{geo_item.pk}}"}{% endif %}; @@ -51,19 +51,19 @@ const refresh_map_{{item.SLUG}}_{{item.pk}} = function(first_init) {      display_points("map-{{window_id}}-" + idx, _geo_points[idx], first_init);  } -const display_map_{{item.SLUG}}_{{item.pk}} = function() { +const display_map_{{geo_item.SLUG}}_{{geo_item.pk}} = function() {      const html = render_map("map-{{window_id}}-{{geo_item.SLUG}}-{{geo_item.pk}}", false, true);      $("#map-content-{{window_id}}-{{geo_item.SLUG}}-{{geo_item.pk}}").html(html);      display_map("map-{{window_id}}-{{geo_item.SLUG}}-{{geo_item.pk}}", null, null); -    $(".map-ol-{{item.SLUG}}-{{item.pk}}").change( +    $(".map-ol-{{geo_item.SLUG}}-{{geo_item.pk}}").change(          function(){ -            refresh_map_{{item.SLUG}}_{{item.pk}}(false); +            refresh_map_{{geo_item.SLUG}}_{{geo_item.pk}}(false);          }      );  } -display_map_{{item.SLUG}}_{{item.pk}}(); -refresh_map_{{item.SLUG}}_{{item.pk}}(true); +display_map_{{geo_item.SLUG}}_{{geo_item.pk}}(); +refresh_map_{{geo_item.SLUG}}_{{geo_item.pk}}(true);  </script>  | 
