lunar-toolkit 0.1.0.dev14__tar.gz → 0.1.0.dev15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/PKG-INFO +3 -1
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/README.md +2 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/serve.py +2 -2
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/index.html +258 -233
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/PKG-INFO +3 -1
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/pyproject.toml +1 -1
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_static.py +1 -1
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/LICENSE +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/__init__.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/asp.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/__init__.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/_jobs.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/_status.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/_utils.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/app.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/build_db.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/download.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/kaguya.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/ode_search.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/pairs.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/process.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/query.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/reference.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/search.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/sfs.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/sfs_report.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/shadowcam.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/stereo.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/cli/workspace.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/config.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/constants.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/csm.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/downloader.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/geometry.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/isis.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/kaguya/__init__.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/kaguya/mi.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/kaguya/tc.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/lroc/__init__.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/lroc/cumindex.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/lroc/nac.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/observation.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/ode.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/provenance.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/reference.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/selection.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/sfs.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/sfs_products.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/sfs_report.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/shadowcam/__init__.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/shadowcam/sc.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_dem_global.tif +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_dem_north.tif +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_dem_south.tif +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_shade_global.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_shade_north.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/lola_shade_south.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/manifest.json +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_global.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_north.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_south.jpg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/stereo.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/stereo_dem.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/tools.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/workspace.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/SOURCES.txt +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/dependency_links.txt +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/entry_points.txt +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/requires.txt +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/top_level.txt +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/setup.cfg +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_aoi.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_app.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_build.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_config.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_csm.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_download.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_footprints.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_integration.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_kaguya.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_kaguya_mi.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_lbl.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_ode.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_reference.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_selection.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_sfs.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_sfs_products.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_sfs_report.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_shadowcam.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_stereo.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_tool_env.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_tools.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_update.py +0 -0
- {lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/tests/test_workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lunar-toolkit
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev15
|
|
4
4
|
Summary: Find, download and process lunar orbital imagery (LROC, ShadowCam, Kaguya TC) and build stereo and shape-from-shading DEMs with ISIS + ASP
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
Keywords: moon,lroc,shadowcam,kaguya,isis,ames-stereo-pipeline,shape-from-shading,dem
|
|
@@ -55,6 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
|
|
56
56
|
# Lunar Toolkit
|
|
57
57
|
|
|
58
|
+

|
|
59
|
+
|
|
58
60
|
Lunar Toolkit finds, downloads and processes lunar orbital imagery and turns it into DEMs.
|
|
59
61
|
|
|
60
62
|
It builds a searchable index of LROC images whose footprint search also works near the poles, finds ShadowCam, LROC and Kaguya products through the PDS Orbital Data Explorer, imports images into [ISIS](https://isis.astrogeology.usgs.gov/), and builds stereo and shape-from-shading (SfS) DEMs with the [Ames Stereo Pipeline](https://stereopipeline.readthedocs.io/) through configurable, reproducible pipelines. A desktop app browses the index, ODE, footprints and full-resolution images.
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
# Lunar Toolkit
|
|
8
8
|
|
|
9
|
+

|
|
10
|
+
|
|
9
11
|
Lunar Toolkit finds, downloads and processes lunar orbital imagery and turns it into DEMs.
|
|
10
12
|
|
|
11
13
|
It builds a searchable index of LROC images whose footprint search also works near the poles, finds ShadowCam, LROC and Kaguya products through the PDS Orbital Data Explorer, imports images into [ISIS](https://isis.astrogeology.usgs.gov/), and builds stereo and shape-from-shading (SfS) DEMs with the [Ames Stereo Pipeline](https://stereopipeline.readthedocs.io/) through configurable, reproducible pipelines. A desktop app browses the index, ODE, footprints and full-resolution images.
|
|
@@ -90,7 +90,7 @@ def add_server_args(p: argparse.ArgumentParser, host: str, port: int) -> None:
|
|
|
90
90
|
"--runs-dir",
|
|
91
91
|
default=None,
|
|
92
92
|
metavar="DIR",
|
|
93
|
-
help="SfS runs listed in the Settings
|
|
93
|
+
help="SfS runs listed in the Settings panel (default: LUNAR_RUNS_DIR).",
|
|
94
94
|
)
|
|
95
95
|
p.add_argument(
|
|
96
96
|
"--admin-token",
|
|
@@ -116,7 +116,7 @@ Examples
|
|
|
116
116
|
lunar serve --host 0.0.0.0 # share on the network; remote clients are read-only
|
|
117
117
|
lunar serve --host 0.0.0.0 --admin-token auto # ... and print a token for remote admin
|
|
118
118
|
|
|
119
|
-
Admin (the Settings
|
|
119
|
+
Admin (the Settings panel: build indexes, download, see local paths) is allowed from this
|
|
120
120
|
machine (loopback) and for requests carrying --admin-token; everyone else can browse,
|
|
121
121
|
search and view. Use `lunar app` for a desktop window.
|
|
122
122
|
""",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Lunar Toolkit Browser</title>
|
|
7
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dockview@8.4.0/dist/styles/dockview.css">
|
|
7
8
|
<style>
|
|
8
9
|
/* Classic desktop look: flat grey panels, white sunken fields, one-pixel edges, square
|
|
9
10
|
corners, a navy accent. */
|
|
@@ -60,16 +61,6 @@
|
|
|
60
61
|
.main { display: grid; grid-template-columns: 340px minmax(0, 1fr); min-height: 0; }
|
|
61
62
|
|
|
62
63
|
.controls { display: flex; flex-direction: column; min-height: 0; padding: 6px 3px 6px 6px; }
|
|
63
|
-
.tabbar { display: flex; position: relative; z-index: 1; }
|
|
64
|
-
.tabbar button {
|
|
65
|
-
font: inherit; color: var(--muted); padding: 3px 12px; margin-right: -1px; min-width: 0; min-height: 0;
|
|
66
|
-
background: var(--chrome); border: 1px solid var(--border); border-bottom: none; cursor: default;
|
|
67
|
-
}
|
|
68
|
-
.tabbar button:hover { background: var(--hover); }
|
|
69
|
-
.tabbar button[aria-selected="true"] {
|
|
70
|
-
color: var(--text); background: var(--window); margin-bottom: -1px; padding-bottom: 4px; position: relative; z-index: 1;
|
|
71
|
-
}
|
|
72
|
-
.tabbar button:focus-visible { outline: 1px dotted var(--text); outline-offset: -4px; }
|
|
73
64
|
.panel {
|
|
74
65
|
flex: 1; min-height: 0; overflow: auto; border: 1px solid var(--border);
|
|
75
66
|
background: var(--window); padding: 2px 8px 8px;
|
|
@@ -120,29 +111,55 @@
|
|
|
120
111
|
button:disabled { color: var(--disabled); }
|
|
121
112
|
button.tool { min-width: 0; padding: 0 8px; min-height: 20px; font-size: 12px; }
|
|
122
113
|
|
|
123
|
-
/* Workspace:
|
|
124
|
-
.workspace {
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
/* Workspace: dockview panels (Footprints, Image, Settings over Results | Details by default) */
|
|
115
|
+
.workspace { min-height: 0; min-width: 0; padding: 6px 6px 4px 3px; }
|
|
116
|
+
.dock { height: 100%; }
|
|
117
|
+
.dockpanel { display: flex; flex-direction: column; height: 100%; min-height: 0; min-width: 0; background: var(--base); }
|
|
118
|
+
.dockview-theme-light {
|
|
119
|
+
--dv-group-view-background-color: var(--base);
|
|
120
|
+
--dv-tabs-and-actions-container-background-color: transparent;
|
|
121
|
+
--dv-tabs-and-actions-container-height: 23px;
|
|
122
|
+
--dv-tabs-and-actions-container-font-size: 13px;
|
|
123
|
+
--dv-activegroup-visiblepanel-tab-background-color: var(--window);
|
|
124
|
+
--dv-inactivegroup-visiblepanel-tab-background-color: var(--window);
|
|
125
|
+
--dv-activegroup-hiddenpanel-tab-background-color: var(--chrome);
|
|
126
|
+
--dv-inactivegroup-hiddenpanel-tab-background-color: var(--chrome);
|
|
127
|
+
--dv-activegroup-visiblepanel-tab-color: var(--text);
|
|
128
|
+
--dv-inactivegroup-visiblepanel-tab-color: var(--text);
|
|
129
|
+
--dv-activegroup-hiddenpanel-tab-color: var(--muted);
|
|
130
|
+
--dv-inactivegroup-hiddenpanel-tab-color: var(--muted);
|
|
131
|
+
--dv-tab-divider-color: transparent;
|
|
132
|
+
--dv-separator-border: transparent;
|
|
133
|
+
--dv-sash-color: transparent;
|
|
134
|
+
--dv-active-sash-color: color-mix(in srgb, var(--accent) 30%, transparent);
|
|
135
|
+
--dv-active-sash-transition-delay: 0s;
|
|
136
|
+
--dv-drag-over-background-color: color-mix(in srgb, var(--accent) 22%, transparent);
|
|
137
|
+
--dv-drag-over-border-color: var(--accent);
|
|
138
|
+
--dv-tabs-container-scrollbar-color: var(--border);
|
|
139
|
+
color: var(--text);
|
|
140
|
+
}
|
|
141
|
+
.dock .dv-tabs-and-actions-container { background: var(--chrome); box-shadow: inset 0 -1px 0 var(--border); }
|
|
142
|
+
.dock .dv-tab {
|
|
143
|
+
padding: 0 12px; margin-right: -1px; border: 1px solid var(--border); cursor: default;
|
|
127
144
|
}
|
|
128
|
-
.
|
|
129
|
-
.
|
|
145
|
+
.dock .dv-tab.dv-inactive-tab:hover { background: var(--hover); }
|
|
146
|
+
.dock .dv-tab.dv-active-tab { border-bottom-color: var(--window); position: relative; z-index: 1; }
|
|
147
|
+
.dock .dv-tab .dv-default-tab { padding: 0; }
|
|
148
|
+
.dock .dv-tab .dv-default-tab .dv-default-tab-action { display: none; }
|
|
149
|
+
.dock .dv-tab:focus-visible::after { outline: 1px dotted var(--text) !important; outline-offset: -4px; }
|
|
150
|
+
.dock .dv-content-container { border: 1px solid var(--border); border-top: none; }
|
|
130
151
|
.panehead {
|
|
131
|
-
display: flex; align-items: center; gap: 6px; padding: 1px 2px 1px 6px; min-height: 23px;
|
|
152
|
+
display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; padding: 1px 2px 1px 6px; min-height: 23px;
|
|
132
153
|
background: var(--header); border-bottom: 1px solid var(--sep);
|
|
133
154
|
}
|
|
134
|
-
.panehead .title { font-weight: bold; }
|
|
135
155
|
.panehead .info { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
136
|
-
.panehead .right { margin-left: auto; display: flex; gap: 3px; }
|
|
156
|
+
.panehead .right { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 3px; }
|
|
157
|
+
#view-results .panehead:has(> #nav:empty):has(> #results-loading[hidden]) { display: none; }
|
|
137
158
|
.panebody { flex: 1; min-height: 0; overflow: auto; position: relative; }
|
|
138
159
|
.panebody:empty::before, .mapbox:empty::before {
|
|
139
160
|
content: attr(data-empty); position: absolute; inset: 0; display: flex; align-items: center;
|
|
140
161
|
justify-content: center; color: var(--disabled); padding: 1em; text-align: center;
|
|
141
162
|
}
|
|
142
|
-
.splitter { position: relative; touch-action: none; }
|
|
143
|
-
.splitter.rows { cursor: row-resize; }
|
|
144
|
-
.splitter.cols { cursor: col-resize; }
|
|
145
|
-
.splitter:hover { background: color-mix(in srgb, var(--accent) 30%, transparent); }
|
|
146
163
|
|
|
147
164
|
/* Tables */
|
|
148
165
|
table { border-collapse: separate; border-spacing: 0; }
|
|
@@ -220,11 +237,8 @@
|
|
|
220
237
|
.map text.gl { fill: var(--muted); font-size: 10.5px; }
|
|
221
238
|
.map text.axis { font-size: 11.5px; }
|
|
222
239
|
|
|
223
|
-
/*
|
|
224
|
-
.
|
|
225
|
-
.viewwrap > .pane { flex: 1; }
|
|
226
|
-
.viewbody { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
227
|
-
.viewbody > .mapbox { flex: 1; min-height: 0; height: auto; }
|
|
240
|
+
/* The image view is a framed canvas under a tool bar */
|
|
241
|
+
.dockpanel > .mapbox { flex: 1; min-height: 0; height: auto; }
|
|
228
242
|
.toolbar {
|
|
229
243
|
display: flex; flex-wrap: wrap; align-items: center; gap: 3px; padding: 2px 4px;
|
|
230
244
|
background: var(--window); border-bottom: 1px solid var(--sep);
|
|
@@ -276,9 +290,9 @@
|
|
|
276
290
|
.statusbar .cell { border-left: 1px solid var(--sep); }
|
|
277
291
|
.statusbar #cursor { min-width: 22em; font-family: "DejaVu Sans Mono", Consolas, "Liberation Mono", monospace; font-size: 12px; }
|
|
278
292
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
293
|
+
.statusbar .layout { display: flex; gap: 3px; padding: 0 0 0 4px; }
|
|
294
|
+
|
|
295
|
+
/* Settings view: group boxes */
|
|
282
296
|
.settings {
|
|
283
297
|
flex: 1; min-height: 0; overflow: auto; padding: 0 10px 10px; background: var(--window);
|
|
284
298
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr)); gap: 0 16px; align-content: start;
|
|
@@ -329,16 +343,11 @@
|
|
|
329
343
|
.main { grid-template-columns: minmax(0, 1fr); }
|
|
330
344
|
.controls { padding: 6px; }
|
|
331
345
|
.panel { overflow: visible; }
|
|
332
|
-
.workspace {
|
|
333
|
-
.workspace > .viewwrap { height: 420px; flex: none; }
|
|
334
|
-
.workspace.settings-on > .viewwrap { height: auto; }
|
|
335
|
-
.settings { overflow: visible; }
|
|
336
|
-
.lower { display: flex; flex-direction: column; gap: 6px; }
|
|
337
|
-
.lower > .pane { height: 320px; flex: none; }
|
|
338
|
-
.splitter { display: none; }
|
|
346
|
+
.workspace { height: 1110px; padding: 0 6px 6px; }
|
|
339
347
|
.statusbar { position: sticky; bottom: 0; flex-wrap: wrap; }
|
|
340
348
|
.statusbar .status { flex-basis: 100%; white-space: normal; }
|
|
341
349
|
.statusbar #cursor { min-width: 0; }
|
|
350
|
+
#layout-side { display: none; }
|
|
342
351
|
}
|
|
343
352
|
</style>
|
|
344
353
|
</head>
|
|
@@ -417,171 +426,160 @@
|
|
|
417
426
|
</div>
|
|
418
427
|
</aside>
|
|
419
428
|
|
|
420
|
-
<main class="workspace" id="workspace">
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
429
|
+
<main class="workspace" id="workspace"><div class="dock" id="dock"></div></main>
|
|
430
|
+
<div id="dock-park" hidden>
|
|
431
|
+
<div class="dockpanel" id="view-map">
|
|
432
|
+
<div class="mapbox" id="map" data-empty="No footprints. Run a search or look up product IDs."></div>
|
|
433
|
+
</div>
|
|
434
|
+
<div class="dockpanel" id="view-image">
|
|
435
|
+
<div class="panehead">
|
|
436
|
+
<span class="loading" id="view-loading" hidden></span>
|
|
437
|
+
<span class="info" id="view-info">No image</span>
|
|
426
438
|
</div>
|
|
427
|
-
<
|
|
428
|
-
<
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
<
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
439
|
+
<div class="toolbar" role="toolbar" aria-label="Image view">
|
|
440
|
+
<select id="view-source" aria-label="Image source" title="Image source" disabled><option value="">(no image)</option></select>
|
|
441
|
+
<button class="tool" id="view-open" type="button" title="Open a local GeoTIFF / COG (or PNG / JPEG)">Open file...</button>
|
|
442
|
+
<input id="view-file" type="file" accept=".tif,.tiff,image/tiff,.png,.jpg,.jpeg" hidden>
|
|
443
|
+
<span class="sep"></span>
|
|
444
|
+
<button class="tool" id="view-zoom-out" type="button" title="Zoom out (-)">-</button>
|
|
445
|
+
<button class="tool" id="view-zoom-in" type="button" title="Zoom in (+)">+</button>
|
|
446
|
+
<button class="tool" id="view-1to1" type="button" title="Full resolution: one image pixel per screen pixel (0)">1:1</button>
|
|
447
|
+
<button class="tool" id="view-fit" type="button" title="Fit the whole image (F)">Fit</button>
|
|
448
|
+
<button class="tool" id="view-fit-width" type="button" title="Fit the image width (W)">Fit width</button>
|
|
449
|
+
<span class="sep"></span>
|
|
450
|
+
<span class="lbl">Rotate</span>
|
|
451
|
+
<button class="tool" id="view-rot-left" type="button" title="Rotate 90 deg counterclockwise (Shift+R; [ ] rotate 5 deg)">-90</button>
|
|
452
|
+
<button class="tool" id="view-rot-right" type="button" title="Rotate 90 deg clockwise (R)">+90</button>
|
|
453
|
+
<input id="view-rot" type="number" step="any" value="0" aria-label="Rotation angle" title="Rotation in degrees, clockwise">
|
|
454
|
+
<span class="sep"></span>
|
|
455
|
+
<label class="lbl" for="view-min">Min</label><input id="view-min" type="number" step="any" disabled>
|
|
456
|
+
<label class="lbl" for="view-max">Max</label><input id="view-max" type="number" step="any" disabled>
|
|
457
|
+
<label class="lbl" for="view-gamma">Gamma</label><input id="view-gamma" type="number" step="0.1" min="0.1" max="10" value="1" disabled>
|
|
458
|
+
<button class="tool" id="view-auto" type="button" title="Stretch the 2nd - 98th percentile of the overview" disabled>Auto</button>
|
|
459
|
+
</div>
|
|
460
|
+
<div class="viewframe" id="view-frame">
|
|
461
|
+
<canvas id="view-canvas" tabindex="0" aria-label="Image (wheel zoom, drag pan, + - 0 F W R [ ] keys)"></canvas>
|
|
462
|
+
<div class="viewmsg" id="view-msg"><span>Select a product with a browse image (LROC NAC / WAC pyramid, ShadowCam COG,
|
|
463
|
+
Kaguya JPEG), open a local GeoTIFF, or start <code>lunar serve --images DIR</code>.</span></div>
|
|
464
|
+
</div>
|
|
465
|
+
</div>
|
|
466
|
+
<div class="dockpanel" id="view-settings">
|
|
467
|
+
<div class="panehead">
|
|
468
|
+
<span class="info" id="set-info">Needs lunar serve or lunar app</span>
|
|
469
|
+
<span class="right"><button class="tool" id="set-refresh" type="button" title="Read the status again (sizes, tools)">Refresh</button></span>
|
|
470
|
+
</div>
|
|
471
|
+
<div class="settings" id="settings">
|
|
472
|
+
<p class="note wide" id="set-note" hidden></p>
|
|
473
|
+
|
|
474
|
+
<fieldset class="wide">
|
|
475
|
+
<legend>Data and indexes</legend>
|
|
476
|
+
<div class="path" id="set-data-dir"></div>
|
|
477
|
+
<div class="tablebox" id="set-indexes"></div>
|
|
478
|
+
<div class="row">
|
|
479
|
+
<label class="lbl" for="set-release">Release</label>
|
|
480
|
+
<input id="set-release" type="text" class="mono" style="max-width: 24em" placeholder="newest (e.g. LROLRC_0066C)" spellcheck="false" data-admin>
|
|
481
|
+
<span class="checks"><label><input id="set-volume-only" type="checkbox" data-admin> Volume index only</label></span>
|
|
436
482
|
</div>
|
|
437
|
-
<
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
<
|
|
453
|
-
<
|
|
454
|
-
<label class="lbl" for="view-max">Max</label><input id="view-max" type="number" step="any" disabled>
|
|
455
|
-
<label class="lbl" for="view-gamma">Gamma</label><input id="view-gamma" type="number" step="0.1" min="0.1" max="10" value="1" disabled>
|
|
456
|
-
<button class="tool" id="view-auto" type="button" title="Stretch the 2nd - 98th percentile of the overview" disabled>Auto</button>
|
|
483
|
+
<p class="hint">Build downloads the cumulative CUMINDEX.TAB (EDR about 3.8 GB) and writes the Parquet with
|
|
484
|
+
DuckDB; "Volume index only" uses one release's INDEX.TAB (about 20 k rows). Update appends the volumes
|
|
485
|
+
released since the build. Same as <code>lunar build-db</code>.</p>
|
|
486
|
+
</fieldset>
|
|
487
|
+
|
|
488
|
+
<fieldset class="wide">
|
|
489
|
+
<legend>Jobs</legend>
|
|
490
|
+
<div class="tablebox" id="set-jobs"></div>
|
|
491
|
+
<p class="hint" id="set-jobs-empty">No jobs yet. Builds and downloads run here in the background (two at a time)
|
|
492
|
+
and resume from their .part files when started again.</p>
|
|
493
|
+
</fieldset>
|
|
494
|
+
|
|
495
|
+
<fieldset>
|
|
496
|
+
<legend>Reference data</legend>
|
|
497
|
+
<div class="row">
|
|
498
|
+
<label class="lbl" for="set-region">Region</label>
|
|
499
|
+
<select id="set-region" data-admin></select>
|
|
457
500
|
</div>
|
|
458
|
-
<div class="
|
|
459
|
-
<
|
|
460
|
-
<
|
|
461
|
-
|
|
501
|
+
<div class="row">
|
|
502
|
+
<span class="lbl">PGDA LOLA 5 m</span>
|
|
503
|
+
<span class="checks" id="set-pgda-kinds"></span>
|
|
504
|
+
<span class="push"><button id="set-pgda-btn" type="button" data-admin>Download</button></span>
|
|
462
505
|
</div>
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
<span class="
|
|
468
|
-
|
|
506
|
+
<div class="row">
|
|
507
|
+
<label class="lbl" for="set-sdem-pat">SfS DEM members</label>
|
|
508
|
+
<input id="set-sdem-pat" type="text" class="mono" value="GLDELEV" spellcheck="false" data-admin
|
|
509
|
+
title="Product codes / substrings or globs, e.g. GLDELEV GLDSIGM README">
|
|
510
|
+
<span class="push">
|
|
511
|
+
<button id="set-sdem-list" type="button" data-admin title="Read the Zenodo zip directory (HTTP Range)">List members</button>
|
|
512
|
+
<button id="set-sdem-btn" type="button" data-admin>Extract</button>
|
|
513
|
+
</span>
|
|
469
514
|
</div>
|
|
470
|
-
<
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
<
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
</
|
|
486
|
-
|
|
487
|
-
<
|
|
488
|
-
<legend>Jobs</legend>
|
|
489
|
-
<div class="tablebox" id="set-jobs"></div>
|
|
490
|
-
<p class="hint" id="set-jobs-empty">No jobs yet. Builds and downloads run here in the background (two at a time)
|
|
491
|
-
and resume from their .part files when started again.</p>
|
|
492
|
-
</fieldset>
|
|
493
|
-
|
|
494
|
-
<fieldset>
|
|
495
|
-
<legend>Reference data</legend>
|
|
496
|
-
<div class="row">
|
|
497
|
-
<label class="lbl" for="set-region">Region</label>
|
|
498
|
-
<select id="set-region" data-admin></select>
|
|
499
|
-
</div>
|
|
500
|
-
<div class="row">
|
|
501
|
-
<span class="lbl">PGDA LOLA 5 m</span>
|
|
502
|
-
<span class="checks" id="set-pgda-kinds"></span>
|
|
503
|
-
<span class="push"><button id="set-pgda-btn" type="button" data-admin>Download</button></span>
|
|
504
|
-
</div>
|
|
505
|
-
<div class="row">
|
|
506
|
-
<label class="lbl" for="set-sdem-pat">SfS DEM members</label>
|
|
507
|
-
<input id="set-sdem-pat" type="text" class="mono" value="GLDELEV" spellcheck="false" data-admin
|
|
508
|
-
title="Product codes / substrings or globs, e.g. GLDELEV GLDSIGM README">
|
|
509
|
-
<span class="push">
|
|
510
|
-
<button id="set-sdem-list" type="button" data-admin title="Read the Zenodo zip directory (HTTP Range)">List members</button>
|
|
511
|
-
<button id="set-sdem-btn" type="button" data-admin>Extract</button>
|
|
512
|
-
</span>
|
|
513
|
-
</div>
|
|
514
|
-
<select id="set-sdem-members" multiple aria-label="Zip members" hidden data-admin></select>
|
|
515
|
-
<div class="tablebox" id="set-reference"></div>
|
|
516
|
-
<p class="hint" id="set-ref-dir"></p>
|
|
517
|
-
</fieldset>
|
|
518
|
-
|
|
519
|
-
<fieldset>
|
|
520
|
-
<legend>Downloads</legend>
|
|
521
|
-
<textarea id="set-dl-ids" class="ids" rows="3" spellcheck="false" aria-label="Product IDs to download"
|
|
522
|
-
placeholder="M1096757719LE M1096757719RE ..." data-admin></textarea>
|
|
523
|
-
<div class="row">
|
|
524
|
-
<label class="lbl" for="set-dl-product">Product</label>
|
|
525
|
-
<select id="set-dl-product" style="flex: 0 0 auto; width: 7em" data-admin>
|
|
526
|
-
<option value="edr">EDR</option>
|
|
527
|
-
<option value="cdr">CDR</option>
|
|
528
|
-
</select>
|
|
529
|
-
<label class="lbl" for="set-dl-dest">To</label>
|
|
530
|
-
<input id="set-dl-dest" type="text" class="mono" spellcheck="false" data-admin>
|
|
531
|
-
<span class="push"><button id="set-dl-btn" type="button" data-admin>Download</button></span>
|
|
532
|
-
</div>
|
|
533
|
-
<div class="tablebox" id="set-downloads"></div>
|
|
534
|
-
<div class="path" id="set-cache-dir" style="margin-top: 6px"></div>
|
|
535
|
-
<div class="tablebox" id="set-cache"></div>
|
|
536
|
-
</fieldset>
|
|
537
|
-
|
|
538
|
-
<fieldset>
|
|
539
|
-
<legend>Environment</legend>
|
|
540
|
-
<div class="tablebox" id="set-env" style="max-height: none"></div>
|
|
541
|
-
</fieldset>
|
|
542
|
-
|
|
543
|
-
<fieldset>
|
|
544
|
-
<legend>Runs</legend>
|
|
545
|
-
<div class="path" id="set-runs-dir"></div>
|
|
546
|
-
<div class="tablebox" id="set-runs"></div>
|
|
547
|
-
</fieldset>
|
|
515
|
+
<select id="set-sdem-members" multiple aria-label="Zip members" hidden data-admin></select>
|
|
516
|
+
<div class="tablebox" id="set-reference"></div>
|
|
517
|
+
<p class="hint" id="set-ref-dir"></p>
|
|
518
|
+
</fieldset>
|
|
519
|
+
|
|
520
|
+
<fieldset>
|
|
521
|
+
<legend>Downloads</legend>
|
|
522
|
+
<textarea id="set-dl-ids" class="ids" rows="3" spellcheck="false" aria-label="Product IDs to download"
|
|
523
|
+
placeholder="M1096757719LE M1096757719RE ..." data-admin></textarea>
|
|
524
|
+
<div class="row">
|
|
525
|
+
<label class="lbl" for="set-dl-product">Product</label>
|
|
526
|
+
<select id="set-dl-product" style="flex: 0 0 auto; width: 7em" data-admin>
|
|
527
|
+
<option value="edr">EDR</option>
|
|
528
|
+
<option value="cdr">CDR</option>
|
|
529
|
+
</select>
|
|
530
|
+
<label class="lbl" for="set-dl-dest">To</label>
|
|
531
|
+
<input id="set-dl-dest" type="text" class="mono" spellcheck="false" data-admin>
|
|
532
|
+
<span class="push"><button id="set-dl-btn" type="button" data-admin>Download</button></span>
|
|
548
533
|
</div>
|
|
549
|
-
|
|
550
|
-
|
|
534
|
+
<div class="tablebox" id="set-downloads"></div>
|
|
535
|
+
<div class="path" id="set-cache-dir" style="margin-top: 6px"></div>
|
|
536
|
+
<div class="tablebox" id="set-cache"></div>
|
|
537
|
+
</fieldset>
|
|
538
|
+
|
|
539
|
+
<fieldset>
|
|
540
|
+
<legend>Environment</legend>
|
|
541
|
+
<div class="tablebox" id="set-env" style="max-height: none"></div>
|
|
542
|
+
</fieldset>
|
|
543
|
+
|
|
544
|
+
<fieldset>
|
|
545
|
+
<legend>Runs</legend>
|
|
546
|
+
<div class="path" id="set-runs-dir"></div>
|
|
547
|
+
<div class="tablebox" id="set-runs"></div>
|
|
548
|
+
</fieldset>
|
|
549
|
+
</div>
|
|
551
550
|
</div>
|
|
552
|
-
<div class="
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
<
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
<span class="right" id="nav"></span>
|
|
559
|
-
</div>
|
|
560
|
-
<div class="panebody" id="results" data-empty="No results"></div>
|
|
561
|
-
</section>
|
|
562
|
-
<div class="splitter cols" id="split-cols" role="separator" aria-orientation="vertical" title="Drag to resize"></div>
|
|
563
|
-
<section class="pane">
|
|
564
|
-
<div class="panehead">
|
|
565
|
-
<span class="title">Details</span>
|
|
566
|
-
<span class="right"><button class="tool" id="detail-clear" type="button">Clear</button></span>
|
|
567
|
-
</div>
|
|
568
|
-
<div class="panebody" id="detail" data-empty="Click a row or footprint"></div>
|
|
569
|
-
</section>
|
|
551
|
+
<div class="dockpanel" id="view-results">
|
|
552
|
+
<div class="panehead">
|
|
553
|
+
<span class="loading" id="results-loading" hidden>Loading...</span>
|
|
554
|
+
<span class="right" id="nav"></span>
|
|
555
|
+
</div>
|
|
556
|
+
<div class="panebody" id="results" data-empty="No results"></div>
|
|
570
557
|
</div>
|
|
571
|
-
|
|
558
|
+
<div class="dockpanel" id="view-details">
|
|
559
|
+
<div class="panehead">
|
|
560
|
+
<span class="right"><button class="tool" id="detail-clear" type="button">Clear</button></span>
|
|
561
|
+
</div>
|
|
562
|
+
<div class="panebody" id="detail" data-empty="Click a row or footprint"></div>
|
|
563
|
+
</div>
|
|
564
|
+
</div>
|
|
572
565
|
</div>
|
|
573
566
|
|
|
574
567
|
<footer class="statusbar">
|
|
575
568
|
<span class="status busy" id="status">Initializing DuckDB...</span>
|
|
576
569
|
<span class="cell" id="count">0 rows</span>
|
|
577
570
|
<span class="cell" id="view-zoom" hidden></span>
|
|
578
|
-
<span class="cell" id="jobs-summary" title="Open the Settings
|
|
571
|
+
<span class="cell" id="jobs-summary" title="Open the Settings panel" hidden></span>
|
|
579
572
|
<span class="cell" id="cursor"></span>
|
|
573
|
+
<span class="cell layout">
|
|
574
|
+
<button class="tool" id="layout-side" type="button" title="Footprints and Image side by side, Results and Details below">Map | Image</button>
|
|
575
|
+
<button class="tool" id="layout-reset" type="button" title="Restore the default panel layout">Reset layout</button>
|
|
576
|
+
</span>
|
|
580
577
|
</footer>
|
|
581
578
|
</div>
|
|
582
579
|
|
|
583
580
|
<script type="module">
|
|
584
581
|
import * as duckdb from 'https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm@1.29.0/+esm';
|
|
582
|
+
import { createDockview, themeLight } from 'https://cdn.jsdelivr.net/npm/dockview-core@8.4.0/+esm';
|
|
585
583
|
|
|
586
584
|
// Mirrors lunar_toolkit.lroc.nac.METADATA_LABELS (PDS_URL is derived below);
|
|
587
585
|
// tests/test_static.py keeps the two in sync.
|
|
@@ -736,27 +734,6 @@
|
|
|
736
734
|
$('count').textContent = `${n} row${n === 1 ? '' : 's'}`;
|
|
737
735
|
}
|
|
738
736
|
|
|
739
|
-
// Splitters: map | lower pane (rows), results | details (columns)
|
|
740
|
-
function splitter(handle, onmove) {
|
|
741
|
-
handle.addEventListener('pointerdown', (e) => {
|
|
742
|
-
e.preventDefault();
|
|
743
|
-
handle.setPointerCapture(e.pointerId);
|
|
744
|
-
const move = (ev) => onmove(ev);
|
|
745
|
-
const up = () => { handle.removeEventListener('pointermove', move); handle.removeEventListener('pointerup', up); };
|
|
746
|
-
handle.addEventListener('pointermove', move);
|
|
747
|
-
handle.addEventListener('pointerup', up);
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
splitter($('split-rows'), (e) => {
|
|
751
|
-
const r = $('workspace').getBoundingClientRect();
|
|
752
|
-
const h = Math.min(Math.max(e.clientY - r.top - 6, 140), r.height - 120);
|
|
753
|
-
$('workspace').style.setProperty('--map-h', `${h}px`);
|
|
754
|
-
});
|
|
755
|
-
splitter($('split-cols'), (e) => {
|
|
756
|
-
const r = $('lower').getBoundingClientRect();
|
|
757
|
-
const w = Math.min(Math.max(r.right - e.clientX - 3, 200), r.width - 200);
|
|
758
|
-
$('lower').style.setProperty('--det-w', `${w}px`);
|
|
759
|
-
});
|
|
760
737
|
$('detail-clear').addEventListener('click', () => $('detail').replaceChildren());
|
|
761
738
|
|
|
762
739
|
// Geometry: ports of lunar_toolkit.geometry (query_region, aoi_region, aoi_mask), so the
|
|
@@ -1454,7 +1431,6 @@
|
|
|
1454
1431
|
const tools = el('span', { class: 'tools' }, ...Object.entries(MAP_TOOLS).map(([t, [label, title]]) =>
|
|
1455
1432
|
el('button', { class: `tool${t === 'pan' ? ' on' : ''}`, type: 'button', 'data-tool': t, title }, label)));
|
|
1456
1433
|
const bar = el('div', { class: 'panehead' },
|
|
1457
|
-
el('span', { class: 'title' }, 'Footprints'),
|
|
1458
1434
|
el('span', { class: 'info' }, generic ? `${MAP_PROJECTIONS[pj.id]}, R = ${MOON_RADIUS_KM} km`
|
|
1459
1435
|
: hemi ? `Polar stereographic (${hemi === 'S' ? 'south' : 'north'}), R = ${MOON_RADIUS_KM} km`
|
|
1460
1436
|
: 'Lon/lat (equirectangular)', ` | ${items.length} footprint(s) | wheel zoom, drag pan`),
|
|
@@ -2743,7 +2719,6 @@
|
|
|
2743
2719
|
};
|
|
2744
2720
|
const viewCanvas = $('view-canvas');
|
|
2745
2721
|
const frameSize = () => [viewCanvas.clientWidth, viewCanvas.clientHeight];
|
|
2746
|
-
const viewActive = () => ($('view-image').hidden ? 'map' : 'image');
|
|
2747
2722
|
const dpr = () => window.devicePixelRatio || 1;
|
|
2748
2723
|
|
|
2749
2724
|
function viewMessage(text, isError = false) {
|
|
@@ -3613,46 +3588,95 @@
|
|
|
3613
3588
|
}
|
|
3614
3589
|
}
|
|
3615
3590
|
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
$('view-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
if (
|
|
3629
|
-
if (name === 'image') {
|
|
3591
|
+
// Docking workspace (dockview). Panels keep their DOM nodes, parked off-screen while hidden so
|
|
3592
|
+
// lookups by id keep working; the layout is saved per viewer.
|
|
3593
|
+
const PANELS = { map: 'Footprints', image: 'Image', settings: 'Settings', results: 'Results', details: 'Details' };
|
|
3594
|
+
const LAYOUT_KEY = 'lunar-layout-v1';
|
|
3595
|
+
const narrow = matchMedia('(max-width: 800px)');
|
|
3596
|
+
let dock = null, saveTimer = 0;
|
|
3597
|
+
const panelShown = (id) => !!dock?.getPanel(id)?.api.isVisible;
|
|
3598
|
+
|
|
3599
|
+
function panelVisible(id, on) {
|
|
3600
|
+
if (id === 'image') $('view-zoom').hidden = !on;
|
|
3601
|
+
if (!on) return;
|
|
3602
|
+
if (id === 'settings') settingsShown();
|
|
3603
|
+
if (id === 'image') {
|
|
3630
3604
|
if (V.pending) { const p = V.pending; V.pending = null; viewProduct(p); }
|
|
3631
3605
|
viewRedraw();
|
|
3632
3606
|
}
|
|
3633
3607
|
}
|
|
3634
3608
|
|
|
3609
|
+
function selectView(id) {
|
|
3610
|
+
$('cursor').textContent = '';
|
|
3611
|
+
dock.getPanel(id)?.api.setActive();
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
function buildLayout(kind) {
|
|
3615
|
+
dock.clear();
|
|
3616
|
+
const add = (id, position, inactive = false) => dock.addPanel({ id, component: id, title: PANELS[id], position, inactive });
|
|
3617
|
+
add('map');
|
|
3618
|
+
add('image', { referencePanel: 'map', direction: kind === 'side' ? 'right' : 'within' }, kind !== 'side');
|
|
3619
|
+
add('settings', { referencePanel: 'image', direction: 'within' }, true);
|
|
3620
|
+
add('results', { direction: 'below' });
|
|
3621
|
+
add('details', { referencePanel: 'results', direction: kind === 'stacked' ? 'below' : 'right' });
|
|
3622
|
+
const size = (id, s) => dock.getPanel(id).group.api.setSize(s);
|
|
3623
|
+
if (kind === 'stacked') { size('map', { height: 440 }); size('results', { height: 320 }); }
|
|
3624
|
+
else { size('map', { height: Math.round(dock.height * 0.55) }); size('details', { width: 380 }); }
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
function restoreLayout() {
|
|
3628
|
+
if (!narrow.matches) {
|
|
3629
|
+
try {
|
|
3630
|
+
dock.fromJSON(JSON.parse(localStorage.getItem(LAYOUT_KEY)));
|
|
3631
|
+
if (Object.keys(PANELS).every((id) => dock.getPanel(id))) return;
|
|
3632
|
+
} catch { /* no saved layout */ }
|
|
3633
|
+
}
|
|
3634
|
+
buildLayout(narrow.matches ? 'stacked' : 'default');
|
|
3635
|
+
}
|
|
3636
|
+
|
|
3637
|
+
function saveLayout() {
|
|
3638
|
+
if (narrow.matches) return;
|
|
3639
|
+
try { localStorage.setItem(LAYOUT_KEY, JSON.stringify(dock.toJSON())); } catch { /* storage blocked */ }
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
function initDock() {
|
|
3643
|
+
const park = $('dock-park');
|
|
3644
|
+
dock = createDockview($('dock'), {
|
|
3645
|
+
theme: { ...themeLight, gap: 6 },
|
|
3646
|
+
disableFloatingGroups: true,
|
|
3647
|
+
disableTabsOverflowList: true,
|
|
3648
|
+
createComponent: ({ name }) => {
|
|
3649
|
+
const element = $(`view-${name}`);
|
|
3650
|
+
return {
|
|
3651
|
+
element,
|
|
3652
|
+
init: ({ api }) => api.onDidVisibilityChange(({ isVisible }) => panelVisible(name, isVisible)),
|
|
3653
|
+
onHide: () => park.append(element),
|
|
3654
|
+
dispose: () => park.append(element),
|
|
3655
|
+
};
|
|
3656
|
+
},
|
|
3657
|
+
});
|
|
3658
|
+
dock.layout($('dock').clientWidth, $('dock').clientHeight);
|
|
3659
|
+
restoreLayout();
|
|
3660
|
+
for (const id of Object.keys(PANELS)) panelVisible(id, panelShown(id));
|
|
3661
|
+
dock.onDidLayoutChange(() => { clearTimeout(saveTimer); saveTimer = setTimeout(saveLayout, 300); });
|
|
3662
|
+
narrow.addEventListener('change', restoreLayout);
|
|
3663
|
+
$('layout-side').addEventListener('click', () => buildLayout('side'));
|
|
3664
|
+
$('layout-reset').addEventListener('click', () => {
|
|
3665
|
+
try { localStorage.removeItem(LAYOUT_KEY); } catch { /* storage blocked */ }
|
|
3666
|
+
buildLayout(narrow.matches ? 'stacked' : 'default');
|
|
3667
|
+
});
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3635
3670
|
// A picked row / footprint: preview in its detail block, and the viewer follows if visible
|
|
3636
3671
|
function selectProduct(block) {
|
|
3637
3672
|
const prod = block._product;
|
|
3638
3673
|
if (!prod) return;
|
|
3639
3674
|
block._preview?._load?.();
|
|
3640
|
-
if (
|
|
3675
|
+
if (panelShown('image')) viewProduct(prod);
|
|
3641
3676
|
else V.pending = prod;
|
|
3642
3677
|
}
|
|
3643
3678
|
|
|
3644
3679
|
function initViewer() {
|
|
3645
|
-
const all = viewTabs();
|
|
3646
|
-
for (const t of all) {
|
|
3647
|
-
t.addEventListener('click', () => selectView(t.dataset.view));
|
|
3648
|
-
t.addEventListener('keydown', (e) => {
|
|
3649
|
-
const d = { ArrowRight: 1, ArrowLeft: -1 }[e.key];
|
|
3650
|
-
if (!d) return;
|
|
3651
|
-
const next = all[(all.indexOf(t) + d + all.length) % all.length];
|
|
3652
|
-
selectView(next.dataset.view);
|
|
3653
|
-
next.focus();
|
|
3654
|
-
});
|
|
3655
|
-
}
|
|
3656
3680
|
$('view-zoom-in').addEventListener('click', () => viewZoom(2));
|
|
3657
3681
|
$('view-zoom-out').addEventListener('click', () => viewZoom(0.5));
|
|
3658
3682
|
$('view-1to1').addEventListener('click', () => viewSetScale(1 / dpr()));
|
|
@@ -4139,7 +4163,7 @@
|
|
|
4139
4163
|
applyAdmin();
|
|
4140
4164
|
$('set-info').textContent = S.admin ? 'Admin' : 'Read-only';
|
|
4141
4165
|
watchJobs();
|
|
4142
|
-
if (
|
|
4166
|
+
if (panelShown('settings')) loadStatus();
|
|
4143
4167
|
} catch {
|
|
4144
4168
|
for (const node of document.querySelectorAll('#settings [data-admin], #set-refresh')) node.disabled = true;
|
|
4145
4169
|
$('set-note').hidden = false;
|
|
@@ -4148,6 +4172,7 @@
|
|
|
4148
4172
|
}
|
|
4149
4173
|
|
|
4150
4174
|
// Boot
|
|
4175
|
+
initDock();
|
|
4151
4176
|
initSearchForm();
|
|
4152
4177
|
showFormRegion();
|
|
4153
4178
|
initViewer();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lunar-toolkit
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev15
|
|
4
4
|
Summary: Find, download and process lunar orbital imagery (LROC, ShadowCam, Kaguya TC) and build stereo and shape-from-shading DEMs with ISIS + ASP
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
Keywords: moon,lroc,shadowcam,kaguya,isis,ames-stereo-pipeline,shape-from-shading,dem
|
|
@@ -55,6 +55,8 @@ Dynamic: license-file
|
|
|
55
55
|
|
|
56
56
|
# Lunar Toolkit
|
|
57
57
|
|
|
58
|
+

|
|
59
|
+
|
|
58
60
|
Lunar Toolkit finds, downloads and processes lunar orbital imagery and turns it into DEMs.
|
|
59
61
|
|
|
60
62
|
It builds a searchable index of LROC images whose footprint search also works near the poles, finds ShadowCam, LROC and Kaguya products through the PDS Orbital Data Explorer, imports images into [ISIS](https://isis.astrogeology.usgs.gov/), and builds stereo and shape-from-shading (SfS) DEMs with the [Ames Stereo Pipeline](https://stereopipeline.readthedocs.io/) through configurable, reproducible pipelines. A desktop app browses the index, ODE, footprints and full-resolution images.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lunar-toolkit"
|
|
7
|
-
version = "0.1.0.
|
|
7
|
+
version = "0.1.0.dev15"
|
|
8
8
|
description = "Find, download and process lunar orbital imagery (LROC, ShadowCam, Kaguya TC) and build stereo and shape-from-shading DEMs with ISIS + ASP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/manifest.json
RENAMED
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_global.jpg
RENAMED
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_north.jpg
RENAMED
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit/static/basemaps/wac_south.jpg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{lunar_toolkit-0.1.0.dev14 → lunar_toolkit-0.1.0.dev15}/lunar_toolkit.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|