mirror of
https://github.com/opengeos/GeoLibre.git
synced 2026-11-06 17:45:23 +00:00
* docs: correct the user guide against the running app and add screenshots Several pages had drifted from the shipped UI: the toolbar was documented as seven menus with Edit and View missing entirely, Add Data omitted ten entries, the plugin and style-type lists were from an older release, and the terrain tutorial claimed raster tools need the desktop app when eight of them have a browser engine. Every claim here was rechecked by driving the app, and the Browser panel, Model Builder, Dashboard, and the attribute table's own tools are now documented rather than only mentioned in the feature list. * fix(mkdocs): update GeoLibre Web link in documentation * Address Claude review feedback - Correct the `C` shortcut row: it toggles the review-comment tool and the pin lands where you click next, not at the map center. Also mention the shortcut in the Review comments section, which only documented the panel. - Give Managing Layers its own Layers-panel screenshot instead of reusing the full-workspace shot from Interface Overview, which did not match the alt text. * Address CodeRabbit review feedback - Name both projection-aware engines in the buffer tip. Python (Pyodide) runs the same GeoPandas path as the sidecar and is the one available on the web build, so pointing only at the sidecar sends web users nowhere. - Stop claiming every on-map-control plugin has a positioning submenu. Flight Simulator and SamGeo toggle directly, and Web Services and DGGS open a list of sub-plugins instead. * Update mkdocs.yml Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
169 lines
7.3 KiB
Markdown
169 lines
7.3 KiB
Markdown
# 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",
|
||
fillColor="#facc15", # style overrides are applied in the same call
|
||
)
|
||
|
||
# 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=, **style)` | Add a layer from a GeoJSON dict / geometry / `__geo_interface__`, with optional inline style overrides; returns the layer id. |
|
||
| `await load_geojson(url, name=, **style)` | Fetch a GeoJSON URL and add it, with the same optional inline style overrides; 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 (0–1). |
|
||
| `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.
|