fix: VLM-Bildanalyse Bugfixes (Prompt, UI, Logging)

- Fix 1: Claude-Prompt weist generische Natur-Objekte ab (forest, mountain etc.)
  Objects-Array nur fuer OSINT-relevante Infrastruktur, Rest in terrain/landscape_clues
- Fix 2: Freundliche UI-Meldungen bei leeren Objects, 0 Treffern, gefilterten Tags
  Button ausgegraut + Hinweis wenn keine Infrastruktur erkannt
- Fix 3: generate_queries gibt JSON statt HTTP 400 bei leeren Fragments
- Fix 4: Verbose Objekt-Match-Logging auf debug reduziert
- Fix 5: Verwaiste static/js/ui/overpass.js geloescht

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
Claude Dev
2026-03-27 23:15:54 +01:00
Ursprung 8936d40fa4
Commit 28a87f1bb5
3 geänderte Dateien mit 35 neuen und 214 gelöschten Zeilen

Datei anzeigen

@@ -346,7 +346,7 @@ async def _run_claude(image_path: str, viewport_info: str = "", filename: str =
"4) Bodenfarbe und Gestein. Heller Rheinkies vs. dunkler Donauschotter. "
"5) Schatten: Richtung und Laenge. Vergleiche mit den Sonnenstand-Daten falls vorhanden. "
"Fuelle identified_features (Gewaessername, Region, Landmarken) und landscape_clues komplett. "
"Antworte ausschliesslich im vorgegebenen JSON-Format."
"OBJEKT-REGELN: Das objects-Array darf NUR konkrete OSINT-relevante Infrastruktur enthalten: Flughaefen, Militaerbasen, Haefen, Kraftwerke, Bruecken, Radaranlagen, Raffinerien, Gefaengnisse, Botschaften, Bahnhoefe, Sendemasten, Staudaemme, Bunker, Hangars, Landebahnen etc. Generische Natur (forest, mountain, farmland, vegetation, residential_area, river, lake, field) gehoert in terrain/landscape_clues, NICHT in objects. Wenn das Bild keine OSINT-relevante Infrastruktur zeigt: objects als leeres Array [] zurueckgeben. Antworte ausschliesslich im vorgegebenen JSON-Format."
)
cmd = [
@@ -603,7 +603,7 @@ async def generate_queries(req: QueryGenRequest):
for obj in req.objects:
obj_type = obj.get("type", "").lower().replace(" ", "_")
osm_tags = obj.get("osm_tags", [])
logger.info(f"VLM Objekt: type={obj_type}, osm_tags={osm_tags}")
logger.debug(f"VLM Objekt: type={obj_type}, osm_tags={osm_tags}")
# Direkte Zuordnung
if obj_type in _OBJECT_TO_OVERPASS and obj_type not in used_types:
@@ -611,7 +611,7 @@ async def generate_queries(req: QueryGenRequest):
fragments.append(f' node{tag}{bbox_str};')
fragments.append(f' way{tag}{bbox_str};')
used_types.add(obj_type)
logger.info(f" -> Mapping-Match: {obj_type} -> {tag}")
logger.debug(f" -> Mapping-Match: {obj_type} -> {tag}")
continue
# Fallback: OSM-Tags aus VLM-Ergebnis verwenden
@@ -620,20 +620,20 @@ async def generate_queries(req: QueryGenRequest):
if "=" in tag_str and tag_str not in used_types:
key, val = tag_str.split("=", 1)
if key in _GENERIC_KEYS:
logger.info(f" -> Tag gefiltert (generisch): {tag_str}")
logger.debug(f" -> Tag gefiltert (generisch): {tag_str}")
continue
frag = f'["{key}"="{val}"]'
fragments.append(f' node{frag}{bbox_str};')
fragments.append(f' way{frag}{bbox_str};')
used_types.add(tag_str)
logger.info(f" -> OSM-Tag verwendet: {tag_str}")
logger.debug(f" -> OSM-Tag verwendet: {tag_str}")
matched = True
break
if not matched and obj_type not in _OBJECT_TO_OVERPASS:
logger.warning(f" -> KEIN MATCH fuer: {obj_type} (tags: {osm_tags})")
logger.debug(f" -> KEIN MATCH fuer: {obj_type} (tags: {osm_tags})")
if not fragments:
raise HTTPException(400, "Keine passenden OSM-Tags fuer die erkannten Objekte gefunden")
return {"query": "", "tag_count": 0, "object_count": len(req.objects), "no_infrastructure": True}
query = "[out:json][timeout:30];\n(\n" + "\n".join(fragments) + "\n);\nout center body;"