/**
* Overpass UI: Query-Editor-Panel mit Template-Browser und BBox-Integration.
*/
const OverpassUI = {
_panel: null,
_editor: null,
_templates: [],
_categories: [],
_activeCategory: null,
_isLoading: false,
_useBbox: true,
init: function() {
this._createPanel();
this._loadTemplates();
},
show: function() {
if (!this._panel) this.init();
this._panel.style.display = 'block';
if (!OverpassLayer._points) OverpassLayer.start(Globe.viewer);
},
hide: function() {
if (this._panel) this._panel.style.display = 'none';
},
_createPanel: function() {
var panel = document.getElementById('overpass-panel');
if (!panel) return;
this._panel = panel;
panel.innerHTML =
'
' +
'
OVERPASS QUERY
' +
'
' +
'
' +
'' +
'' +
'' +
'OVERPASSQL EDITOR
' +
'' +
'' +
'' +
'
' +
'' +
'' +
'';
this._editor = document.getElementById('overpass-editor');
},
_loadTemplates: function() {
var self = this;
fetch('/api/overpass/templates')
.then(function(r) { return r.json(); })
.then(function(data) {
self._categories = data.categories || [];
if (self._categories.length > 0) {
self._activeCategory = self._categories[0].id;
self._renderCategoryTabs();
self._renderTemplateList();
}
})
.catch(function(e) { console.warn('Overpass Templates:', e); });
},
_renderCategoryTabs: function() {
var el = document.getElementById('overpass-cat-tabs');
if (!el) return;
var self = this;
var html = '';
this._categories.forEach(function(cat) {
var active = cat.id === self._activeCategory ? ' active' : '';
html += '';
});
el.innerHTML = html;
},
_selectCategory: function(catId) {
this._activeCategory = catId;
this._renderCategoryTabs();
this._renderTemplateList();
},
_renderTemplateList: function() {
var el = document.getElementById('overpass-template-list');
if (!el) return;
var self = this;
var cat = this._categories.find(function(c) { return c.id === self._activeCategory; });
if (!cat) { el.innerHTML = ''; return; }
var html = '';
cat.templates.forEach(function(t) {
html += '';
});
el.innerHTML = html;
},
_applyTemplate: function(templateId) {
var tpl = null;
for (var i = 0; i < this._categories.length; i++) {
var found = this._categories[i].templates.find(function(t) { return t.id === templateId; });
if (found) { tpl = found; break; }
}
if (tpl && this._editor) {
this._editor.value = tpl.query;
OverpassLayer.setColor(tpl.color);
}
},
_getBboxFromViewport: function() {
if (!Globe.viewer) return null;
var rect = Globe.viewer.camera.computeViewRectangle();
if (!rect) return null;
return [
Cesium.Math.toDegrees(rect.south),
Cesium.Math.toDegrees(rect.west),
Cesium.Math.toDegrees(rect.north),
Cesium.Math.toDegrees(rect.east),
];
},
_executeQuery: function() {
if (this._isLoading || !this._editor) return;
var query = this._editor.value.trim();
if (!query) return;
var bbox = null;
if (this._useBbox) {
bbox = this._getBboxFromViewport();
}
this._isLoading = true;
var btn = document.getElementById('overpass-exec-btn');
if (btn) { btn.disabled = true; btn.textContent = 'LADE...'; }
var resultEl = document.getElementById('overpass-result');
if (resultEl) { resultEl.style.display = 'block'; resultEl.textContent = 'Anfrage wird gesendet...'; resultEl.style.color = 'var(--text-dim)'; }
var startTime = Date.now();
var self = this;
fetch('/api/overpass/query', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: query, bbox: bbox }),
})
.then(function(r) {
if (r.status === 429) {
return r.json().then(function(d) { throw new Error(d.detail || 'Rate-Limit erreicht'); });
}
if (!r.ok) {
return r.json().then(function(d) { throw new Error(d.detail || 'Fehler ' + r.status); });
}
return r.json();
})
.then(function(data) {
var elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
OverpassLayer.render(data);
if (resultEl) {
var text = data.total + ' Objekte (' + elapsed + 's)';
if (data.cached) text += ' [Cache]';
if (data.truncated) text += ' [max. ' + data.total + ' angezeigt]';
resultEl.textContent = text;
resultEl.style.color = 'var(--accent)';
}
var clearBtn = document.getElementById('overpass-clear-btn');
if (clearBtn) clearBtn.style.display = 'block';
})
.catch(function(e) {
if (resultEl) {
resultEl.textContent = 'Fehler: ' + e.message;
resultEl.style.color = '#ff5252';
}
})
.finally(function() {
self._isLoading = false;
if (btn) { btn.disabled = false; btn.textContent = 'AUSFUEHREN'; }
});
},
_clearResults: function() {
OverpassLayer.clear();
var resultEl = document.getElementById('overpass-result');
if (resultEl) { resultEl.style.display = 'none'; resultEl.style.color = 'var(--text-dim)'; }
var clearBtn = document.getElementById('overpass-clear-btn');
if (clearBtn) clearBtn.style.display = 'none';
},
executeQueryDirect: function(query, bbox, color) {
if (this._editor) this._editor.value = query;
if (color) OverpassLayer.setColor(color);
this._useBbox = !!bbox;
var bboxCb = document.getElementById('overpass-bbox');
if (bboxCb) bboxCb.checked = this._useBbox;
this.show();
this._executeQuery();
},
};