diff --git a/streetup/assets/static/assets/inspection_map.js b/streetup/assets/static/assets/inspection_map.js
index 3c39cef..910f267 100644
--- a/streetup/assets/static/assets/inspection_map.js
+++ b/streetup/assets/static/assets/inspection_map.js
@@ -22,9 +22,19 @@
if (mapContainer.dataset.mapInitialized === 'true') return;
mapContainer.dataset.mapInitialized = 'true';
- // Centrage et style depuis les settings globaux (window.MAP_STYLE_LIGHT / window.DEFAULT_MAP_CENTER)
- const defaultCenter = window.DEFAULT_MAP_CENTER || [4.3517, 50.8503];
- const defaultZoom = window.DEFAULT_MAP_ZOOM || 15;
+ // Centrage et style depuis les settings globaux ou pré-sélection d'asset
+ let defaultCenter = window.DEFAULT_MAP_CENTER || [4.3517, 50.8503];
+ let defaultZoom = window.DEFAULT_MAP_ZOOM || 15;
+
+ if (window.PRESELECT_LON !== null && window.PRESELECT_LAT !== null && typeof window.PRESELECT_LON !== 'undefined' && typeof window.PRESELECT_LAT !== 'undefined') {
+ const preLon = parseFloat(window.PRESELECT_LON);
+ const preLat = parseFloat(window.PRESELECT_LAT);
+ if (!isNaN(preLon) && !isNaN(preLat) && preLon >= -180 && preLon <= 180 && preLat >= -90 && preLat <= 90 && !(preLon === 0 && preLat === 0)) {
+ defaultCenter = [preLon, preLat];
+ defaultZoom = 19;
+ }
+ }
+
const styleUrl = window.MAP_STYLE_LIGHT || 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json';
map = new maplibregl.Map({
@@ -304,6 +314,34 @@
map.getCanvas().style.cursor = '';
});
+ // Prise en compte de la pré-sélection d'un asset (zoom, thématique, catégorie)
+ if (window.PRESELECT_THEMATIC_CODE) {
+ const tileBtn = document.querySelector(`.thematic-tile[data-thematic="${window.PRESELECT_THEMATIC_CODE}"]`);
+ if (tileBtn) {
+ document.querySelectorAll('.thematic-tile').forEach(t => t.classList.remove('active'));
+ tileBtn.classList.add('active');
+ }
+ }
+
+ if (window.PRESELECT_CATEGORY_ID) {
+ const catSelect = document.getElementById('filter-category-select');
+ if (catSelect) {
+ catSelect.value = String(window.PRESELECT_CATEGORY_ID);
+ }
+ }
+
+ if (window.PRESELECT_LON !== null && window.PRESELECT_LAT !== null && typeof window.PRESELECT_LON !== 'undefined' && typeof window.PRESELECT_LAT !== 'undefined') {
+ const lon = parseFloat(window.PRESELECT_LON);
+ const lat = parseFloat(window.PRESELECT_LAT);
+ if (!isNaN(lon) && !isNaN(lat) && lon >= -180 && lon <= 180 && lat >= -90 && lat <= 90 && !(lon === 0 && lat === 0)) {
+ map.flyTo({
+ center: [lon, lat],
+ zoom: 19,
+ duration: 1200
+ });
+ }
+ }
+
// Charger les assets et l'historique d'inspections au premier affichage
loadAssets();
loadInspectionsHistory();
@@ -383,7 +421,10 @@
gpsBtn.addEventListener('click', locateUser);
}
- locateUser();
+ const hasPreselect = (window.PRESELECT_LON !== null && window.PRESELECT_LAT !== null && typeof window.PRESELECT_LON !== 'undefined' && typeof window.PRESELECT_LAT !== 'undefined');
+ if (!hasPreselect) {
+ locateUser();
+ }
}
function locateUser() {
diff --git a/streetup/assets/templates/assets/components/asset_inspections.html b/streetup/assets/templates/assets/components/asset_inspections.html
index 21a96ca..dd4f0d1 100644
--- a/streetup/assets/templates/assets/components/asset_inspections.html
+++ b/streetup/assets/templates/assets/components/asset_inspections.html
@@ -10,9 +10,18 @@
{% endif %}
{% if can_inspect %}
-
+
+
{% endif %}
@@ -149,3 +158,47 @@
{% endfor %}
+
+{% if can_inspect %}
+{% include "assets/components/inspection_form_modal.html" %}
+
+
+{% endif %}
diff --git a/streetup/assets/templates/assets/quick_inspection_map.html b/streetup/assets/templates/assets/quick_inspection_map.html
index 0947348..29204b3 100644
--- a/streetup/assets/templates/assets/quick_inspection_map.html
+++ b/streetup/assets/templates/assets/quick_inspection_map.html
@@ -436,6 +436,12 @@
{% endblock %}
diff --git a/streetup/assets/views/inspections.py b/streetup/assets/views/inspections.py
index 2a16b66..d44ff95 100644
--- a/streetup/assets/views/inspections.py
+++ b/streetup/assets/views/inspections.py
@@ -126,6 +126,54 @@ def inspections_list(request):
return render(request, 'assets/inspections_list.html', context)
+def _get_asset_wgs84_lon_lat(obj):
+ if hasattr(obj, 'lon') and hasattr(obj, 'lat') and obj.lon is not None and obj.lat is not None:
+ try:
+ lon_f = float(obj.lon)
+ lat_f = float(obj.lat)
+ if -180 <= lon_f <= 180 and -90 <= lat_f <= 90 and not (lon_f == 0 and lat_f == 0):
+ return lon_f, lat_f
+ except (ValueError, TypeError):
+ pass
+
+ if hasattr(obj, 'geojson') and obj.geojson:
+ try:
+ import json
+ data = json.loads(obj.geojson) if isinstance(obj.geojson, str) else obj.geojson
+ geom_data = data.get('geometry', {}) if data.get('type') == 'Feature' else data
+ g_type = geom_data.get('type')
+ coords = geom_data.get('coordinates')
+ if g_type == 'Point' and coords:
+ return float(coords[0]), float(coords[1])
+ elif g_type == 'Polygon' and coords and len(coords) > 0:
+ ring = coords[0]
+ avg_lon = sum(pt[0] for pt in ring) / len(ring)
+ avg_lat = sum(pt[1] for pt in ring) / len(ring)
+ return avg_lon, avg_lat
+ elif g_type == 'MultiPolygon' and coords and len(coords) > 0:
+ all_pts = [pt for poly in coords for ring in poly for pt in ring]
+ if all_pts:
+ avg_lon = sum(pt[0] for pt in all_pts) / len(all_pts)
+ avg_lat = sum(pt[1] for pt in all_pts) / len(all_pts)
+ return avg_lon, avg_lat
+ except Exception:
+ pass
+
+ if hasattr(obj, 'geom') and obj.geom:
+ try:
+ g = obj.geom
+ srid = getattr(g, 'srid', None) or 3812
+ from django.contrib.gis.geos import GEOSGeometry
+ g_copy = GEOSGeometry(g.wkt, srid=srid)
+ g_4326 = g_copy.transform(4326, clone=True)
+ centroid = g_4326.centroid
+ return float(centroid.x), float(centroid.y)
+ except Exception:
+ pass
+
+ return None, None
+
+
@login_required
def quick_inspection_map(request):
"""
@@ -143,12 +191,43 @@ def quick_inspection_map(request):
from assets.models import ParkingSpot
parking_spot_ct_id = ContentType.objects.get_for_model(ParkingSpot).id
+ preselect_ct_id = request.GET.get('content_type_id')
+ preselect_obj_id = request.GET.get('object_id')
+ preselect_lon = None
+ preselect_lat = None
+ preselect_thematic_code = None
+ preselect_category_id = None
+
+ if preselect_ct_id and preselect_obj_id:
+ try:
+ ct = ContentType.objects.get(pk=preselect_ct_id)
+ obj = ct.get_object_for_this_type(pk=preselect_obj_id)
+ if obj:
+ from assets.permissions import _get_asset_thematic
+ th = _get_asset_thematic(obj)
+ if th:
+ preselect_thematic_code = th.code
+ if hasattr(obj, 'category') and obj.category:
+ preselect_category_id = obj.category.id
+
+ preselect_lon, preselect_lat = _get_asset_wgs84_lon_lat(obj)
+ except Exception:
+ pass
+
+ import json
+
context = {
'base_template': base_template,
'is_mobile': is_mobile,
'thematics': thematics,
'categories': categories,
'parking_spot_ct_id': parking_spot_ct_id,
+ 'preselect_ct_id': preselect_ct_id or "null",
+ 'preselect_obj_id': preselect_obj_id or "null",
+ 'preselect_lon': json.dumps(preselect_lon) if preselect_lon is not None else "null",
+ 'preselect_lat': json.dumps(preselect_lat) if preselect_lat is not None else "null",
+ 'preselect_thematic_code': json.dumps(preselect_thematic_code) if preselect_thematic_code else "null",
+ 'preselect_category_id': preselect_category_id or "null",
}
return render(request, 'assets/quick_inspection_map.html', context)