render_geolibre

render_geolibre class

Reactively render a GeoLibre map – the full GeoLibre GIS app embedded as a widget.

Usage Source

render_geolibre(
    _fn: Optional[ValueFn[ValueT]] = None,
    *,
    width: Optional[str] = None,
    height: Optional[str] = None,
    fill: Optional[bool] = None,
    fillable: Optional[bool] = None,
    rate_policy: Optional[RatePolicy] = None,
    rate_delay: Optional[float] = None,
)

@render_geolibre is a decorator that creates a render function – a function that returns the map to display and re-runs when the reactive values it reads change:

from geolibre import Map

from shinywidgets import render_geolibre


@render_geolibre
def map():
    return Map()

The render function should return a geolibre.Map (requires pip install 'shinywidgets[geolibre]'). In a filling layout, the map fills its container unless the Map was given a height other than geolibre’s default ("800px"). The height is read once, when the embedded app loads, so changing .widget.height after rendering has no effect (resize the output’s container instead).

Note

Accessing the rendered widget: the render function gains two read-only attributes: .value and .widget, both the rendered geolibre.Map instance.

Responding to user interaction: user edits in the app (panning, zooming, adding or restyling layers) sync back to the project trait, so map.read("project") gives you the live project – but note it invalidates on every pan and zoom, and carries the whole project (including inlined layer data), so prefer the event callbacks for high-frequency interactions: register map.widget.on_click(), on_selection_change(), or on_layer_change() inside the render function and have the callback set a reactive.value.

Mutating the widget: methods that edit the map’s project (its synced document) work as they do in Jupyter – add_geojson()/add_vector()/add_cog()/etc., set_center()/set_zoom()/fit_project_bounds(), layer styling (get_layer(id).set_style()/set_opacity()), and set_identify()/show_control(). Methods that send a command to the app and wait for its reply – fly_to(), fit_bounds(), zoom_to_layer(), identify(), get_center()/get_view()/get_bounds(), get_selected_features()/get_drawn_features(), run_algorithm(), and to_image() – can’t run inside a render function, reactive.calc, or reactive.effect/observer (sync or async): the reply is only delivered once the effect finishes, so waiting for it there deadlocks. Instead, await the *_async() variants (fly_to_async()/get_center_async()/…) in a reactive.extended_task, which runs outside that flush. Where a non-blocking alternative exists – set_center() for fly_to(), fit_project_bounds() for fit_bounds(), the synced project trait for the query methods – it remains the cheaper option.

Network access: shinywidgets serves the bundled GeoLibre app from the Shiny app itself, so the widget works in deployed apps (shinyapps.io, Posit Connect, …) as well as locally. This includes layers read from files on the server’s disk (e.g., add_cog()/add_raster() of a local GeoTIFF): geolibre serves those from a localhost server in the Python process, and shinywidgets mounts a reverse proxy at /proxy/{port}/ that forwards that server to the browser, same-origin (the same role jupyter-server-proxy plays for Jupyter servers). Note this makes the localhost server reachable by anyone who can reach the app; its file routes are protected by unguessable per-process tokens. Basemap tiles and remote data URLs require internet access from the browser.

The app_layout parameter: geolibre.Map(app_layout=...) chooses the app’s chrome ("embed", "full", or "maponly"). (geolibre < 3.6.1 named this parameter layout, shadowing ipywidgets’ Layout trait; geolibre >= 3.6.1 renamed it to app_layout and deprecated passing a string as layout.)

Parameters

width : Optional[str] = None

A CSS length unit (e.g., "400px" or "100%") for the output’s width.

height : Optional[str] = None

A CSS length unit for the output’s height. When None (the default), the output is designed to fill the height of its parent container (see fill and fillable).

fill : Optional[bool] = None

Whether the output should grow or shrink to fit its parent container. When None (the default), this is True if height is not specified.

fillable : Optional[bool] = None

Whether the output container should fill available space (scrolling its contents on overflow). When None (the default), this is True if height is not specified.

See also

output_widget(): in Shiny Core, the UI needs this to hold the output (Shiny Express displays it where the render function is defined).