giswqs commited on
Commit
cd11da1
·
unverified ·
0 Parent(s):

Initial commit

Browse files
.github/workflows/sync-hf.yml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face hub
2
+ on:
3
+ push:
4
+ branches: [main]
5
+
6
+ # to run this workflow manually from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ sync-to-hub:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+ lfs: true
17
+ - name: Push to hub
18
+ env:
19
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
20
+ run: git push --force https://giswqs:[email protected]/spaces/giswqs/leafmap-voila main
.gitignore ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116
+ .pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
169
+
170
+ # Ruff stuff:
171
+ .ruff_cache/
172
+
173
+ # PyPI configuration file
174
+ .pypirc
.pre-commit-config.yaml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: check-toml
6
+ - id: check-yaml
7
+ - id: end-of-file-fixer
8
+ types: [python]
9
+ - id: trailing-whitespace
10
+ - id: requirements-txt-fixer
11
+ - id: check-added-large-files
12
+ args: ["--maxkb=500"]
13
+
14
+ - repo: https://github.com/psf/black
15
+ rev: 25.1.0
16
+ hooks:
17
+ - id: black-jupyter
18
+
19
+ - repo: https://github.com/codespell-project/codespell
20
+ rev: v2.4.1
21
+ hooks:
22
+ - id: codespell
23
+ args:
24
+ [
25
+ "--ignore-words-list=aci,acount,acounts,fallow,ges,hart,hist,nd,ned,ois,wqs,watermask,tre,mape",
26
+ "--skip=*.csv,*.geojson,*.json,*.yml*.js,*.html,*cff,*.pdf",
27
+ ]
28
+
29
+ - repo: https://github.com/kynan/nbstripout
30
+ rev: 0.8.1
31
+ hooks:
32
+ - id: nbstripout
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM condaforge/mambaforge:latest
2
+
3
+ # The HF Space container runs with user ID 1000.
4
+ RUN useradd -m -u 1000 user
5
+ USER user
6
+
7
+ # Set home to the user's home directory
8
+ ENV HOME=/home/user \
9
+ PATH=/home/user/.local/bin:$PATH
10
+
11
+ # Set the working directory to the user's home directory
12
+ WORKDIR $HOME/app
13
+ COPY --chown=user . .
14
+
15
+ RUN mamba env create --prefix $HOME/env -f ./environment.yml
16
+
17
+ EXPOSE 7860
18
+ WORKDIR $HOME/app
19
+
20
+ CMD ["mamba", "run", "-p", "/home/user/env", "--no-capture-output", "voila", "--no-browser", "notebooks/"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Open Geospatial Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Leafmap Voila
3
+ emoji: 🚀
4
+ colorFrom: red
5
+ colorTo: red
6
+ sdk: docker
7
+ app_port: 7860
8
+ tags:
9
+ - leafmap
10
+ pinned: false
11
+ short_description: A Voila template for leafmap
12
+ license: mit
13
+ ---
14
+
15
+ # leafmap-voila
16
+
17
+ Build a docker image for using leafmap with Voila
18
+
19
+ To build the image:
20
+
21
+ ```bash
22
+ docker buildx build --platform linux/amd64,linux/arm64 -t giswqs/leafmap:voila --push .
23
+ ```
24
+
25
+ To run the image:
26
+
27
+ ```bash
28
+ docker run -it -p 7860:7860 -v $(pwd):/home/jovyan/notebooks giswqs/leafmap:voila
29
+ ```
30
+
31
+ To push the image to the registry:
32
+
33
+ ```bash
34
+ docker push giswqs/leafmap:voila
35
+ ```
environment.yml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: voila
2
+ channels:
3
+ - conda-forge
4
+ dependencies:
5
+ - python=3.12
6
+ - pip
7
+ - ipykernel
8
+ - jupyterlab
9
+ - leafmap
10
+ - maplibre
11
+ - voila
12
+ - voila_topbar
notebooks/dashboard.ipynb ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "# %pip install leafmap"
11
+ ]
12
+ },
13
+ {
14
+ "cell_type": "code",
15
+ "execution_count": null,
16
+ "id": "1",
17
+ "metadata": {},
18
+ "outputs": [],
19
+ "source": [
20
+ "import leafmap.maplibregl as leafmap\n",
21
+ "import ipywidgets as widgets"
22
+ ]
23
+ },
24
+ {
25
+ "cell_type": "code",
26
+ "execution_count": null,
27
+ "id": "2",
28
+ "metadata": {},
29
+ "outputs": [],
30
+ "source": [
31
+ "tw = leafmap.TabWidget(\n",
32
+ " title=\"Interactive Dashboard\",\n",
33
+ " tabs=(\"Home\", \"Map\", \"Population\", \"Settings\"),\n",
34
+ " icons=(\"mdi-home\", \"mdi-airplane\", \"mdi-account-box\", \"mdi-cog\"),\n",
35
+ " show_panel_titles=False,\n",
36
+ ")\n",
37
+ "\n",
38
+ "# Customize dialog\n",
39
+ "tw.set_help_title(\"About this dashboard\")\n",
40
+ "tw.set_help_content(\n",
41
+ " widgets.HTML(\n",
42
+ " \"\"\"\n",
43
+ " <p><b>User Guide</b></p>\n",
44
+ " <ul>\n",
45
+ " <li>Step 1: Click on the tab</li>\n",
46
+ " <li>Navigate the map</li>\n",
47
+ " <li>? — help</li>\n",
48
+ " </ul>\n",
49
+ " \"\"\"\n",
50
+ " )\n",
51
+ ")\n",
52
+ "\n",
53
+ "m = leafmap.Map(projection=\"globe\", sidebar_visible=True, height=\"600px\")\n",
54
+ "m.add_overture_3d_buildings()\n",
55
+ "m.create_container()\n",
56
+ "\n",
57
+ "home_tab = widgets.HTML(\n",
58
+ " \"\"\"\n",
59
+ " <h1>Welcome to the Leafmap Visualization Dashboard</h1>\n",
60
+ " <p>This is the home tab.</p>\n",
61
+ " <img src=\"https://assets.gishub.org/images/geog-312.png\" width=\"100%\">\n",
62
+ " \"\"\"\n",
63
+ ")\n",
64
+ "\n",
65
+ "settings_tab = widgets.HTML(\n",
66
+ " \"\"\"\n",
67
+ " <h1>Settings</h1>\n",
68
+ " <p>This is the settings tab.</p>\n",
69
+ " \"\"\"\n",
70
+ ")\n",
71
+ "\n",
72
+ "data = \"https://github.com/opengeos/datasets/releases/download/vector/countries.geojson\"\n",
73
+ "\n",
74
+ "m2 = leafmap.Map(style=\"liberty\", projection=\"globe\")\n",
75
+ "first_symbol_id = m2.find_first_symbol_layer()[\"id\"]\n",
76
+ "m2.add_data(\n",
77
+ " data,\n",
78
+ " column=\"POP_EST\",\n",
79
+ " scheme=\"Quantiles\",\n",
80
+ " cmap=\"Blues\",\n",
81
+ " legend_title=\"Population\",\n",
82
+ " name=\"population\",\n",
83
+ " # before_id=first_symbol_id,\n",
84
+ " extrude=True,\n",
85
+ " scale_factor=1000,\n",
86
+ ")\n",
87
+ "container = m2.create_container()\n",
88
+ "\n",
89
+ "tw.set_tab_content(0, home_tab)\n",
90
+ "tw.set_tab_content(1, m.container)\n",
91
+ "tw.set_tab_content(3, settings_tab)\n",
92
+ "tw.set_tab_content(2, m2.container)\n",
93
+ "\n",
94
+ "tw.widget"
95
+ ]
96
+ }
97
+ ],
98
+ "metadata": {
99
+ "kernelspec": {
100
+ "display_name": "geo",
101
+ "language": "python",
102
+ "name": "python3"
103
+ },
104
+ "language_info": {
105
+ "codemirror_mode": {
106
+ "name": "ipython",
107
+ "version": 3
108
+ },
109
+ "file_extension": ".py",
110
+ "mimetype": "text/x-python",
111
+ "name": "python",
112
+ "nbconvert_exporter": "python",
113
+ "pygments_lexer": "ipython3",
114
+ "version": "3.12.2"
115
+ }
116
+ },
117
+ "nbformat": 4,
118
+ "nbformat_minor": 5
119
+ }
notebooks/leafmap.ipynb ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import leafmap.maplibregl as leafmap"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": null,
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "m = leafmap.Map(\n",
19
+ " style=\"liberty\", projection=\"globe\", sidebar_visible=True, height=\"750px\"\n",
20
+ ")\n",
21
+ "m.add_basemap(\"USGS.Imagery\")\n",
22
+ "cities = (\n",
23
+ " \"https://github.com/opengeos/datasets/releases/download/world/world_cities.geojson\"\n",
24
+ ")\n",
25
+ "m.add_geojson(cities, name=\"Cities\")\n",
26
+ "m"
27
+ ]
28
+ }
29
+ ],
30
+ "metadata": {
31
+ "kernelspec": {
32
+ "display_name": "geo",
33
+ "language": "python",
34
+ "name": "python3"
35
+ },
36
+ "language_info": {
37
+ "codemirror_mode": {
38
+ "name": "ipython",
39
+ "version": 3
40
+ },
41
+ "file_extension": ".py",
42
+ "mimetype": "text/x-python",
43
+ "name": "python",
44
+ "nbconvert_exporter": "python",
45
+ "pygments_lexer": "ipython3",
46
+ "version": "3.12.2"
47
+ }
48
+ },
49
+ "nbformat": 4,
50
+ "nbformat_minor": 2
51
+ }
voila.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "Voila": {
3
+ "ip":"0.0.0.0",
4
+ "port": 7860,
5
+ "tornado_settings": {
6
+ "headers": {
7
+ "Content-Security-Policy": "frame-ancestors self *"
8
+ }
9
+ }
10
+ }
11
+ }