Jakecole1 commited on
Commit
f2433b4
·
verified ·
1 Parent(s): 7d3ea29

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -97
app.py CHANGED
@@ -1,112 +1,191 @@
1
  import streamlit as st
2
- import pydeck as pdk
3
  import geopandas as gpd
4
  import pandas as pd
 
 
 
 
 
 
5
 
 
 
6
 
7
- @st.cache_data
8
- def load_geojson_data(file_paths):
9
- geodata = []
10
- for path in file_paths:
11
- gdf = gpd.read_file(path)
12
- gdf['lon'] = gdf.geometry.x
13
- gdf['lat'] = gdf.geometry.y
14
- geodata.append(gdf)
15
- return geodata
16
-
17
- st.sidebar.title("Geospatial Data Visualization")
18
- timestamp = st.sidebar.select_slider("Time", options=[f"{year}-01" for year in range(2016, 2024)])
19
-
20
-
21
- st.title("Geospatial Data Visualization")
22
-
23
-
24
- geojson_file_paths = ['kathajodi_centroids.geojson','chambal_centroids.geojson']
25
-
26
-
27
- geojson_data = load_geojson_data(geojson_file_paths)
28
-
29
-
30
- all_geo_data = pd.concat(geojson_data)
31
- all_geo_data['lon'] = all_geo_data.geometry.x
32
- all_geo_data['lat'] = all_geo_data.geometry.y
33
-
34
-
35
- if 'view_state' not in st.session_state:
36
- st.session_state.view_state = pdk.ViewState(
37
- latitude=all_geo_data['lat'].mean(),
38
- longitude=all_geo_data['lon'].mean(),
39
- zoom=10,
40
- pitch=45,
41
- bearing=0
42
- )
43
-
44
-
45
- tab1, tab2 = st.tabs(["Heatmap", "3D Hexagon Plot"])
46
-
47
-
48
- with tab1:
49
- st.subheader("Heatmap View")
50
 
51
- # Pydeck HeatmapLayer for Points
52
- heatmap_layer = pdk.Layer(
53
- "HeatmapLayer",
54
- all_geo_data,
55
- get_position=['lon', 'lat'],
56
- aggregation=pdk.types.String("MEAN"),
57
- opacity=0.5
58
- )
59
-
60
- r = pdk.Deck(
61
- layers=[heatmap_layer],
62
- initial_view_state=st.session_state.view_state,
63
- map_style='mapbox://styles/mapbox/satellite-v9'
64
- )
65
 
 
 
 
 
 
 
 
66
 
67
- st.session_state.view_state = r.initial_view_state
68
 
 
 
 
69
 
70
- st.pydeck_chart(r)
 
 
71
 
72
- # Add an informational box
73
- with st.expander("View Information"):
74
- st.write(f"Selected Time: {timestamp}")
75
- num_points = len(all_geo_data)
76
- st.write(f"Number of Features: {num_points}")
77
 
78
- # 3D Hexagon Plot Tab
79
- with tab2:
80
- st.subheader("3D Hexagon Map View")
81
-
82
-
83
- hexagon_layer = pdk.Layer(
84
- "HexagonLayer",
85
- all_geo_data,
86
- get_position=['lon', 'lat'],
87
- radius=1000,
88
- elevation_scale=20,
89
- elevation_range=[0, 1000],
90
- extruded=True,
91
- coverage=1,
92
- pickable=True
93
- )
94
-
95
-
96
- r = pdk.Deck(
97
- layers=[hexagon_layer],
98
- initial_view_state=st.session_state.view_state,
99
- map_style='mapbox://styles/mapbox/satellite-v9'
100
- )
101
 
102
-
103
- st.session_state.view_state = r.initial_view_state
 
 
 
104
 
105
 
