Files
wehub-resource-sync 7df9ebf22c
Sync labels / sync (push) Failing after 1m9s
Publish Container Image / Build and publish container image (push) Has been cancelled
Deploy Website / Deploy to GitHub Pages (push) Has been cancelled
Deploy Website / Build website and demo (push) Has been cancelled
Deploy viewer / Deploy viewer proxy to Cloudflare Workers (push) Has been cancelled
Deploy tiles / Deploy planetary tile proxy to Cloudflare Workers (push) Has been cancelled
Deploy collab / Deploy collaboration relay to Cloudflare Workers (push) Has been cancelled
CI / Dependency audit (push) Has been cancelled
CI / E2E smoke (Playwright) (push) Has been cancelled
CI / Validate CITATION.cff (push) Has been cancelled
CI / Build and test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:00 +08:00

165 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Python Console
The **Python Console** runs Python right inside the app, against the map you are
looking at. Open it from **Processing → Python Console**. It docks as a
resizable panel at the bottom of the window (drag its top edge to resize, and the
**✕** button to close it) — it does not block the rest of the app.
Python runs in your browser via [Pyodide](https://pyodide.org) (CPython compiled
to WebAssembly), so it works in both the web and desktop builds with nothing to
install. The console exposes a single object, **`geolibre`**, that drives the
live app — its methods mirror the [`geolibre` Python package](../python.md), so
what you learn here transfers to notebooks and back.
## First run
The Python runtime downloads the first time you open the console (a one-time
download of a few MB, shown as a progress message in the header). After that it
stays warm, and your variables persist as long as the app is open — even if you
close and reopen the panel.
Type code in the input box and press **Ctrl/Cmd + Enter** (or click **Run**) to
execute it. Output, return values, and errors appear in the scrollback above.
### Editing shortcuts
| Key | Action |
| --- | --- |
| **Ctrl/Cmd + Enter** | Run the current code |
| **Enter** | Newline (multi-line editing) |
| **↑ / ↓** | Recall previous / next command (when the caret is on the first / last line) |
| **Tab** or **Ctrl + Space** | Autocomplete the name or attribute at the caret |
Autocomplete introspects the **live** runtime, so `geolibre.` lists its real
methods, and your own variables and any imported modules complete too. When more
than one candidate matches, a list appears — use **↑/↓** to choose and
**Enter/Tab** to accept, or **Esc** to dismiss.
```python
geolibre.get_center() # [lng, lat] of the current view
geolibre.get_bounds() # [west, south, east, north]
geolibre.fly_to(-122.4, 37.8, zoom=10)
```
## Script editor
For multi-line scripts you want to keep, click **Show editor** (the panel icon in
the header) to open a script editor beside the console — like QGIS's Python
editor. Drag the divider to resize it, and click the icon again to hide it.
The editor **shares the console's interpreter**, so a variable or function you
define in a script is immediately usable in the console, and vice-versa.
- **New / Open / Save / Save As** work with `.py` files. On the desktop app, Save
writes back to the open file; in the browser it downloads (or uses the
File System Access API). An unsaved file shows a `•` next to its name.
- **Run** (or **Ctrl/Cmd+Enter**) executes the whole script — or just the
**selected** lines if you have a selection. Output and errors appear in the
console on the right.
- **Tab** indents, **Ctrl+Space** autocompletes, and **Ctrl/Cmd+S** saves.
## Driving the map
```python
# Add data (a GeoJSON dict, a geometry, or anything with __geo_interface__)
layer_id = geolibre.add_geojson(
{"type": "Point", "coordinates": [-122.4, 37.8]}, name="Pin"
)
# Style, toggle, and inspect layers
layer = geolibre.get_layer(layer_id)
layer.opacity = 0.6
layer.visible = False
layer.set_style(circleRadius=8, fillColor="#ff0000")
for layer in geolibre.layers:
print(layer.name, layer.type, layer.visible)
# Identify features at a point (like clicking the map)
hits = geolibre.identify(-122.4, 37.8)
```
## Async operations
The console supports top-level `await`. A few operations are asynchronous and
must be awaited:
```python
# Fetch a remote GeoJSON URL and add it
await geolibre.load_geojson("https://example.com/data.geojson", name="Data")
# Run a processing algorithm; result layers are added to the map
geolibre.list_algorithms() # discover ids + parameters
result = await geolibre.run_algorithm("buffer", {"layer": layer_id, "distance": 1000})
print(result["logs"], result["resultLayerIds"])
```
## Loading more packages
To keep startup fast, only the base runtime loads up front. Pull in additional
packages on demand:
```python
await geolibre.load_package("numpy")
import numpy as np
np.array([1, 2, 3]).mean()
await geolibre.load_package("geopandas") # also pulls shapely/pyproj/pandas
```
Any package in the [Pyodide distribution](https://pyodide.org/en/stable/usage/packages-in-pyodide.html)
is available this way.
## `geolibre` API reference
| Method | Description |
| --- | --- |
| `get_view()` | Live camera `{center, zoom, bearing, pitch, bbox}`. |
| `get_center()` | Live map center `[lng, lat]`. |
| `get_bounds()` | Live viewport bounds `[west, south, east, north]`. |
| `fly_to(lng, lat, zoom=, bearing=, pitch=, duration=)` | Animate the camera; only the given fields change. |
| `fit_bounds([w, s, e, n])` | Fit the camera to a bounding box. |
| `set_basemap(url)` | Set the basemap style (an http(s) or root-relative URL). |
| `identify(lng, lat, layer_id=None)` | Query rendered features at a point (like a click). |
| `add_geojson(data, name=)` | Add a layer from a GeoJSON dict / geometry / `__geo_interface__`; returns the layer id. |
| `await load_geojson(url, name=)` | Fetch a GeoJSON URL and add it; returns the layer id. |
| `layers` | List of [`Layer`](#layer) objects, in draw order. |
| `get_layer(layer_id)` | The `Layer` with that id (raises if absent). |
| `remove_layer(layer_id)` | Remove a layer by id. |
| `list_algorithms()` | Available processing algorithms (`id`, `name`, `group`, `parameters`). |
| `await run_algorithm(id, parameters=None)` | Run an algorithm; adds result layers and returns `{logs, resultLayerIds}`. |
| `to_image()` | Capture the current map as PNG **bytes**. |
| `await load_package(name)` | Load a Pyodide package on demand. |
### `Layer`
A handle returned by `geolibre.layers` / `geolibre.get_layer(...)`.
| Member | Description |
| --- | --- |
| `id`, `name`, `type` | Identity (read-only). |
| `visible` | Get/set visibility. |
| `opacity` | Get/set opacity (01). |
| `set_style(**style)` | Merge style overrides (e.g. `fillColor="#ff0000"`). |
| `get_features()` | The layer's features as [`Feature`](#feature) objects. |
| `zoom_to()` | Fit the camera to the layer's extent. |
| `remove()` | Remove the layer from the map. |
### `Feature`
A GeoJSON feature returned by `Layer.get_features()`. It *is* a plain `dict`
(so it serializes and feeds into `geopandas.GeoDataFrame.from_features`), with
convenience accessors `.geometry`, `.properties`, `.id`, and `__geo_interface__`.
## Notes & limitations
- **Runs on the main thread**, by design, so Python can drive the live map
synchronously. A long-running cell briefly pauses the UI — avoid tight loops
and prefer `await geolibre.run_algorithm(...)` for heavy work.
- **Sandboxed.** Pyodide cannot read your computer's filesystem or reach the
desktop app's local tools; network access follows the app's content-security
policy. `to_image()` therefore returns bytes rather than writing a file.
- **Same API as notebooks.** The [`geolibre` Python package](../python.md)
exposes the same methods from a Jupyter `Map` object, so console snippets and
notebook code are interchangeable.