borderless / ui /globe.py
spagestic's picture
Restructure the UI with Form and Chat tabs while keeping the globe always visible.
1fc9fb8
Raw
History Blame Contribute Delete
4.98 kB
# ui/globe.py
import json
from pathlib import Path
import gradio as gr
ASSETS_DIR = Path(__file__).resolve().parent.parent / "assets"
def _read_asset(name: str) -> str:
return (ASSETS_DIR / name).read_text(encoding="utf-8")
def globe_head_html() -> str:
"""MapLibre assets for the page <head> (used by app launch)."""
return _read_asset("globe_head.html")
def _map_data_attrs(
*,
style: str = "https://tiles.openfreemap.org/styles/liberty",
center: tuple[float, float] = (0.0, 20.0),
zoom: float = 1.5,
min_zoom: float = 0.0,
max_zoom: float = 22.0,
bearing: float = 0.0,
pitch: float = 0.0,
min_pitch: float = 0.0,
max_pitch: float = 85.0,
projection: str = "globe",
attribution_control: bool = True,
scroll_zoom: bool = True,
drag_rotate: bool = True,
drag_pan: bool = True,
keyboard: bool = True,
double_click_zoom: bool = True,
touch_zoom_rotate: bool = True,
interactive: bool = True,
show_geolocate_control: bool = False,
use_current_location: bool = False,
geolocate_zoom: float = 10.0,
track_user_location: bool = False,
show_user_location: bool = True,
show_accuracy_circle: bool = True,
) -> str:
attrs = {
"data-style": style,
"data-center": json.dumps(list(center)),
"data-zoom": zoom,
"data-min-zoom": min_zoom,
"data-max-zoom": max_zoom,
"data-bearing": bearing,
"data-pitch": pitch,
"data-min-pitch": min_pitch,
"data-max-pitch": max_pitch,
"data-projection": projection,
"data-attribution-control": str(attribution_control).lower(),
"data-scroll-zoom": str(scroll_zoom).lower(),
"data-drag-rotate": str(drag_rotate).lower(),
"data-drag-pan": str(drag_pan).lower(),
"data-keyboard": str(keyboard).lower(),
"data-double-click-zoom": str(double_click_zoom).lower(),
"data-touch-zoom-rotate": str(touch_zoom_rotate).lower(),
"data-interactive": str(interactive).lower(),
"data-show-geolocate-control": str(show_geolocate_control).lower(),
"data-use-current-location": str(use_current_location).lower(),
"data-geolocate-zoom": geolocate_zoom,
"data-track-user-location": str(track_user_location).lower(),
"data-show-user-location": str(show_user_location).lower(),
"data-show-accuracy-circle": str(show_accuracy_circle).lower(),
}
return " ".join(f'{key}="{value}"' for key, value in attrs.items())
def render_globe_panel(
*,
height: str = "720px",
style: str = "https://tiles.openfreemap.org/styles/liberty",
center: tuple[float, float] = (0.0, 20.0),
zoom: float = 1.5,
min_zoom: float = 0.0,
max_zoom: float = 22.0,
bearing: float = 0.0,
pitch: float = 0.0,
min_pitch: float = 0.0,
max_pitch: float = 85.0,
projection: str = "globe",
attribution_control: bool = True,
scroll_zoom: bool = True,
drag_rotate: bool = True,
drag_pan: bool = True,
keyboard: bool = True,
double_click_zoom: bool = True,
touch_zoom_rotate: bool = True,
interactive: bool = True,
show_geolocate_control: bool = False,
use_current_location: bool = False,
geolocate_zoom: float = 10.0,
track_user_location: bool = False,
show_user_location: bool = True,
show_accuracy_circle: bool = True,
):
data_attrs = _map_data_attrs(
style=style,
center=center,
zoom=zoom,
min_zoom=min_zoom,
max_zoom=max_zoom,
bearing=bearing,
pitch=pitch,
min_pitch=min_pitch,
max_pitch=max_pitch,
projection=projection,
attribution_control=attribution_control,
scroll_zoom=scroll_zoom,
drag_rotate=drag_rotate,
drag_pan=drag_pan,
keyboard=keyboard,
double_click_zoom=double_click_zoom,
touch_zoom_rotate=touch_zoom_rotate,
interactive=interactive,
show_geolocate_control=show_geolocate_control,
use_current_location=use_current_location,
geolocate_zoom=geolocate_zoom,
track_user_location=track_user_location,
show_user_location=show_user_location,
show_accuracy_circle=show_accuracy_circle,
)
return gr.HTML(
value=(
'<div class="globe-shell is-loading">'
f'<div class="globe-map" {data_attrs}></div>'
'<div class="globe-status globe-loading">Loading the globe...</div>'
"</div>"
),
css_template=_read_asset("globe.css"),
html_template="${value}",
js_on_load=_read_asset("globe.js"),
min_height=height,
show_label=False,
container=False,
padding=False,
scale=1,
elem_classes=["globe-panel"],
)