Skip to content

Conversation

kylebarron
Copy link
Member

@kylebarron kylebarron commented Oct 8, 2025

Change list

  • Ensure that the default value of Map.basemap is MaplibreBasemap if no value of basemap was passed. Add a test for this.
  • Define various View classes to map to deck.gl views.
  • Define View models on the TS side.
  • When a GlobeView is passed, pass projection="globe" to Maplibre
  • Render a dark background on the canvas when in globe view
  • Add views parameter to Map. For now this only supports a single view instance, but hopefully in the future it'll support more.

This PR also sets the stage for non-geospatial map rendering and for multi-view support.

todo:

With this PR, to generate a map with globe view, someone would call

from lonboard import Map
from lonboard.view import GlobeView
from lonboard.basemap import MaplibreBasemap

lonboard.Map(
	layer,
	views=GlobeView(),
	basemap=MaplibreBasemap(mode="interleaved"),
)

Globe view:

image

Closes #886 (globe view), closes #375 (orthographic view) (though might need more work to allow non-spatial data)

Relates to

@vgeorge
Copy link
Member

vgeorge commented Oct 9, 2025

@kylebarron The general approach seems quite comprehensive. I’d suggest implementing the different modes more progressively, as this will likely require some refactoring on the JS side. In hindsight, adding XState wasn’t the best choice on my part, it makes state management a bit harder to evolve. I’ll open a ticket to propose an alternative. I think we can still address this technical debt while it’s not too complex, but not on this PR.

@kylebarron
Copy link
Member Author

I think despite what are a bunch of changes here on the Python side, the JS side only needs to change to support two modes: One with mapbox overlay and one without.

We can also merge this PR or something similar without exposing the classes to users, so we can keep developing on the JS side

@vgeorge
Copy link
Member

vgeorge commented Oct 10, 2025

@kylebarron sounds good. Now that we merged the Playwright PR we can add specs to ensure JS features continue to work as expected.

kylebarron added a commit that referenced this pull request Oct 14, 2025
…lay (#921)

As described in the [upstream deck.gl
docs](https://deck.gl/docs/developer-guide/base-maps/using-with-maplibre),
there are three ways to support using deck.gl with Maplibre:
_interleaved_, _overlaid_, and _reverse-controlled_. The first two are
supported via `MapboxOverlay` with a prop `interleaved: true|false`,
while the latter is implemented by having Maplibre be a child of the
deck.gl Map.

There are worthwhile reasons to support all of these modes. We need to
use interleaved or overlaid to support globe view, while
reverse-controlled better supports multiple deck.gl views.

This PR refactors the map component in `index.tsx` into two separate
React components: a deck.gl-first renderer (i.e. "reverse-controlled")
and a MapboxOverlay renderer.

The idea is that this will pair with #908 to give users more control
over various ways of rendering maps.

This is backwards-compatible because we default to reverse-controlled,
the existing default.

Closes #890, closes
#437, for
#886, for
#718
kylebarron added a commit that referenced this pull request Oct 15, 2025
A small refactor to make it easier to read `_map.py` by removing the
HTML export functionality, moving that to `_html_export.py`. This was
extracted from #908, see
https://github.com/developmentseed/lonboard/pull/908/files#r2414276602
kylebarron added a commit that referenced this pull request Oct 15, 2025
In ipywidgets, a "model" is the core of reactivity. In particular, a
Lonboard `Map` is reactive, but every underlying layer is _also_
reactive, so that when a user changes any property on a layer, it
automatically gets updated on the map.

By extension, our
[`Extension`](https://developmentseed.org/lonboard/latest/api/layer-extensions/)
classes are also themselves models. These are separate Python classes
that get serialized as their own reactive models on the JS side.

Soon we'll have more types of widget models that we want to be reactive,
including views and basemap styles (#908).

Right now, model initialization is slightly hard-coded to handle layer
initialization. This PR refactors the model initialization to be fully
generic.
@kylebarron kylebarron changed the title wip: Define models for Views, Basemap wip: Define models for Views Oct 15, 2025
@kylebarron
Copy link
Member Author

The basemap refactor was extracted to #935

@kylebarron kylebarron changed the title wip: Define models for Views feat: Define models for Views Oct 16, 2025
@github-actions github-actions bot added the feat label Oct 16, 2025
Comment on lines -20 to -22
async loadSubModels() {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unused.

@kylebarron kylebarron changed the title feat: Define models for Views feat: Support globe view Oct 17, 2025
@kylebarron kylebarron marked this pull request as ready for review October 17, 2025 00:03
@kylebarron kylebarron requested review from Copilot and vgeorge October 17, 2025 00:03
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for globe view rendering in lonboard by introducing a Views abstraction layer that maps to deck.gl's view system. The implementation allows users to specify different view types (Globe, Map, Orbit, etc.) and automatically configures the underlying rendering pipeline appropriately.

Key changes:

  • Created View class hierarchy (BaseView, GlobeView, MapView, etc.) to represent different deck.gl views
  • Added views parameter to Map class for specifying view instances
  • Updated default basemap behavior to use MaplibreBasemap() instead of None
  • Integrated view type detection to configure Maplibre projection mode and canvas background

Reviewed Changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lonboard/view.py Defines new View class hierarchy with FirstPersonView, GlobeView, MapView, OrbitView, and OrthographicView
lonboard/_map.py Adds views parameter and updates basemap default initialization
lonboard/types/map.py Updates MapKwargs TypedDict to include views parameter
lonboard/traits.py Updates ViewStateTrait validation signature to include Map type hint
src/model/view.ts Implements TypeScript view models that build deck.gl view instances
src/model/base.ts Removes unused loadSubModels method
src/model/extension.ts Removes call to removed loadSubModels method
src/index.tsx Integrates view state management and globe-specific styling
src/renderers/overlay.tsx Passes projection="globe" to Maplibre when using GlobeView
src/renderers/types.ts Updates MapRendererProps type to include views
src/util.ts Adds isGlobeView helper function
tests/test_map.py Adds test for default basemap behavior
eslint.config.js Reorganizes import statements alphabetically

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

kylebarron added a commit that referenced this pull request Oct 20, 2025
…ap` if no value of `basemap` was passed. (#963)

Extracted from #908 so
that `main` is clear
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Maplibre GlobeView Add support for OrthographicView

2 participants