mirror of
https://github.com/opengeos/GeoLibre.git
synced 2026-11-06 17:45:23 +00:00
b01611255e1663d6a3d33e90fcf538ba2adbb17d
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5ecb05760e |
docs: correct the user guide against the running app and add screenshots (#2112)
* 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> |
||
|
|
ccaf754005 |
Follow-up: notebook style review fixes (#1620)
* Address follow-up review feedback on #1619
Second round of bot review comments on #1619, which merged before they could
be addressed on that branch.
- docs/notebook.md: drop the `layer_id`-taking calls from the snippet instead
of annotating them. The fire-and-forget client can never produce an id, so
the example was self-contradictory; the calls are now described in prose
below it, pointing at the widget client that does return ids.
- console_api.py: give `load_geojson` the same `**style` kwargs as
`add_geojson`, so both console entry points style in one call.
- tests/scripting-style-params.test.ts: set the history coalesce window to 0
so the empty-style guard is actually under test (at the app's default window
the two writes merge and the assertion passed either way — verified by
mutating the guard), and add a case pinning the app-window behavior: a
styled add coalesces into one undo entry, so one Ctrl+Z removes the layer
rather than leaving an unstyled one behind.
* Address review feedback
- Capture the app's history coalesce window with `getHistoryCoalesceMs()` and
restore that, instead of hard-coding 400 in the cleanup path and in the
coalescing case, so the test follows the source default if it moves.
* Address Claude review feedback
- Document the `**style` kwargs on `load_geojson` in the Python console API
table; the signature gained them in
|
||
|
|
4ad82800a2 |
Support inline GeoJSON styles in notebook bridge (#1619)
* fix: support inline GeoJSON styles in notebooks
* fix: skip empty notebook style updates
* Address review feedback
- Extract the empty-style guard in `addGeoJsonLayer` into a documented
`styleParamPatch` helper (`scripting/style-params.ts`), so the rule that a
`{}` payload writes nothing is testable on its own. The scripting module
itself pulls in the plugin/map stack (and its CSS) and cannot be imported
under `node --test`.
- Add `tests/scripting-style-params.test.ts`: covers the patch helper and
replays what the handler does against the real store — the style merges onto
the new layer, and a style-less call still costs exactly one undo step.
- docs/notebook.md: flag that the fire-and-forget client returns no layer id,
so the `layer_id`-taking calls in the snippet need one from the blocking
widget client.
* Address Claude review feedback
- Give the in-app Pyodide console's `add_geojson` the same `**style` kwargs as
the notebook client, so one-call styling behaves identically across both
Python entry points (flagged in the review summary as an inconsistency).
* Document the console's inline add_geojson styles
- Update the Python console user guide for the `**style` kwargs added to
`console_api.add_geojson` in
|
||
|
|
6f3f4ade7a |
feat(scripting): Python automation API + in-app Python Console (#327)
* feat(scripting): Python automation API + in-app Python Console Add two PyQGIS-style ways to script GeoLibre programmatically. Notebook API (geolibre.Map anywidget): - Request/reply command channel + event channel over the anywidget custom message bus, relayed by _frontend.js into the embedded app. - App-side dispatcher (useCommandBridge) backed by a shared scriptingApi factory; MapController gains flyTo() and identifyFeatures(). - Python request()/on() primitives (blocking via jupyter-ui-poll) plus get_center, get_bounds, fly_to, fit_bounds, identify, get_features, run_algorithm, list_algorithms, to_image, and a Layer/Feature model. In-app Python Console: - Dockable, resizable bottom panel (Processing -> Python Console), not a modal. - Main-thread Pyodide runtime (minimal/fast startup, on-demand packages, async execution) exposing a `geolibre` facade that drives the live store and map, sharing the same scriptingApi handlers as the notebook bridge. Extracts the embed-host handshake into embedHost.ts (shared by both bridges). * Address Claude review feedback - pyodide-console: destroy the result JsProxy in a finally so a throwing toString() can't leak it. - map-controller (featureIdForLayer): return null when the rendered feature has no properties, instead of vacuously matching the first source feature. - _frontend.js: cap the pre-ready pendingCommands queue at 500 as a defensive bound. - console_api to_image: return PNG bytes to match the notebook Map.to_image() return type (host-path writing isn't available in-browser). * Address CodeRabbit review feedback - test_scripting: inject a fake jupyter_ui_poll via sys.modules instead of patching by string path, fixing the package-publish CI job which lacks the optional dependency (ModuleNotFoundError). - map-controller (featureIdForLayer): only return a property-matched id for an unambiguous single hit (compare full key sets), else null — supersedes the empty-properties guard and avoids wrong ids for non-unique features. - geolibre.request: move send() inside the try so a failing send() still pops the pending slot. - console_api Layer: sync self._info in the visible/opacity setters so later reads on the same handle aren't stale; add -> None annotations. - PythonConsolePanel: show runtime-init failures as an error (no spinner), separate from loading progress. - embedHost: document the ?embed=1 trust model / deployment constraint. - scriptingApi.toImage: note the synchronous PNG encode blocks the main thread. * Address review feedback (round 2) - embedHost.isEmbedded: auto-trust only a SAME-ORIGIN framing parent by probing window.parent.location.href (which throws cross-origin); `window.parent !== window` does not throw cross-origin, so the old check would auto-activate the bridge for a third-party framer. Doc corrected. - useCommandBridge: dispatch only own-property handlers (Object.hasOwn), so an inherited member like "constructor"/"toString" can't be invoked as a command. - scriptingApi.setBasemap: validate the url is an http(s)/root-relative string (rejects undefined -> "undefined" and javascript:/data: schemes). - console_api.load_geojson: raise on non-ok HTTP responses instead of parsing an error body as GeoJSON. - to_image (both notebook geolibre.py and console_api): raise on a data URL with no comma instead of silently returning empty bytes. - PythonConsolePanel: tear down in-flight drag listeners on unmount. - pyodide-console: drop the redundant scriptPromise reset in script.onerror. - geolibre.request: register the pending slot inside the try. * docs: add Python Console guide and interactive scripting API reference - New user-guide page (user-guide/python-console.md) covering the in-app Python Console: opening/docking, first-run runtime load, driving the map, async await, on-demand packages, and a full geolibre/Layer/Feature API reference. - python.md: document the interactive scripting surface (live queries, events, processing, to_image, Layer/Feature) that the notebook widget shares with the console, with a new API-reference subsection. - mkdocs.yml: add the Python Console page to the User Guide nav. * feat(python-console): command history, autocomplete, eraser icon - Up/Down arrows recall previous/next submitted commands (only when the caret is on the first/last line, so multi-line editing still works); a draft is saved when history navigation starts. - Tab / Ctrl+Space autocomplete the name or attribute at the caret, backed by a new _geolibre_complete() that introspects the live Pyodide namespace (real geolibre methods, user variables, builtins, keywords; private names hidden). A single match inserts directly; multiple show a dropdown (Up/Down to choose, Enter/Tab to accept, Esc to dismiss). - Swap the Clear-output icon from Trash2 to Eraser. - Docs: document the editing shortcuts in the Python Console guide. * feat(python-console): QGIS-style script editor alongside the console - "Show editor" toggle splits a script editor into the Python Console panel (left), with a draggable vertical divider; hidden by default. - The editor runs in the SAME Pyodide interpreter as the console (shared globals), so scripts and the REPL share state. Run executes the whole buffer or the current selection; output goes to the console scrollback. - Open/Save/Save As/New for .py files via the app's cross-platform file I/O (openLocalDataFileWithFallback / saveTextFileWithFallback); desktop Save writes in place via new tauri-io writeTextFileToPath, web downloads. Dirty marker + discard confirmation. - Editor keys: Ctrl/Cmd+Enter run, Ctrl/Cmd+S save, Tab indent, Ctrl+Space autocomplete. - Factor the console autocomplete into a shared usePyCompletion hook (with a tabTriggers option) reused by both the console input and the editor. - Add i18n strings and document the script editor in the user guide. * Address review feedback (round 3) - featureIdForLayer: return null for zero-property features (no fake index id), and compare object/array property values by JSON (MapLibre re-parses them to fresh refs, so === always failed). - scriptingApi.setOpacity: reject non-finite and clamp to [0,1]. - notebook Map: add set_basemap alias (name parity with the console facade). - PythonConsolePanel: dispatch PANEL_RESIZE_END on unmount mid-drag so MapCanvas clears panelResizeActive. - pyodide-console: serialize runs through a queue so overlapping calls can't clobber the instance-global stdout/stderr capture; document the merged stdout/stderr stream. - usePyCompletion: clamp completion splice offsets against current code. - geolibre._wait_for_result: check the deadline before and after poll() so a slow pump can't overrun a small timeout. * feat(python-editor): clear button; address review feedback (round 4) - Add a "Clear editor" eraser button to the script editor toolbar (empties the buffer, keeping the filename; confirms when there are unsaved changes). - PythonConsolePanel: throttle the editor splitter drag through requestAnimationFrame with direct DOM writes (commit to state on mouseup), and give the vertical and horizontal drags separate cleanup refs so one can't overwrite the other's teardown. - _frontend.js: warn when the pre-ready command queue is full instead of silently dropping, so a full queue is diagnosable. - geolibre._wait_for_result: poll at 20 Hz (sleep 0.05) instead of 100 Hz to cut idle CPU; deadline is still checked each iteration. * Address review feedback (round 5) - PythonEditorPane: Tab now block-indents every selected line with 4 spaces (PEP 8) instead of replacing a multi-line selection with two spaces; the selection is preserved. - scriptingApi: validate layerId is a non-empty string across the layer handlers (getLayerFeatures/removeLayer/setVisibility/setOpacity/setStyle/zoomToLayer) via a shared requireLayerId, matching identify. - _frontend.js: post commands straight through once ready instead of a push→flush cycle; only buffer before ready. - pyodide-console: remove the failed <script> element on load error so retries don't orphan dead tags in <head>. |