Spaces:
Sleeping
Sleeping
updated area estimates
Browse files- pag/add_field.py +56 -28
pag/add_field.py
CHANGED
@@ -8,9 +8,13 @@ from folium.plugins import Draw
|
|
8 |
from shapely.geometry import Polygon
|
9 |
from streamlit_folium import st_folium
|
10 |
from authentication import greeting, check_password
|
11 |
-
import shapely.ops as ops
|
12 |
from functools import partial
|
13 |
-
import pyproj
|
|
|
|
|
|
|
|
|
14 |
|
15 |
def check_authentication():
|
16 |
if not check_password():
|
@@ -18,7 +22,18 @@ def check_authentication():
|
|
18 |
|
19 |
|
20 |
|
|
|
|
|
|
|
21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
def display_existing_fields(current_user):
|
24 |
with st.expander("Existing Fields", expanded=False):
|
@@ -30,17 +45,28 @@ def display_existing_fields(current_user):
|
|
30 |
else:
|
31 |
st.info("No Fields Added Yet!")
|
32 |
|
33 |
-
def add_existing_fields_to_map(
|
34 |
if os.path.exists(f"fields_{current_user}.parquet"):
|
35 |
-
fg = folium.FeatureGroup(name="Existing Fields", control=True).add_to(
|
36 |
gdf = gpd.read_parquet(f"fields_{current_user}.parquet")
|
37 |
for i, row in gdf.iterrows():
|
38 |
edges = row['geometry'].exterior.coords.xy
|
39 |
edges = [[i[1], i[0]] for i in zip(*edges)]
|
40 |
folium.Polygon(edges, color='blue', fill=True, fill_color='blue', fill_opacity=0.6).add_to(fg)
|
41 |
-
return
|
42 |
|
43 |
def get_center_of_existing_fields(current_user):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
if os.path.exists(f"fields_{current_user}.parquet"):
|
45 |
gdf = gpd.read_parquet(f"fields_{current_user}.parquet")
|
46 |
edges = gdf['geometry'][0].exterior.coords.xy
|
@@ -50,14 +76,14 @@ def get_center_of_existing_fields(current_user):
|
|
50 |
return edges_center
|
51 |
return [15.572363674301132, 32.69167103104079]
|
52 |
|
53 |
-
def display_map_and_drawing_controls(
|
54 |
zoom_start = 13
|
55 |
if st.session_state['active_drawing'] is None:
|
56 |
st.info("IMPORTANT: Click on the drawing to confirm the drawn field", icon="π¨")
|
57 |
sat_basemap = utils.basemaps['Google Satellite Hybrid'] # Change this line to use 'Google Satellite Hybrid'
|
58 |
-
sat_basemap.add_to(
|
59 |
-
folium.LayerControl().add_to(
|
60 |
-
output = st_folium(
|
61 |
active_drawing = output['last_active_drawing']
|
62 |
st.session_state['active_drawing'] = active_drawing
|
63 |
return False
|
@@ -136,9 +162,9 @@ def check_intersection_with_existing_fields(active_drawing, current_user):
|
|
136 |
if geom1.overlaps(geom2).any():
|
137 |
st.warning("Field intersects with existing fields. Please draw again!")
|
138 |
with st.expander("Intersecting Fields", expanded=False):
|
139 |
-
|
140 |
-
|
141 |
-
st_folium(
|
142 |
return True
|
143 |
return False
|
144 |
|
@@ -147,21 +173,23 @@ def check_intersection_with_existing_fields(active_drawing, current_user):
|
|
147 |
def check_polygon_area_within_range(active_drawing, min_area_km2=1, max_area_km2=10):
|
148 |
if active_drawing is None:
|
149 |
return
|
|
|
|
|
150 |
edges = [[i[0], i[1]] for i in active_drawing['geometry']['coordinates'][0]]
|
151 |
geom = Polygon(edges)
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
if geom_area < min_area_km2:
|
160 |
-
st.warning(f"Field area is less than {min_area_km2} km2. Please draw again!")
|
161 |
return False
|
162 |
-
if
|
163 |
-
st.warning(f"Field area is more than {max_area_km2} km2. Please draw again!")
|
164 |
return False
|
|
|
|
|
165 |
return True
|
166 |
|
167 |
|
@@ -170,18 +198,18 @@ def add_drawing():
|
|
170 |
current_user = greeting("Drag and Zoom and draw your fields on the map, make sure to name them uniquely")
|
171 |
current_user = st.session_state['current_user']
|
172 |
display_existing_fields(current_user)
|
173 |
-
|
174 |
center_start = get_center_of_existing_fields(current_user)
|
175 |
zoom_start = 13
|
176 |
-
|
|
|
177 |
|
178 |
draw_options = {'polyline': False, 'polygon': True, 'rectangle': True, 'circle': False, 'marker': False, 'circlemarker': False}
|
179 |
-
Draw(export=True, draw_options=draw_options).add_to(
|
180 |
-
|
181 |
|
182 |
|
183 |
|
184 |
-
captured = display_map_and_drawing_controls(
|
185 |
if captured:
|
186 |
intersects = check_intersection_with_existing_fields(st.session_state['active_drawing'], current_user)
|
187 |
within_area = check_polygon_area_within_range(st.session_state['active_drawing'])
|
|
|
8 |
from shapely.geometry import Polygon
|
9 |
from streamlit_folium import st_folium
|
10 |
from authentication import greeting, check_password
|
11 |
+
# import shapely.ops as ops
|
12 |
from functools import partial
|
13 |
+
# import pyproj
|
14 |
+
from pyproj import Transformer
|
15 |
+
from shapely.ops import transform
|
16 |
+
from geopy.geocoders import Nominatim
|
17 |
+
from streamlit_folium import folium_static
|
18 |
|
19 |
def check_authentication():
|
20 |
if not check_password():
|
|
|
22 |
|
23 |
|
24 |
|
25 |
+
# Function to get coordinates from a location name
|
26 |
+
def get_location_coordinates(location_name):
|
27 |
+
geolocator = Nominatim(user_agent="geoapiExercises")
|
28 |
|
29 |
+
try:
|
30 |
+
location = geolocator.geocode(location_name)
|
31 |
+
if location:
|
32 |
+
return location.latitude, location.longitude
|
33 |
+
else:
|
34 |
+
return None, None
|
35 |
+
except:
|
36 |
+
return None, None
|
37 |
|
38 |
def display_existing_fields(current_user):
|
39 |
with st.expander("Existing Fields", expanded=False):
|
|
|
45 |
else:
|
46 |
st.info("No Fields Added Yet!")
|
47 |
|
48 |
+
def add_existing_fields_to_map(field_map, current_user):
|
49 |
if os.path.exists(f"fields_{current_user}.parquet"):
|
50 |
+
fg = folium.FeatureGroup(name="Existing Fields", control=True).add_to(field_map)
|
51 |
gdf = gpd.read_parquet(f"fields_{current_user}.parquet")
|
52 |
for i, row in gdf.iterrows():
|
53 |
edges = row['geometry'].exterior.coords.xy
|
54 |
edges = [[i[1], i[0]] for i in zip(*edges)]
|
55 |
folium.Polygon(edges, color='blue', fill=True, fill_color='blue', fill_opacity=0.6).add_to(fg)
|
56 |
+
return field_map
|
57 |
|
58 |
def get_center_of_existing_fields(current_user):
|
59 |
+
location_name = st.text_input('Enter a location to search:')
|
60 |
+
if location_name:
|
61 |
+
lat, lon = get_location_coordinates(location_name)
|
62 |
+
if lat is not None and lon is not None:
|
63 |
+
# Update your map to center on the search result and adjust zoom as desired
|
64 |
+
m = folium.Map(location=[lat, lon], zoom_start=13)
|
65 |
+
# Add the map to the Streamlit app
|
66 |
+
# st_data = folium_static(m)
|
67 |
+
return [lat, lon]
|
68 |
+
else:
|
69 |
+
st.error('Location not found. Please try again.')
|
70 |
if os.path.exists(f"fields_{current_user}.parquet"):
|
71 |
gdf = gpd.read_parquet(f"fields_{current_user}.parquet")
|
72 |
edges = gdf['geometry'][0].exterior.coords.xy
|
|
|
76 |
return edges_center
|
77 |
return [15.572363674301132, 32.69167103104079]
|
78 |
|
79 |
+
def display_map_and_drawing_controls(field_map, center_start):
|
80 |
zoom_start = 13
|
81 |
if st.session_state['active_drawing'] is None:
|
82 |
st.info("IMPORTANT: Click on the drawing to confirm the drawn field", icon="π¨")
|
83 |
sat_basemap = utils.basemaps['Google Satellite Hybrid'] # Change this line to use 'Google Satellite Hybrid'
|
84 |
+
sat_basemap.add_to(field_map)
|
85 |
+
folium.LayerControl().add_to(field_map)
|
86 |
+
output = st_folium(field_map, center=center_start, zoom=zoom_start, key="new", width=800)
|
87 |
active_drawing = output['last_active_drawing']
|
88 |
st.session_state['active_drawing'] = active_drawing
|
89 |
return False
|
|
|
162 |
if geom1.overlaps(geom2).any():
|
163 |
st.warning("Field intersects with existing fields. Please draw again!")
|
164 |
with st.expander("Intersecting Fields", expanded=False):
|
165 |
+
field_map = geom1.explore(name= "New Field", color="red")
|
166 |
+
field_map = gdf.explore(m=field_map, name="Existing Fields", color="blue")
|
167 |
+
st_folium(field_map)
|
168 |
return True
|
169 |
return False
|
170 |
|
|
|
173 |
def check_polygon_area_within_range(active_drawing, min_area_km2=1, max_area_km2=10):
|
174 |
if active_drawing is None:
|
175 |
return
|
176 |
+
transformer = Transformer.from_crs("EPSG:4326", "EPSG:6933", always_xy=True)
|
177 |
+
|
178 |
edges = [[i[0], i[1]] for i in active_drawing['geometry']['coordinates'][0]]
|
179 |
geom = Polygon(edges)
|
180 |
+
transformed_geom = transform(transformer.transform, geom)
|
181 |
+
|
182 |
+
|
183 |
+
area_km2 = transformed_geom.area / 10**6
|
184 |
+
|
185 |
+
if area_km2 < min_area_km2:
|
186 |
+
st.warning(f"Field area {area_km2} is less than {min_area_km2} km2. Please draw again!")
|
|
|
|
|
187 |
return False
|
188 |
+
if area_km2 > max_area_km2:
|
189 |
+
st.warning(f"Field area {TRUNC(area_km2,3)} is more than {max_area_km2} km2. Please draw again!")
|
190 |
return False
|
191 |
+
st.success(f"Field area is {TRUNC(area_km2,3} km2, now give it a unique name {st.session_state['current_user']} !")
|
192 |
+
|
193 |
return True
|
194 |
|
195 |
|
|
|
198 |
current_user = greeting("Drag and Zoom and draw your fields on the map, make sure to name them uniquely")
|
199 |
current_user = st.session_state['current_user']
|
200 |
display_existing_fields(current_user)
|
|
|
201 |
center_start = get_center_of_existing_fields(current_user)
|
202 |
zoom_start = 13
|
203 |
+
field_map = folium.Map(location=center_start, zoom_start=zoom_start)
|
204 |
+
|
205 |
|
206 |
draw_options = {'polyline': False, 'polygon': True, 'rectangle': True, 'circle': False, 'marker': False, 'circlemarker': False}
|
207 |
+
Draw(export=True, draw_options=draw_options).add_to(field_map)
|
208 |
+
field_map = add_existing_fields_to_map(field_map, current_user)
|
209 |
|
210 |
|
211 |
|
212 |
+
captured = display_map_and_drawing_controls(field_map, center_start)
|
213 |
if captured:
|
214 |
intersects = check_intersection_with_existing_fields(st.session_state['active_drawing'], current_user)
|
215 |
within_area = check_polygon_area_within_range(st.session_state['active_drawing'])
|