> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wherobots.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Map widget (wherobots_gl)

> Render the Wherobots map inline in a Jupyter notebook.

```python theme={"system"}
from wherobots_gl import Map
```

## Map

```python theme={"system"}
Map(
    layers: Optional[list[LayerInput]] = None,
    view: Optional[dict[str, float]] = None,
    basemap: str = 'light',
    height: Union[str, float] = DEFAULT_HEIGHT,
    aws_credentials: Optional[dict[str, str]] = None,
    credentials_provider: Optional[CredentialsProvider] = None,
    *,
    projection: str = 'mercator',
    terrain: bool = False,
    **kwargs: Any,
)
```

An inline Wherobots-GL map widget for Jupyter notebooks.

#### Parameters

<ParamField path="layers" type="Optional[list[LayerInput]]" default="None">
  Layers to render. Each entry is either a **bare source URL string**
  (the layer `type` is inferred from the URL's extension) or a
  **config dict**. A dict needs only `source`; an explicit `type`
  (`zarr` / `pmtiles` / `cog` / `geoparquet`) wins over
  inference, and any other layer option, such as `opacity`, is passed
  to the map unchanged. Examples:

  ```python theme={"system"}
  Map(layers=["s3://bucket/scene.zarr"])               # bare string
  Map(layers=[{"source": ".../tiles.pmtiles"}])        # dict, no type
  Map(layers=[{"type": "cog", "source": "...", "opacity": 0.5}])
  ```
</ParamField>

<ParamField path="view" type="Optional[dict[str, float]]" default="None">
  Map viewport `{"zoom", "lat", "lng", "bearing", "pitch"}` — the last
  two in degrees (rotation clockwise from north, and tilt from straight
  down), written back with the rest so a tilted 3D-terrain camera
  round-trips. Both may be omitted when constructing; they default to 0.
  Updated in place when the
  user pans/zooms. Empty (`{}`) on a `from_url` map built
  without a `view` kwarg: the URL's `z`/`lat`/`lng` (or the
  map's default view) apply until the first pan writes it back.
</ParamField>

<ParamField path="basemap" type="str" default="'light'">
  Basemap style. One of `BASEMAP_STYLES`. Set from Python only —
  the widget shows no basemap switcher; assigning `m.basemap` re-styles
  the map. Empty (`""`) on a `from_url` map built without a
  `basemap` kwarg: the URL's `basemap=` (or the map's default)
  applies until one is assigned.
</ParamField>

<ParamField path="height" type="Union[str, float]" default="DEFAULT_HEIGHT">
  Map height as a CSS length string (e.g. `"600px"`, `"80vh"`) or a
  number of pixels. Defaults to `DEFAULT_HEIGHT`.
</ParamField>

<ParamField path="aws_credentials" type="Optional[dict[str, str]]" default="None">
  Optional **static, global** `{"accessKeyId", "secretAccessKey",
    "sessionToken"?}` for private S3 sources. Held in kernel memory and
  never stored in the widget state, so it is never embedded in a saved
  `.ipynb`. Takes precedence over `credentials_provider` and applies to
  every source. Leave `None` for public URLs or to use per-source minting.
  Reassign `m.aws_credentials = {...}` to update a live map.
</ParamField>

<ParamField path="credentials_provider" type="Optional[CredentialsProvider]" default="None">
  Optional callable `(source_url, region) -> creds_dict | None` invoked
  once per private source to mint **path-scoped** credentials on demand.
  When neither this nor `aws_credentials` is given, credentials are
  minted through Wherobots storage credentials, so a private-S3 map works
  out of the box in a Wherobots kernel and no credentials are used when no
  Wherobots authentication is available.
</ParamField>

<ParamField path="projection" type="str" default="'mercator'">
  Map projection — one of `MAP_PROJECTIONS`. `"globe"` renders the
  same basemap and layers on a 3D sphere; `"mercator"` (the default) is
  the flat map. Set from Python only — the widget shows no globe toggle;
  assigning `m.projection` reprojects the map in place (layers are not
  reloaded). Empty (`""`) on a `from_url` map built without a
  `projection` kwarg: the URL's `projection=` (or the map's
  default) applies until one is assigned.
</ParamField>

<ParamField path="terrain" type="bool" default="False">
  Whether to render 3D terrain (a shipped elevation source; exaggeration is
  fixed at 1). Orthogonal to `basemap` — relief sits under any style. Set
  from Python only; the widget shows no toggle. **Zarr, COG and GeoParquet
  layers are hidden by terrain**, because they render without elevation
  and would end up behind the ground, and a `WARNING` is logged when
  both are present; PMTiles is unaffected.
</ParamField>

<ParamField path="kwargs" type="Any" />

### aws\_credentials

```python theme={"system"}
Map.aws_credentials: Optional[dict[str, str]]
```

Credentials for private S3 sources (kernel-memory only).

Held in the kernel and never stored in the widget state, so they are
never written into a saved `.ipynb`. Assigning new credentials updates
a map that is already displayed.

### viewport\_bbox

```python theme={"system"}
Map.viewport_bbox: Optional[tuple[float, float, float, float]]
```

Current viewport as `(west, south, east, north)` in EPSG:4326, or
`None` if the map hasn't reported its bounds yet (it reports once the
map first renders).

Order matches the common `(minx, miny, maxx, maxy)` bbox convention, so
e.g. `shapely.geometry.box(*m.viewport_bbox)` works directly. Also
`None` if the map reports bounds that are not numbers.

### viewport\_bbox\_wkt

```python theme={"system"}
Map.viewport_bbox_wkt: Optional[str]
```

Current viewport as a WKT `POLYGON` (EPSG:4326), or `None` if the
map hasn't reported bounds yet. Feed it to Spatial SQL via
`ST_GeomFromText`.

### add\_layer()

```python theme={"system"}
add_layer(layer: LayerInput) -> None
```

Append a layer and update the map.

#### Parameters

<ParamField path="layer" type="LayerInput" required>
  A source URL string or a layer config dict, as in `layers`.
</ParamField>

### close()

```python theme={"system"}
close() -> None
```

Close the widget and release its background credential threads.

Safe to call more than once. The notebook also calls it when the widget
is disposed.

### from\_url()

```python theme={"system"}
Map.from_url(url: str, **kwargs: Any) -> Map
```

Build a `Map` from a wherobots-gl share URL (or query string).

The map reads the URL the same way the Wherobots web app does, so a
shared map opens with the same layers, view and settings. The reverse,
turning a map built in Python into a share URL, is not supported (see
`to_url`).

#### Parameters

<ParamField path="url" type="str" required>
  A full `https://…?…` share URL, a `"?z=…&l0.src=…"` string, or
  a bare `"z=…&l0.src=…"` query. Extra `kwargs` (`basemap`,
  `projection`, `terrain`, `height`, `aws_credentials`) are
  passed to `__init__`.
</ParamField>

<ParamField path="kwargs" type="Any" />

### to\_sql\_filter()

```python theme={"system"}
to_sql_filter(geometry: str = 'geometry') -> Optional[str]
```

Spatial-SQL predicate restricting `geometry` to the current viewport:
`ST_Intersects(<geometry>, ST_GeomFromText('POLYGON(...)', 4326))`.
Returns `None` if the map hasn't reported bounds yet.

The bounds are EPSG:4326 (lng/lat); the predicate assumes `geometry` is
also 4326 — wrap it in `ST_Transform` yourself if your column's CRS
differs. Example:

```python theme={"system"}
sedona.sql(f"SELECT * FROM t WHERE {m.to_sql_filter('geom')}")
```

#### Parameters

<ParamField path="geometry" type="str" default="'geometry'">
  Name of the geometry column to filter, or any SQL expression that
  returns a geometry.
</ParamField>

### to\_url()

```python theme={"system"}
to_url() -> str
```

Return the share-URL query this map was built from with `from_url`.

Changes made afterwards, such as layers added in Python or the current
viewport, are not encoded, and a map not built from a URL returns an
empty string.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.