Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lonboard/_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ def as_html(self) -> HTML:

@t.default("view_state")
def _default_initial_view_state(self) -> dict[str, Any]:
if isinstance(self.view, (MapView, GlobeView)):
if self.view is None or isinstance(self.view, (MapView, GlobeView)):
return compute_view(self.layers) # type: ignore

return {}
27 changes: 24 additions & 3 deletions lonboard/_viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import json
from textwrap import dedent
from typing import TYPE_CHECKING, Any, Protocol, TypeAlias, cast
from typing import TYPE_CHECKING, Any, Literal, Protocol, TypeAlias, cast

import numpy as np
from arro3.core import Array, ChunkedArray, Schema, Table, struct_field
Expand All @@ -26,6 +26,7 @@
)
from lonboard.basemap import CartoStyle, MaplibreBasemap
from lonboard.layer import PathLayer, PolygonLayer, ScatterplotLayer
from lonboard.view import BaseView, GlobeView

if TYPE_CHECKING:
import duckdb
Expand Down Expand Up @@ -81,13 +82,14 @@ def __geo_interface__(self) -> dict: ...
DEFAULT_POLYGON_LINE_COLOR = [0, 0, 0, 200]


def viz(
def viz( # noqa: PLR0913
data: VizDataInput | list[VizDataInput] | tuple[VizDataInput, ...],
*,
scatterplot_kwargs: ScatterplotLayerKwargs | None = None,
path_kwargs: PathLayerKwargs | None = None,
polygon_kwargs: PolygonLayerKwargs | None = None,
map_kwargs: MapKwargs | None = None,
view: BaseView | Literal["globe"] | None = None,
) -> Map:
"""Plot your data easily.

Expand Down Expand Up @@ -165,6 +167,7 @@ def viz(
[`PolygonLayer`][lonboard.PolygonLayer]s.
map_kwargs: a `dict` of parameters to pass down to the generated
[`Map`][lonboard.Map].
view: a [view instance][lonboard.view.BaseView] to use for the map view, or the string "globe".

For more control over rendering, construct [`Map`][lonboard.Map] and `Layer` objects
directly.
Expand Down Expand Up @@ -200,8 +203,26 @@ def viz(

map_kwargs = map_kwargs if map_kwargs else {}

if "view" not in map_kwargs and view is not None:
if view == "globe":
map_kwargs["view"] = GlobeView()
else:
map_kwargs["view"] = view

if "basemap_style" not in map_kwargs and "basemap" not in map_kwargs:
map_kwargs["basemap"] = MaplibreBasemap(style=CartoStyle.DarkMatter)
map_kwargs["basemap"] = MaplibreBasemap(
mode="interleaved",
style=CartoStyle.DarkMatter,
)

# If we're using a known style that has labels, set layers to be below labels
if map_kwargs["basemap"].style in [
CartoStyle.DarkMatter,
CartoStyle.Positron,
CartoStyle.Voyager,
]:
for layer in layers:
layer.before_id = "watername_ocean"

return Map(layers=layers, **map_kwargs)

Expand Down
14 changes: 13 additions & 1 deletion tests/test_map.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import geopandas as gpd
import pytest
from geodatasets import get_path
from traitlets import TraitError

from lonboard import Map, ScatterplotLayer, SolidPolygonLayer
from lonboard import Map, ScatterplotLayer, SolidPolygonLayer, viz
from lonboard.basemap import MaplibreBasemap
from lonboard.view import FirstPersonView, GlobeView, OrthographicView
from lonboard.view_state import (
Expand Down Expand Up @@ -182,3 +184,13 @@ def test_map_view_validate_globe_view_basemap():
match=r"GlobeView requires the basemap mode to be 'interleaved'.",
):
m.view = GlobeView()


def test_default_view_state_inferred():
gdf = gpd.read_file(get_path("nybb"))
m = viz(gdf)
view_state = m.view_state
assert isinstance(view_state, MapViewState)
assert view_state.longitude - (-73.90) < 1e-2
assert view_state.latitude - 40.67 < 1e-2
assert view_state.zoom == 9