106
- st.pydeck_chart(r)
107
-
108
- # Add informational box
109
- with st.expander("View Information"):
110
- st.write(f"Selected Time: {timestamp}")
111
- num_points = len(all_geo_data)
112
- st.write(f"Number of Features: {num_points}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
 
2
  import geopandas as gpd
3
  import pandas as pd
4
+ import os
5
+ import zipfile
6
+ import tempfile
7
+ from keplergl import KeplerGl
8
+ from shapely.geometry import Polygon, MultiPolygon
9
+ import pydeck as pdk
10
 
11
+ def main():
12
+ polygons_zip_path = 'polygons-20240817T212638Z-001.zip'
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ valid_polygon_gdfs = []
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+
18
+ with tempfile.TemporaryDirectory() as tmpdirname:
19
+ with zipfile.ZipFile(polygons_zip_path, 'r') as zip_ref:
20
+ zip_ref.extractall(tmpdirname)
21
+
22
+ polygons_dir = os.path.join(tmpdirname, 'polygons')
23
+ geojson_files = [f for f in os.listdir(polygons_dir) if f.endswith('.geojson')]
24
 
25
+ geojson_files = geojson_files[:2]
26
 
27
+ for file in geojson_files:
28
+ try:
29
+ gdf = gpd.read_file(os.path.join(polygons_dir, file)).to_crs(epsg=4326)
30
 
31
+ if gdf.empty:
32
+ st.warning(f"Skipping empty file: {file}")
33
+ continue
34
 
35
+ gdf = gdf[gdf.geometry.apply(lambda geom: isinstance(geom, (Polygon, MultiPolygon)))]
 
 
 
 
36
 
37
+ if gdf.empty:
38
+ st.warning(f"No valid geometries found in file: {file}")
39
+ continue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ valid_polygon_gdfs.append(gdf)
42
+
43
+ except Exception as e:
44
+ st.error(f"Error processing file {file}: {str(e)}")
45
+ continue
46
 
47
 
48
+ if valid_polygon_gdfs:
49
+ tab1, tab2 = st.tabs(["Editable Point based map", "Pydeck Heatmap"])
50
+
51
+ combined_polygon_gdf = gpd.GeoDataFrame(pd.concat(valid_polygon_gdfs, ignore_index=True))
52
+
53
+ with tab1:
54
+ kepler_data = {
55
+ "polygons": combined_polygon_gdf
56
+ }
57
+
58
+ kepler_map = KeplerGl(height=600)
59
+
60
+ kepler_map.add_data(data=kepler_data["polygons"], name="Polygons")
61
+
62
+ config = {
63
+ "version": "v1",
64
+ "config": {
65
+ "visState": {
66
+ "layers": [
67
+ {
68
+ "id": "polygon-layer",
69
+ "type": "geojson",
70
+ "config": {
71
+ "dataId": "Polygons",
72
+ "label": "Polygons",
73
+ "color": [255, 0, 0],
74
+ "highlightColor": [252, 242, 26, 255],
75
+ "columns": {
76
+ "geojson": "geometry"
77
+ },
78
+ "isVisible": True,
79
+ "visConfig": {
80
+ "opacity": 0.8,
81
+ "thickness": 1.5,
82
+ "strokeColor": [255, 0, 0],
83
+ "colorRange": {
84
+ "name": "Custom",
85
+ "type": "sequential",
86
+ "category": "Custom",
87
+ "colors": [
88
+ "#000004", "#3b0f70", "#8c2981", "#de4968", "#fe9f6d", "#fcfdbf" # Magma
89
+ ]
90
+ },
91
+ "filled": True,
92
+ "stroked": True,
93
+ "enable3d": False,
94
+ "wireframe": False
95
+ },
96
+ "visualChannels": {
97
+ "colorField": {
98
+ "name": "class",
99
+ "type": "real"
100
+ },
101
+ "colorScale": "quantile"
102
+ }
103
+ }
104
+ }
105
+ ]
106
+ },
107
+ "mapStyle": {
108
+ "styleType": "satellite",
109
+ "topLayerGroups": {},
110
+ "visibleLayerGroups": {
111
+ "label": True,
112
+ "road": True,
113
+ "border": False,
114
+ "building": True,
115
+ "water": True,
116
+ "land": True,
117
+ "3d building": False
118
+ },
119
+ "threeDBuildingColor": [9.665468314072013, 17.18305478057247, 31.1442867897876],
120
+ "mapStyles": {}
121
+ },
122
+ "mapState": {
123
+ "bearing": 0,
124
+ "dragRotate": True,
125
+ "latitude": combined_polygon_gdf.geometry.centroid.y.mean(),
126
+ "longitude": combined_polygon_gdf.geometry.centroid.x.mean(),
127
+ "pitch": 0,
128
+ "zoom": 10
129
+ },
130
+ "interactionConfig": {
131
+ "brush": {
132
+ "enabled": True
133
+ },
134
+ "tooltip": {
135
+ "enabled": True,
136
+ "fieldsToShow": {
137
+ "Polygons": [
138
+ {
139
+ "name": "class",
140
+ "format": None
141
+ }
142
+ ]
143
+ }
144
+ }
145
+ },
146
+ "animationConfig": {
147
+ "enabled": True
148
+ }
149
+ }
150
+ }
151
+
152
+ kepler_map = KeplerGl(height=600, config=config)
153
+ kepler_map.add_data(data=kepler_data["polygons"], name="Polygons")
154
+ kepler_map.save_to_html(file_name="kepler_map.html")
155
+ st.components.v1.html(open("kepler_map.html", 'r').read(), height=600)
156
+ st.sidebar.title("Summary Stats")
157
+ st.sidebar.write(combined_polygon_gdf.describe())
158
+
159
+ with tab2:
160
+ combined_polygon_gdf['centroid'] = combined_polygon_gdf.geometry.centroid
161
+ combined_polygon_gdf['longitude'] = combined_polygon_gdf.centroid.x
162
+ combined_polygon_gdf['latitude'] = combined_polygon_gdf.centroid.y
163
+ data = combined_polygon_gdf[['longitude', 'latitude', 'class']]
164
+ heatmap_layer = pdk.Layer(
165
+ "HeatmapLayer",
166
+ data=data,
167
+ get_position='[longitude, latitude]',
168
+ get_weight="class",
169
+ radius_pixels=50,
170
+ )
171
+
172
+ view_state = pdk.ViewState(
173
+ latitude=combined_polygon_gdf.geometry.centroid.y.mean(),
174
+ longitude=combined_polygon_gdf.geometry.centroid.x.mean(),
175
+ zoom=10,
176
+ bearing=0,
177
+ pitch=0
178
+ )
179
+
180
+ r = pdk.Deck(
181
+ layers=[heatmap_layer],
182
+ initial_view_state=view_state,
183
+ map_style='mapbox://styles/mapbox/satellite-v9'
184
+ )
185
+
186
+ st.pydeck_chart(r)
187
+ else:
188
+ st.error("No valid GeoDataFrames could be combined.")
189
+
190
+ if __name__ == "__main__":
191
+ main()