feat: Praezisere Geolocation durch Koordinatenschaetzung + Feature-Erkennung
VLM-Schema: - estimated_coordinates: Claude schaetzt Lat/Lon + Radius direkt - identified_features: Konkreter Gewaessername, engste Region, Landmarken - landscape_clues um water_characteristics erweitert VLM-Prompt: Komplett ueberarbeitet - Primaerziel ist jetzt Reverse Geolocation statt nur Objekterkennung - Spezifische Anleitungen: Fluss-ID (Rhein vs Donau), Kiesfarbe, Uferform - Explizite Aufforderung fuer Koordinatenschaetzung BBox-Kaskade (Prioritaet): 1. EXIF-GPS (exakt) 2. estimated_coordinates + Radius (VLM-Schaetzung) 3. identified_features (Gewaesser/Region aus Matching) 4. estimated_location_type (grobe Region) 5. Weltweit (Fallback) Regions-Mapping: 30+ neue Eintraege - Deutsche Bundeslaender (NRW, Bayern, Hessen, etc.) - Flussgebiete (Niederrhein, Oberrhein, Mosel, Elbe, etc.) - Staedte (Duesseldorf, Koeln, Bonn, Neuss) Frontend: - Gruen hervorgehobene Koordinaten-Box mit Radius - Identifizierte Features (Gewaesser, Region, Landmarken) - Fly-To zur geschaetzten Position
Dieser Commit ist enthalten in:
@@ -238,14 +238,41 @@ const VlmUI = {
|
||||
}
|
||||
}
|
||||
|
||||
// Geschaetzte Koordinaten
|
||||
var coordsHtml = '';
|
||||
if (data.estimated_coordinates && data.estimated_coordinates.latitude) {
|
||||
var ec = data.estimated_coordinates;
|
||||
var rKm = ec.confidence_radius_km || '?';
|
||||
coordsHtml = '<div class="vlm-exif-card" style="border-color:rgba(0,255,136,0.3);background:rgba(0,255,136,0.06);margin-top:8px">' +
|
||||
'<div style="font-size:9px;letter-spacing:1.5px;color:var(--accent);margin-bottom:4px">GESCHAETZTE POSITION</div>' +
|
||||
'<div style="font-size:13px;color:var(--accent);font-weight:700">' + ec.latitude.toFixed(4) + ', ' + ec.longitude.toFixed(4) +
|
||||
' <span style="font-size:11px;font-weight:400;color:var(--text-dim)">(±' + rKm + ' km)</span></div>' +
|
||||
(ec.reasoning ? '<div style="font-size:10px;color:var(--text-dim);margin-top:4px">' + ec.reasoning + '</div>' : '') +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
// Identifizierte Features
|
||||
var featHtml = '';
|
||||
if (data.identified_features) {
|
||||
var if_ = data.identified_features;
|
||||
var fp = [];
|
||||
if (if_.water_body) fp.push('<b>Gewaesser:</b> ' + if_.water_body);
|
||||
if (if_.specific_region) fp.push('<b>Region:</b> ' + if_.specific_region);
|
||||
if (if_.nearby_landmarks) fp.push('<b>Landmarken:</b> ' + if_.nearby_landmarks);
|
||||
if (fp.length > 0) {
|
||||
featHtml = '<div style="font-size:9px;letter-spacing:1.5px;color:#00bcd4;margin:8px 0 4px">IDENTIFIZIERTE MERKMALE</div>' +
|
||||
'<div style="font-size:11px;color:var(--text);line-height:1.8">' + fp.join('<br>') + '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Szene
|
||||
var sceneEl = document.getElementById('vlm-scene');
|
||||
if (sceneEl) {
|
||||
sceneEl.innerHTML = exifHtml +
|
||||
sceneEl.innerHTML = exifHtml + coordsHtml +
|
||||
'<div style="margin-top:8px">' + (data.scene_description || 'Keine Beschreibung') +
|
||||
(data.terrain ? ' | Gelaende: ' + data.terrain : '') +
|
||||
(data.estimated_location_type ? ' | Region: ' + data.estimated_location_type : '') +
|
||||
'</div>' + cluesHtml;
|
||||
'</div>' + featHtml + cluesHtml;
|
||||
}
|
||||
|
||||
// Objekte
|
||||
@@ -350,16 +377,29 @@ const VlmUI = {
|
||||
});
|
||||
}
|
||||
|
||||
// === BBox bestimmen: EXIF-GPS > Viewport-Checkbox > Region ===
|
||||
// === BBox bestimmen: EXIF-GPS > estimated_coordinates > Viewport > Region (Backend) ===
|
||||
var bbox = null;
|
||||
var ec = analysis.estimated_coordinates;
|
||||
var hasEstCoords = ec && ec.latitude && ec.longitude;
|
||||
|
||||
if (hasExifGps) {
|
||||
// 0.5 Grad um EXIF-Position
|
||||
bbox = [
|
||||
exif.latitude - 0.5,
|
||||
exif.longitude - 0.5,
|
||||
exif.latitude + 0.5,
|
||||
exif.longitude + 0.5,
|
||||
exif.latitude - 0.5, exif.longitude - 0.5,
|
||||
exif.latitude + 0.5, exif.longitude + 0.5,
|
||||
];
|
||||
} else if (hasEstCoords) {
|
||||
// VLM-geschaetzte Koordinaten: Radius in Grad
|
||||
var rKm = ec.confidence_radius_km || 50;
|
||||
var rDeg = Math.max(0.1, Math.min(rKm / 111, 10));
|
||||
bbox = [
|
||||
ec.latitude - rDeg, ec.longitude - rDeg,
|
||||
ec.latitude + rDeg, ec.longitude + rDeg,
|
||||
];
|
||||
// Zur geschaetzten Position fliegen
|
||||
Globe.viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(ec.longitude, ec.latitude, Math.max(50000, rKm * 2000)),
|
||||
duration: 2,
|
||||
});
|
||||
} else {
|
||||
var bboxCb = document.getElementById('vlm-use-bbox');
|
||||
if (bboxCb && bboxCb.checked && Globe.viewer) {
|
||||
@@ -373,7 +413,6 @@ const VlmUI = {
|
||||
];
|
||||
}
|
||||
}
|
||||
// Kein explizites BBox? Region wird vom Backend aus estimated_location_type abgeleitet
|
||||
}
|
||||
|
||||
var btn = document.getElementById('vlm-search-btn');
|
||||
@@ -393,6 +432,8 @@ const VlmUI = {
|
||||
objects: selected,
|
||||
bbox: bbox,
|
||||
estimated_location_type: analysis.estimated_location_type || null,
|
||||
estimated_coordinates: analysis.estimated_coordinates || null,
|
||||
identified_features: analysis.identified_features || null,
|
||||
}),
|
||||
})
|
||||
.then(function(r) {
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren