Scripting wolfhece from a VSCode Jupyter Notebook
This notebook shows the recommended way to drive a live WolfMapViewer interactively from VSCode — no bridge, no separate server, no extra dependencies beyond ipykernel (already used by VSCode itself).
How it works
IPython has built-in support for wx event-loop integration via the %gui wx magic. When active, IPython drives the wx event loop itself using a timer-based mechanism — you must not call app.MainLoop() because IPython handles it.
%gui wx ← tells IPython to manage the wx event loop
run once, alone in its own cell, before any wx code
Each notebook cell returns immediately; wx windows are live and keep processing events while you run subsequent cells.
Two entry points
Class |
When to use |
|---|---|
|
Minimal viewer only — no extra data, fastest start |
|
Full production stack (hydrometry, PICC, cadaster, WMS, …) |
Sections A and B below cover each option.
Requirements — wolfhece installed in the active kernel’s environment. The kernel is the same Python that runs in the VSCode terminal.
[1]:
# ── Step 1 (mandatory, run this cell first, alone) ───────────────────────────
# Activate wx event-loop integration. After this cell, wx windows are live
# and the notebook remains interactive simultaneously.
%gui wx
[ ]:
# ── Step 2 ───────────────────────────────────────────────────────────────────
# Create the wx.App singleton. False = do not redirect stdout/stderr.
# Do NOT call app.MainLoop() — %gui wx handles the event loop.
# import wx
# app = wx.App(False)
Section A — Minimal viewer (WolfMapViewer)
Use this when you only need the map canvas, without the full data stack (no hydrometry GUI, no PICC/cadaster layers, etc.).
[3]:
from wolfhece.PyDraw import WolfMapViewer
viewer = WolfMapViewer(None, title='wolfhece — notebook session')
viewer.Show()
INFO:root:Importing wolfhece modules
INFO:root:wolfhece modules imported
[3]:
False
[4]:
# Cells below execute while the viewer is open.
# Current viewport bounds:
print(f"x: [{viewer.xmin:.1f}, {viewer.xmax:.1f}]")
print(f"y: [{viewer.ymin:.1f}, {viewer.ymax:.1f}]")
x: [-2.0, 42.0]
y: [-0.9, 40.9]
[5]:
# Load a raster array and display it.
# Adapt the path to your own file.
from pathlib import Path
array_file = Path(r'C:\path\to\my_array.bin') # ← adapt
if array_file.exists():
viewer.add_object(which='array', filename=str(array_file), id='DEM', ToCheck=True)
viewer.findminmax(True)
viewer.Autoscale(False)
viewer.Paint()
else:
print(f"File not found: {array_file}")
File not found: C:\path\to\my_array.bin
[6]:
# Direct wx calls are safe — we are on the main thread.
viewer.set_statusbar_text('Hello from the notebook!')
viewer.Paint()
Section B — Full production stack (MapManager)
MapManager wraps a WolfMapViewer and automatically loads the standard data layers: SPW hydrometry stations, PICC parcels, cadaster, land maps, WMS tiles, coordinate grid, and optional HECE database items.
Key points
Pass
splash=Falseto suppress the splash screen (not needed in a notebook).The viewer itself is at
manager.mapviewer.MapManageris itself a (hidden)wx.Frame— you do not need to callmanager.Show(). The viewer frame shows itself.
[2]:
# Close the minimal viewer from Section A first if it is still open.
# viewer.Close()
from wolfhece.PyGui import MapManager
# splash=False → skip the WolfLauncher splash screen
manager = MapManager(splash=False)
# Convenient shorthand
v = manager.mapviewer
INFO:root:Importing wolfhece modules
INFO:root:wolfhece modules imported
INFO:root:MapManager
INFO:root:MapManager - MapViewer created
INFO:root:MapManager - Data directories created
ERROR:root:Error in hydrometry init: 'numpy.ndarray' object is not callable
INFO:root:MapManager - hydrometry_wolfgui created
INFO:root:MapManager - Picc_data created
INFO:root:MapManager - Cadaster_data created
INFO:root:MapManager - PlansTerrier created
INFO:root:MapManager - Ouvrages Ponts created
INFO:root:MapManager - Ouvrages Seuils created
INFO:root:MapManager - Enquetes created
INFO:root:MapManager - Particularites created
INFO:root:MapManager - PlansTerrier created
INFO:root:MapManager - Menu Landuse/Landcover created
[4]:
# Verify what was loaded automatically.
from wolfhece.PyDraw import draw_type
arrays = v.get_list_ids(drawing_type=draw_type.ARRAYS, checked_state=None)
vectors = v.get_list_ids(drawing_type=draw_type.VECTORS, checked_state=None)
print("Arrays :", arrays or '(none)')
print("Vectors :", vectors or '(none)')
Arrays : (none)
Vectors : ['grid']
[5]:
# Add a raster, fit the view and repaint.
from pathlib import Path
array_file = Path(r'C:\path\to\my_array.bin') # ← adapt
if array_file.exists():
v.add_object(which='array', filename=str(array_file), id='DEM', ToCheck=True)
v.findminmax(True)
v.Autoscale(False)
v.Paint()
else:
print(f"File not found: {array_file}")
File not found: C:\path\to\my_array.bin
[6]:
# Inspect the active array (selected in the tree on the left).
a = v.active_array
if a is not None:
print(f"Active array : {a.idx}")
print(f" Shape : {a.array.shape}")
print(f" Min / Max : {float(a.array.min()):.3f} / {float(a.array.max()):.3f}")
else:
print('No active array — click one in the tree.')
No active array — click one in the tree.
[7]:
# Access the SPW hydrometry sub-manager loaded by MapManager.
hydro = manager.SPWhydrometry
print(type(hydro))
# hydro.get_stations() ← example method (check the API)
<class 'wolfhece.hydrometry.kiwis_wolfgui.hydrometry_wolfgui'>
Section C — Useful scripting patterns
A collection of common operations once the viewer is live.
[8]:
# Work with the active array as a NumPy masked array.
import numpy as np
a = v.active_array
if a is not None:
data = a.array # np.ma.MaskedArray, shape (cols, rows)
valid = data[~data.mask]
print(f"Valid cells : {valid.size:,}")
print(f"Mean : {valid.mean():.3f}")
print(f"Std : {valid.std():.3f}")
[ ]:
# Save the current canvas to PNG.
from pathlib import Path
out = Path.home() / 'wolf_snapshot.png'
v.save_canvasogl(fn=str(out))
print(f'Saved → {out}')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[9], line 5
2 from pathlib import Path
4 out = Path.home() / 'wolf_snapshot.png'
----> 5 v.save_canvas(str(out))
6 print(f'Saved → {out}')
AttributeError: 'WolfMapViewer' object has no attribute 'save_canvas'
[ ]:
# Programmatic zoom to a bounding box (Lambert 72 / 2008 coords).
# v.zoom_on_bounds(xmin, ymin, xmax, ymax)
# v.Autoscale(False)
# v.Paint()
Section D — Comparison with the standalone app (wolf.py)
# wolf.py (standalone)
ex = wx.App()
mywolf = MapManager() # splash=True by default
ex.MainLoop() # blocks until the window closes
# notebook (this file)
%gui wx # IPython manages the event loop
app = wx.App(False)
manager = MapManager(splash=False) # no MainLoop() call
v = manager.mapviewer # keep running cells while the window is live
The only differences are %gui wx, splash=False, and the absence of MainLoop(). Everything else — objects, methods, data — is identical.
Section E — Closing
Close the viewer window normally, or from a cell:
[ ]:
# v.Close() # closes the viewer frame
# manager.Close() # also closes the manager frame (log window, etc.)