Swisstopo + OSM Importer + Höhenlinien + Bulk-Op Performance
Swisstopo Iter 3:
- Ortho-Drape: TIN-Mesh aus Terrain-Grid mit per-vertex UVs + PictureFrame-Material
- Project-Cache: TIFs werden neben .3dm gespeichert (SMB-shareable)
- Layer-Restruktur: 80_swisstopo/{Terrain, Luftbild} Sub-Ebenen
- TIFs direkt (kein PNG-Downsampling) für volle Auflösung
- UV-Inset gegen weisse Streifen zwischen Kacheln
- Hoehenlinien (2D, swissALTI3D) auf aktives Geschoss OKFF projiziert
- TIN-Mesh + Schichtenmodell aus Contours (separate Optionen)
- TLM3D entfernt (swisstopo liefert nur GDB/SHP, kein DXF)
OSM Importer (neu):
- rhino/osm.py: Overpass-API-Client
- src/OsmApp.jsx: React-Dialog mit Adresse + Radius + 7 Kategorien
- Strassen/Gebäude/Wasser/Wasserläufe/Parks/Wald/Fusswege (Codes 7101-7107)
- ElementeApp: PillGroup "Importer" mit Swisstopo + OSM Buttons
Sub-Ebenen — rekursiv durch hierarchische Ebenen:
- Visibility-Toggle: slimEbene rekursiv (children bleiben erhalten)
- Settings-Dialog: _find_sublayer_by_code_recursive + _replace_in_tree
- Hatch Auto-Fill: refresh_layer_fills + _fill_signature + _ebene_fill_for_layer
alle rekursiv durch children
- EbenenSettingsApp: flattenEbenen-Helper
Bulk-Op Performance (Delete/Cut/etc.):
- _USER_BULK_CMDS + _BULK_ACTIVE_KEY Sticky-Flag
- CommandBegin: doc.Views.RedrawEnabled = False + Listener-Bail aktiv
- CommandEnd: RedrawEnabled restore + 1× Redraw + Selection-Refresh
- Bail-outs in dimensionen.on_idle/on_select, elemente._on_idle_selection,
gestaltung.on_idle_flush/on_delete
- Verhindert das sichtbare "Runterzählen" pro Element bei Bulk-Delete
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+21
-2
@@ -653,14 +653,33 @@ def cleanup_default_layers(doc):
|
||||
print("[EBENEN] Default-Layer entfernt: {}".format(", ".join(deleted)))
|
||||
|
||||
|
||||
def _find_sublayer_by_code_recursive(doc, parent_id, code):
|
||||
"""Sucht einen Sub-Layer mit `code` unter parent_id — auch tief
|
||||
verschachtelt (Sub-Sub-Layer mit gleichem Code-Prefix). Liefert
|
||||
layer_index oder -1."""
|
||||
prefix = code + "_"
|
||||
direct = []
|
||||
for i, layer in enumerate(doc.Layers):
|
||||
if layer is None or layer.IsDeleted: continue
|
||||
if layer.ParentLayerId == parent_id:
|
||||
if layer.Name.startswith(prefix): return i
|
||||
direct.append(layer.Id)
|
||||
for child_id in direct:
|
||||
idx = _find_sublayer_by_code_recursive(doc, child_id, code)
|
||||
if idx >= 0: return idx
|
||||
return -1
|
||||
|
||||
|
||||
def set_active_sublayer(doc, zeichnungsebene_id, code):
|
||||
"""Macht den Sublayer 'code' unter Zeichnungsebene 'zeichnungsebene_id' aktiv."""
|
||||
"""Macht den Sublayer 'code' unter Zeichnungsebene 'zeichnungsebene_id'
|
||||
aktiv. Sucht rekursiv durch verschachtelte Sub-Layer (z.B. 70_osm/
|
||||
7101_Strassen liegt zwei Ebenen tief)."""
|
||||
parent_idx = _find_top_by_id(doc, zeichnungsebene_id)
|
||||
if parent_idx < 0:
|
||||
print("[EBENEN] Parent-Layer fuer Zeichnungsebene {} nicht gefunden".format(zeichnungsebene_id))
|
||||
return
|
||||
parent_id = doc.Layers[parent_idx].Id
|
||||
sub_idx = _find_sublayer_by_code(doc, parent_id, code)
|
||||
sub_idx = _find_sublayer_by_code_recursive(doc, parent_id, code)
|
||||
if sub_idx >= 0:
|
||||
doc.Layers.SetCurrentLayerIndex(sub_idx, True)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user