diff --git a/loko/assets/static/assets/inspection_map.js b/loko/assets/static/assets/inspection_map.js index 06b7575..074efb6 100644 --- a/loko/assets/static/assets/inspection_map.js +++ b/loko/assets/static/assets/inspection_map.js @@ -1399,6 +1399,7 @@ let modelName = props.model_name || props.location_type || ''; if (modelName === 'NatureRWIZ' || modelName === 'NatureRWIAsset' || modelName === 'naturerwiasset' || props.thematic === 'water' || props.location_type === 'NatureRWIZ') { modelName = 'naturerwiz'; + window.currentGiepLocationId = props.location_id || (props.is_location ? objId : null) || objId; } document.getElementById('insp_target_type').textContent = props.element_type || props.asset_type_display || props.model_name || 'Asset'; diff --git a/loko/assets/views/water.py b/loko/assets/views/water.py index 0d5c7e9..a2f3f24 100644 --- a/loko/assets/views/water.py +++ b/loko/assets/views/water.py @@ -173,6 +173,9 @@ def water_assets_geojson(request): categories = data.get('category') or [] if isinstance(categories, str): categories = [categories] + geometry_types = data.get('geometry_types') or ([data.get('geometry_type')] if data.get('geometry_type') else []) + if not geometry_types and data.get('polygons_only'): + geometry_types = ['polygon'] # Récupération et parsing de la géométrie filter_geom_raw = data.get("filter_geom") @@ -191,6 +194,9 @@ def water_assets_geojson(request): sections_ids = [section_id] if section_id else [] statuses = request.GET.getlist('asset_status') categories = request.GET.getlist('category', []) + geometry_types = request.GET.getlist('geometry_type') + if not geometry_types and request.GET.get('polygons_only') in ('1', 'true', 'True', 'yes'): + geometry_types = ['polygon'] filter_geom_3812 = None _search_q = (data.get('q') or '').strip() if request.method == 'POST' else '' @@ -202,8 +208,59 @@ def water_assets_geojson(request): naturerwiasset_qs = NatureRWIAsset.objects.all() + POLYGON_STRUCTURE_TYPES = [ + 'bassin sec/infiltration', 'bassin en eau', 'fosse', 'jardin de pluie', 'noue', + 'massif drainant', 'tranchee drainante', 'toiture stockante', 'toiture verte', + 'bassin orage', 'saul-vide', 'saul-terre', 'citerne', 'espace vert sur dalle', + 'bande filtrante', 'collecteur en beton poreux' + ] + + if geometry_types: + from django.db.models import Q + geom_q = Q() + for gt in geometry_types: + gt_lower = gt.lower() + if gt_lower == 'polygon': + geom_q |= Q(geometry_type__iexact='polygon') | Q(structure_type__in=POLYGON_STRUCTURE_TYPES) + elif gt_lower == 'point': + geom_q |= Q(geometry_type__iexact='point') + elif gt_lower == 'line': + geom_q |= Q(geometry_type__iexact='line') + else: + geom_q |= Q(geometry_type__iexact=gt_lower) + naturerwiasset_qs = naturerwiasset_qs.filter(geom_q) + if sections_ids: - naturerwiasset_qs = naturerwiasset_qs.filter(location_id__in=sections_ids) + from django.db.models import Q + zones = list(NatureRWIZ.objects.filter(id__in=sections_ids)) + if zones: + zone_ids = [z.id for z in zones] + q_loc = Q(location_id__in=zone_ids) + for z in zones: + if z.geom: + q_loc |= Q(geom__intersects=z.geom) + naturerwiasset_qs = naturerwiasset_qs.filter(q_loc) + else: + target_asset = NatureRWIAsset.objects.filter(id__in=sections_ids).first() + if target_asset: + if target_asset.location_id: + loc = target_asset.location + q_loc = Q(location_id=target_asset.location_id) + if loc and loc.geom: + q_loc |= Q(geom__intersects=loc.geom) + naturerwiasset_qs = naturerwiasset_qs.filter(q_loc) + elif target_asset.geom: + zone = NatureRWIZ.objects.filter(geom__intersects=target_asset.geom).first() + if zone: + naturerwiasset_qs = naturerwiasset_qs.filter( + Q(location=zone) | (Q(geom__intersects=zone.geom) if zone.geom else Q()) + ) + else: + naturerwiasset_qs = naturerwiasset_qs.filter(id=target_asset.id) + else: + naturerwiasset_qs = naturerwiasset_qs.filter(id=target_asset.id) + else: + naturerwiasset_qs = naturerwiasset_qs.filter(location_id__in=sections_ids) if categories: naturerwiasset_qs = naturerwiasset_qs.filter(category__id__in=categories) @@ -226,9 +283,11 @@ def water_assets_geojson(request): naturerwiasset_qs = apply_search(naturerwiasset_qs, data) if naturerwiasset_qs.count() > MAX_ASSET_FEATURES: - return JsonResponse({"error": f"{_("Trop d'objets à afficher")} (> {MAX_ASSET_FEATURES})"}, status=413) + err_msg = _("Trop d'objets à afficher") + return JsonResponse({"error": f"{err_msg} (> {MAX_ASSET_FEATURES})"}, status=413) from django.db.models import FloatField, Value, CharField, F + from django.contrib.gis.db.models.functions import AsGeoJSON, Transform from assets.views.core import get_element_type_label naturerwiasset_qs = (naturerwiasset_qs.annotate( @@ -238,20 +297,22 @@ def water_assets_geojson(request): color=Value(None, output_field=CharField()), location_lon=F('location__lon'), location_lat=F('location__lat'), + computed_geojson=AsGeoJSON(Transform('geom', 4326)), ) .values( 'id', 'code', 'name', 'status', 'validation_status', 'lon', 'lat', 'surface_area', - 'category_name', 'model_name', 'color', 'geojson', - 'category_id', 'location_lon', 'location_lat', 'structure_type' + 'category_name', 'model_name', 'color', 'geojson', 'computed_geojson', + 'category_id', 'location_lon', 'location_lat', 'structure_type', 'geometry_type' ) .order_by('code') )[:MAX_ASSET_FEATURES] def build_geometry_and_coords(obj): geometry = None - if obj.get('geojson'): + geojson_str = obj.get('computed_geojson') or obj.get('geojson') + if geojson_str: try: - geometry = json.loads(obj['geojson']) + geometry = json.loads(geojson_str) except (TypeError, ValueError, json.JSONDecodeError): geometry = None @@ -296,6 +357,7 @@ def water_assets_geojson(request): "thematic": "water", "is_location": False, "structure_type": obj.get('structure_type', ''), + "geometry_type": obj.get('geometry_type', ''), } } @@ -320,6 +382,10 @@ def water_assets_autocomplete(request): except (TypeError, ValueError): category_id = None + geometry_type = request.GET.get('geometry_type') + if not geometry_type and request.GET.get('polygons_only') in ('1', 'true', 'True', 'yes'): + geometry_type = 'polygon' + qs = NatureRWIAsset.objects.exclude(status='removed').annotate( code_u=Lower(Unaccent('code')), name_fr_u=Lower(Unaccent('name_fr')), @@ -336,13 +402,27 @@ def water_assets_autocomplete(request): if category_id is not None: qs = qs.filter(category_id=category_id) + if geometry_type: + if geometry_type.lower() == 'polygon': + POLYGON_STRUCTURE_TYPES = [ + 'bassin sec/infiltration', 'bassin en eau', 'fosse', 'jardin de pluie', 'noue', + 'massif drainant', 'tranchee drainante', 'toiture stockante', 'toiture verte', + 'bassin orage', 'saul-vide', 'saul-terre', 'citerne', 'espace vert sur dalle', + 'bande filtrante', 'collecteur en beton poreux' + ] + qs = qs.filter(Q(geometry_type__iexact='polygon') | Q(structure_type__in=POLYGON_STRUCTURE_TYPES)) + else: + qs = qs.filter(geometry_type__iexact=geometry_type) + if location_id: try: loc = NatureRWIZ.objects.get(id=location_id) if loc.geom: - qs = qs.filter(geom__intersects=loc.geom) + qs = qs.filter(Q(location_id=location_id) | Q(geom__intersects=loc.geom)) + else: + qs = qs.filter(location_id=location_id) except NatureRWIZ.DoesNotExist: - pass + qs = qs.filter(location_id=location_id) items = [] for a in qs.select_related('category')[:100]: diff --git a/loko/inspections/templates/inspections/components/asset_fields/_naturerwiz.html b/loko/inspections/templates/inspections/components/asset_fields/_naturerwiz.html index a51b4a0..87e057b 100644 --- a/loko/inspections/templates/inspections/components/asset_fields/_naturerwiz.html +++ b/loko/inspections/templates/inspections/components/asset_fields/_naturerwiz.html @@ -1,7 +1,7 @@ {% load i18n static %} -