giswqs pre-commit-ci[bot] commited on
Commit
1b68c20
·
unverified ·
1 Parent(s): 1d9e843

Initial commit (#1)

Browse files

* Initial commit

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.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@v5
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/duckdb-solara main
.gitignore CHANGED
@@ -182,9 +182,9 @@ cython_debug/
182
  .abstra/
183
 
184
  # Visual Studio Code
185
- # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
  # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
- # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
  # you could uncomment the following to ignore the entire vscode folder
189
  # .vscode/
190
 
 
182
  .abstra/
183
 
184
  # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
  # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
  # you could uncomment the following to ignore the entire vscode folder
189
  # .vscode/
190
 
.pre-commit-config.yaml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.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,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM quay.io/jupyter/base-notebook:latest
2
+
3
+ COPY requirements.txt .
4
+ RUN pip install -r requirements.txt
5
+
6
+ RUN mkdir ./pages
7
+ COPY /pages ./pages
8
+
9
+ WORKDIR /home/jovyan
10
+ USER jovyan
11
+
12
+ EXPOSE 7860
13
+
14
+ HEALTHCHECK CMD curl --fail http://localhost:7860/_stcore/health
15
+
16
+ ENTRYPOINT ["solara", "run", "./pages", "--host=0.0.0.0", "--port=7860"]
README.md ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: DuckDB Solara
3
+ emoji: 📚
4
+ colorFrom: green
5
+ colorTo: yellow
6
+ sdk: docker
7
+ pinned: false
8
+ license: mit
9
+ short_description: A solara web app template for DuckDB
10
+ ---
11
+
12
+ This is a Solara web app for DuckDB. Click on the menu above to see the different examples.
13
+
14
+ Source code: <https://github.com/opengeos/duckdb-solara>
15
+
16
+ ![](https://github.com/user-attachments/assets/216789ff-7e9d-46df-8bb0-9fbaca531a39)
pages/00_home.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import solara
2
+
3
+
4
+ @solara.component
5
+ def Page():
6
+ with solara.Column(align="center"):
7
+ markdown = """
8
+ ## A Solara web app for DuckDB
9
+
10
+ This is a Solara web app for DuckDB. Click on the menu above to see the different examples.
11
+ <br>
12
+ Source code: <https://github.com/opengeos/duckdb-solara>
13
+
14
+ ![](https://github.com/user-attachments/assets/216789ff-7e9d-46df-8bb0-9fbaca531a39)
15
+ """
16
+
17
+ solara.Markdown(markdown)
pages/01_h3.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import duckdb
3
+ import solara
4
+ import ipywidgets as widgets
5
+ import leafmap.maplibregl as leafmap
6
+ import matplotlib.pyplot as plt
7
+
8
+
9
+ def create_map():
10
+
11
+ m = leafmap.Map(
12
+ add_sidebar=True,
13
+ add_floating_sidebar=False,
14
+ sidebar_visible=True,
15
+ layer_manager_expanded=False,
16
+ height="800px",
17
+ )
18
+ m.add_basemap("Esri.WorldImagery", before_id=m.first_symbol_layer_id, visible=False)
19
+ m.add_draw_control(controls=["polygon", "trash"])
20
+
21
+ con = duckdb.connect()
22
+ con.install_extension("httpfs")
23
+ con.install_extension("spatial")
24
+ con.install_extension("h3", repository="community")
25
+ con.load_extension("httpfs")
26
+ con.load_extension("spatial")
27
+ con.load_extension("h3")
28
+
29
+ url = "https://data.gishub.org/duckdb/h3_res4_geo.parquet"
30
+
31
+ con.sql(
32
+ f"CREATE TABLE IF NOT EXISTS h3_res4_geo AS SELECT * FROM read_parquet('{url}');"
33
+ )
34
+
35
+ colormaps = sorted(plt.colormaps())
36
+
37
+ checkbox = widgets.Checkbox(
38
+ description="3D Map",
39
+ value=True,
40
+ style={"description_width": "initial"},
41
+ layout=widgets.Layout(width="initial"),
42
+ )
43
+ outline_chk = widgets.Checkbox(
44
+ description="Add Hexagon Outline",
45
+ value=False,
46
+ style={"description_width": "initial"},
47
+ layout=widgets.Layout(width="initial"),
48
+ )
49
+
50
+ colormap_dropdown = widgets.Dropdown(
51
+ options=colormaps,
52
+ description="Colormap:",
53
+ value="inferno",
54
+ style={"description_width": "initial"},
55
+ )
56
+ class_slider = widgets.IntSlider(
57
+ description="Class:",
58
+ min=1,
59
+ max=10,
60
+ step=1,
61
+ value=5,
62
+ style={"description_width": "initial"},
63
+ )
64
+ apply_btn = widgets.Button(description="Apply")
65
+ close_btn = widgets.Button(description="Close")
66
+ output_widget = widgets.Output()
67
+ output_widget.append_stdout(
68
+ "Draw a polygon on the map. Then, \nclick on the 'Apply' button"
69
+ )
70
+
71
+ def on_apply_btn_click(change):
72
+ with output_widget:
73
+ try:
74
+ output_widget.outputs = ()
75
+ if len(m.draw_features_selected) > 0:
76
+ geojson = m.draw_features_selected[0]["geometry"]
77
+ df = con.sql(
78
+ f"""
79
+ SELECT * EXCLUDE (geometry), ST_AsText(geometry) AS geometry FROM h3_res4_geo
80
+ WHERE ST_Intersects(geometry, ST_GeomFromGeoJSON('{json.dumps(geojson)}'));
81
+ """
82
+ ).df()
83
+ gdf = leafmap.df_to_gdf(df)
84
+ if "H3 Hexagon" in m.layer_dict:
85
+ m.remove_layer("H3 Hexagon")
86
+
87
+ if outline_chk.value:
88
+ outline_color = "rgba(255, 255, 255, 255)"
89
+ else:
90
+ outline_color = "rgba(255, 255, 255, 0)"
91
+
92
+ if checkbox.value:
93
+ m.add_data(
94
+ gdf,
95
+ column="building_count",
96
+ scheme="JenksCaspall",
97
+ cmap=colormap_dropdown.value,
98
+ k=class_slider.value,
99
+ outline_color=outline_color,
100
+ name="H3 Hexagon",
101
+ before_id=m.first_symbol_layer_id,
102
+ extrude=True,
103
+ fit_bounds=False,
104
+ add_legend=False,
105
+ )
106
+ else:
107
+ m.add_data(
108
+ gdf,
109
+ column="building_count",
110
+ scheme="JenksCaspall",
111
+ cmap=colormap_dropdown.value,
112
+ k=class_slider.value,
113
+ outline_color=outline_color,
114
+ name="H3 Hexagon",
115
+ before_id=m.first_symbol_layer_id,
116
+ fit_bounds=False,
117
+ add_legend=False,
118
+ )
119
+
120
+ m.remove_from_sidebar(name="Legend")
121
+ m.add_legend_to_sidebar(
122
+ title="Building Count",
123
+ legend_dict=m.legend_dict,
124
+ )
125
+ except Exception as e:
126
+ with output_widget:
127
+ output_widget.outputs = ()
128
+ output_widget.append_stderr(str(e))
129
+
130
+ def on_close_btn_click(change):
131
+ m.remove_from_sidebar(name="H3 Hexagonal Grid")
132
+
133
+ apply_btn.on_click(on_apply_btn_click)
134
+ close_btn.on_click(on_close_btn_click)
135
+
136
+ widget = widgets.VBox(
137
+ [
138
+ widgets.HBox([checkbox, outline_chk]),
139
+ colormap_dropdown,
140
+ class_slider,
141
+ widgets.HBox([apply_btn, close_btn]),
142
+ output_widget,
143
+ ]
144
+ )
145
+ m.create_container()
146
+ m.add_to_sidebar(
147
+ widget, label="H3 Hexagonal Grid", widget_icon="mdi-hexagon-multiple"
148
+ )
149
+
150
+ return m
151
+
152
+
153
+ @solara.component
154
+ def Page():
155
+ m = create_map()
156
+ return m.to_solara()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ anymap
2
+ fiona
3
+ geopandas
4
+ leafmap>=0.57.8
5
+ mapclassify
6
+ solara