engratif78 commited on
Commit
8444ac4
Β·
verified Β·
1 Parent(s): a66ffac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -118
app.py CHANGED
@@ -5,30 +5,16 @@ import zipfile
5
  import tempfile
6
  import os
7
  from streamlit_folium import st_folium
 
 
 
 
 
 
 
 
 
8
 
9
- # Set Google Maps API Key (Replace with your actual API Key)
10
- google_maps_api_key = "YOUR_GOOGLE_MAPS_API_KEY" # Replace with your own Google Maps API Key
11
-
12
- st.set_page_config(page_title="🌍 GIS Data Viewer", layout="wide", page_icon="πŸ—ΊοΈ")
13
-
14
- # ---------- Title & Intro ----------
15
- st.markdown("""
16
- <div style='text-align: center'>
17
- <h1 style="color:#1f77b4;">πŸ—ΊοΈ GIS Data Viewer</h1>
18
- <p style="font-size:18px;">Upload and explore your geospatial data (GeoJSON, Shapefile ZIP, or KMZ) on an interactive map with **Google Maps**.</p>
19
- </div>
20
- """, unsafe_allow_html=True)
21
-
22
- # ---------- Sidebar ----------
23
- with st.sidebar:
24
- st.header("πŸ“‚ Upload & Options")
25
- uploaded_file = st.file_uploader("Choose a GeoJSON, KMZ, or zipped Shapefile", type=["geojson", "zip", "kmz"])
26
- show_coordinates = st.checkbox("Show Coordinates", value=True)
27
- show_table = st.checkbox("Show Attribute Table", value=True)
28
- st.markdown("---")
29
- st.markdown("βœ… Supported formats:\n- `.geojson`\n- `.shp` in `.zip`\n- `.kmz`\n\nπŸ“ Automatically reprojects to **WGS84 (EPSG:4326)**.")
30
-
31
- # ---------- Load File Function ----------
32
  def load_geodata(file):
33
  ext = file.name.lower()
34
  with tempfile.TemporaryDirectory() as tmpdir:
@@ -50,106 +36,63 @@ def load_geodata(file):
50
  gdf = gpd.read_file(os.path.join(tmpdir, kml_files[0]))
51
  else:
52
  raise Exception("Unsupported file format.")
53
-
54
- # Ensure CRS is WGS84
55
  if gdf.crs and gdf.crs.to_epsg() != 4326:
56
  gdf = gdf.to_crs(epsg=4326)
57
  return gdf
58
 
59
- # ---------- Show Map Function ----------
60
- def show_map(gdf, show_coords):
61
- if gdf is not None and not gdf.empty:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  center = gdf.geometry.unary_union.centroid
63
- m = folium.Map(location=[center.y, center.x], zoom_start=10, tiles=None)
64
-
65
- # Add Google Maps TileLayer
66
- google_maps_url = f'https://{google_maps_api_key}.googleusercontent.com/maps/vt/lyrs=m&x={{x}}&y={{y}}&z={{z}}'
67
- folium.TileLayer(tiles=google_maps_url, attr="Google Maps", name="Google Maps").add_to(m)
68
-
69
- def style_func(feature):
70
- return {"fillColor": "#4287f5", "color": "#003366", "weight": 2, "fillOpacity": 0.6}
71
-
72
- folium.GeoJson(data=gdf, style_function=style_func, name="GeoData").add_to(m)
73
-
74
- if show_coords:
75
- for idx, row in gdf.iterrows():
76
- if row.geometry.geom_type == 'Point':
77
- coords = row.geometry.coords[0]
78
- folium.Marker(
79
- location=[coords[1], coords[0]],
80
- popup=f"Point {idx+1} - Coordinates: ({coords[1]}, {coords[0]})",
81
- icon=folium.Icon(color='blue', icon='info-sign')
82
- ).add_to(m)
83
- else:
84
- centroid = row.geometry.centroid
85
- folium.Marker(
86
- location=[centroid.y, centroid.x],
87
- popup=f"Feature {idx+1} - Coordinates: ({centroid.y}, {centroid.x})",
88
- icon=folium.Icon(color='green', icon='ok-sign')
89
- ).add_to(m)
90
-
91
- # Add Layer Control
92
  folium.LayerControl().add_to(m)
93
 
94
- return m
95
- else:
96
- return folium.Map(location=[30.0, 70.0], zoom_start=3)
97
 
