Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
02d6e13
View model definitions
kylebarron Oct 8, 2025
ab8c55d
Allow none
kylebarron Oct 8, 2025
71b0b4e
Pass in views to Map constructor
kylebarron Oct 8, 2025
4bfd2ba
move html export to separate file
kylebarron Oct 8, 2025
f14cdba
move view_state down after view
kylebarron Oct 8, 2025
c490176
Set up maplibre basemap widet
kylebarron Oct 8, 2025
aaf66a3
Define split renderers
kylebarron Oct 14, 2025
ca7bfd4
Implement split renderers
kylebarron Oct 14, 2025
a043703
alphabetize
kylebarron Oct 14, 2025
fa0940c
Merge branch 'main' into kyle/view-basemap-refactor
kylebarron Oct 14, 2025
879bff0
Merge branch 'main' into kyle/split-renderers2
kylebarron Oct 14, 2025
08ce7f8
Merge branch 'kyle/split-renderers2' into kyle/view-basemap-refactor
kylebarron Oct 14, 2025
18aacb4
Merge branch 'main' into kyle/view-basemap-refactor
kylebarron Oct 14, 2025
e185723
Merge branch 'main' into kyle/view-basemap-refactor
kylebarron Oct 15, 2025
05b1ec2
Merge branch 'main' into kyle/view-basemap-refactor
kylebarron Oct 16, 2025
3571acf
reduce diff
kylebarron Oct 16, 2025
2e59606
Support deck views
kylebarron Oct 16, 2025
6ff3540
Apply linear gradient background
kylebarron Oct 16, 2025
e846164
Add dark background when in globe view
kylebarron Oct 16, 2025
8c88487
pass undefined when no views passed
kylebarron Oct 16, 2025
188164c
Remove multi-view support for now
kylebarron Oct 16, 2025
89d70eb
fix basemap when constructing `Map` without any parameters
kylebarron Oct 16, 2025
582d606
Let `views` be None
kylebarron Oct 16, 2025
9b8ebcc
remove accidental render_mode
kylebarron Oct 16, 2025
d72e7b7
reduce diff
kylebarron Oct 16, 2025
5ff4d12
remove controller
kylebarron Oct 17, 2025
a273191
Merge branch 'main' into kyle/view-basemap-refactor
kylebarron Oct 22, 2025
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
Prev Previous commit
Next Next commit
move html export to separate file
  • Loading branch information
kylebarron committed Oct 8, 2025
commit 4bfd2ba95e134cca51d97eabe5cb73e0663a6956
84 changes: 84 additions & 0 deletions lonboard/_html_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from __future__ import annotations

from io import StringIO
from typing import IO, TYPE_CHECKING, TextIO, overload

from ipywidgets.embed import dependency_state, embed_minimal_html

if TYPE_CHECKING:
from pathlib import Path

from lonboard import Map


# HTML template to override exported map as 100% height
_HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{title}</title>
</head>
<style>
html {{ height: 100%; }}
body {{ height: 100%; overflow: hidden;}}
.widget-subarea {{ height: 100%; }}
.jupyter-widgets-disconnected {{ height: 100%; }}
</style>
<body>
{snippet}
</body>
</html>
"""


@overload
def map_to_html(
m: Map,
*,
filename: None = None,
title: str | None = None,
) -> str: ...


@overload
def map_to_html(
m: Map,
*,
filename: str | Path | TextIO | IO[str],
title: str | None = None,
) -> None: ...


def map_to_html(
m: Map,
*,
filename: str | Path | TextIO | IO[str] | None = None,
title: str | None = None,
) -> str | None:
def inner(fp: str | Path | TextIO | IO[str]) -> None:
original_height = m.height
try:
with m.hold_trait_notifications():
m.height = "100%"
embed_minimal_html(
fp,
views=[m],
title=title or "Lonboard export",
template=_HTML_TEMPLATE,
drop_defaults=False,
# Necessary to pass the state of _this_ specific map. Otherwise, the
# state of all known widgets will be included, ballooning the file size.
state=dependency_state((m), drop_defaults=False),
)
finally:
# If the map had a height before the HTML was generated, reset it.
m.height = original_height

if filename is None:
with StringIO() as sio:
inner(sio)
return sio.getvalue()

else:
inner(filename)
return None
51 changes: 2 additions & 49 deletions lonboard/_map.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from __future__ import annotations

from io import StringIO
from pathlib import Path
from typing import IO, TYPE_CHECKING, Any, TextIO, overload

import ipywidgets
import traitlets
import traitlets as t
from ipywidgets import CallbackDispatcher
from ipywidgets.embed import dependency_state, embed_minimal_html

from lonboard._base import BaseAnyWidget
from lonboard._html_export import map_to_html
from lonboard._layer import BaseLayer
from lonboard._viewport import compute_view
from lonboard.basemap import CartoBasemap
Expand Down Expand Up @@ -40,25 +39,6 @@
# bundler yields lonboard/static/{index.js,styles.css}
bundler_output_dir = Path(__file__).parent / "static"

# HTML template to override exported map as 100% height
_HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{title}</title>
</head>
<style>
html {{ height: 100%; }}
body {{ height: 100%; overflow: hidden;}}
.widget-subarea {{ height: 100%; }}
.jupyter-widgets-disconnected {{ height: 100%; }}
</style>
<body>
{snippet}
</body>
</html>
"""


class Map(BaseAnyWidget):
"""The top-level class used to display a map in a Jupyter Widget.
Expand Down Expand Up @@ -575,34 +555,7 @@ def to_html(
If `filename` is not passed, returns the HTML content as a `str`.

"""

def inner(fp: str | Path | TextIO | IO[str]) -> None:
original_height = self.height
try:
with self.hold_trait_notifications():
self.height = "100%"
embed_minimal_html(
fp,
views=[self],
title=title or "Lonboard export",
template=_HTML_TEMPLATE,
drop_defaults=False,
# Necessary to pass the state of _this_ specific map. Otherwise, the
# state of all known widgets will be included, ballooning the file size.
state=dependency_state((self), drop_defaults=False),
)
finally:
# If the map had a height before the HTML was generated, reset it.
self.height = original_height

if filename is None:
with StringIO() as sio:
inner(sio)
return sio.getvalue()

else:
inner(filename)
return None
return map_to_html(self, filename=filename, title=title)

def as_html(self) -> HTML:
"""Render the current map as a static HTML file in IPython.
Expand Down