98
- # ---------- Main Viewer ----------
99
- try:
100
- if uploaded_file:
101
- with st.spinner("Processing your file..."):
102
- gdf = load_geodata(uploaded_file)
103
- st.success("βœ… File successfully loaded.")
104
-
105
- # File Metadata
106
- st.subheader("πŸ“„ File Information")
107
- st.markdown(f"""
108
- - **Geometry Type**: {gdf.geom_type.iloc[0] if not gdf.empty else 'N/A'}
109
- - **CRS**: {gdf.crs}
110
- - **Number of Features**: {len(gdf)}
111
- - **Columns**: {", ".join(gdf.columns)}
112
- """)
113
-
114
- # Show Map
115
- st.subheader("πŸ—ΊοΈ Map Viewer")
116
- map_view = show_map(gdf, show_coordinates)
117
- st_data = st_folium(map_view, width=1100, height=600)
118
-
119
- # Show Coordinates in Table
120
- if show_coordinates:
121
- st.subheader("πŸ“ Coordinates Table")
122
- coords_list = []
123
-
124
- # Extract coordinates from geometries
125
- for idx, row in gdf.iterrows():
126
- if row.geometry.geom_type == 'Point':
127
- coords = row.geometry.coords[0]
128
- coords_list.append({
129
- "Feature ID": idx + 1,
130
- "Geometry Type": row.geometry.geom_type,
131
- "Coordinates": f"({coords[1]}, {coords[0]})"
132
- })
133
- else:
134
- centroid = row.geometry.centroid
135
- coords_list.append({
136
- "Feature ID": idx + 1,
137
- "Geometry Type": row.geometry.geom_type,
138
- "Coordinates": f"({centroid.y}, {centroid.x})"
139
- })
140
-
141
- # Display coordinates as table
142
- st.dataframe(coords_list)
143
-
144
- # Show Attribute Table
145
- if show_table:
146
- st.subheader("πŸ“‹ Attribute Table")
147
- st.dataframe(gdf)
148
-
149
- else:
150
- st.info("Please upload a GeoJSON, zipped Shapefile, or KMZ to begin.")
151
- map_view = show_map(None, False)
152
- st_folium(map_view, width=1100, height=500)
153
-
154
- except Exception as e:
155
- st.error(f"❌ Error: {e}")
 
5
  import tempfile
6
  import os
7
  from streamlit_folium import st_folium
8
+ from shapely.geometry import LineString
9
+
10
+ st.set_page_config(page_title="GIS Viewer", layout="wide")
11
+
12
+ st.title("πŸ—ΊοΈ GIS Viewer with Connected Points")
13
+
14
+ st.markdown("Upload a GeoJSON, KMZ, or zipped Shapefile. This app will connect every 2 consecutive points with a solid line.")
15
+
16
+ uploaded_file = st.file_uploader("Upload GeoJSON, KMZ or zipped Shapefile", type=["geojson", "zip", "kmz"])
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  def load_geodata(file):
19
  ext = file.name.lower()
20
  with tempfile.TemporaryDirectory() as tmpdir:
 
36
  gdf = gpd.read_file(os.path.join(tmpdir, kml_files[0]))
37
  else:
38
  raise Exception("Unsupported file format.")
 
 
39
  if gdf.crs and gdf.crs.to_epsg() != 4326:
40
  gdf = gdf.to_crs(epsg=4326)
41
  return gdf
42
 
43
+ def create_lines_from_points(points_gdf):
44
+ lines = []
45
+ for i in range(0, len(points_gdf) - 1, 2):
46
+ p1 = points_gdf.iloc[i].geometry
47
+ p2 = points_gdf.iloc[i+1].geometry
48
+ if p1.geom_type == "Point" and p2.geom_type == "Point":
49
+ line = LineString([p1, p2])
50
+ lines.append({"geometry": line})
51
+ return gpd.GeoDataFrame(lines, geometry="geometry", crs="EPSG:4326")
52
+
53
+ if uploaded_file:
54
+ try:
55
+ with st.spinner("Processing file..."):
56
+ gdf = load_geodata(uploaded_file)
57
+
58
+ st.success("File loaded successfully!")
59
+
60
+ # Filter only points
61
+ point_gdf = gdf[gdf.geometry.type == "Point"].reset_index(drop=True)
62
+ line_gdf = create_lines_from_points(point_gdf)
63
+
64
+ # Map setup
65
  center = gdf.geometry.unary_union.centroid
66
+ m = folium.Map(location=[center.y, center.x], zoom_start=10)
67
+
68
+ folium.GeoJson(gdf, name="Features",
69
+ tooltip=folium.GeoJsonTooltip(fields=gdf.columns[:3].tolist())).add_to(m)
70
+
71
+ # Add lines between points
72
+ folium.GeoJson(line_gdf, name="Lines Between Points",
73
+ style_function=lambda x: {"color": "red", "weight": 3}).add_to(m)
74
+
75
+ # Add point markers
76
+ for idx, row in point_gdf.iterrows():
77
+ coords = row.geometry.coords[0]
78
+ folium.Marker(
79
+ location=[coords[1], coords[0]],
80
+ popup=f"Point {idx+1} - ({coords[1]}, {coords[0]})",
81
+ icon=folium.Icon(color="blue", icon="info-sign")
82
+ ).add_to(m)
83
+
 
 
 
 
 
 
 
 
 
 
 
84
  folium.LayerControl().add_to(m)
85
 
86
+ st.subheader("🌍 Map Viewer")
87
+ st_folium(m, width=1100, height=600)
 
88
 
89
+ st.subheader("πŸ“ Points Table")
90
+ st.dataframe(point_gdf)
91
+
92
+ st.subheader("πŸ“‹ Full Attribute Table")
93
+ st.dataframe(gdf)
94
+
95
+ except Exception as e:
96
+ st.error(f"Error: {e}")
97
+ else:
98
+ st.info("Please upload a geospatial file to get started.")