-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpharmascysol.py
226 lines (188 loc) · 7.71 KB
/
pharmascysol.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import streamlit as st
import folium
from streamlit_folium import folium_static
import overpy
from geopy.distance import geodesic
import pandas as pd
# Set page config at the very beginning of the script
st.set_page_config(page_title="Pharmacy Finder", page_icon="🏥")
def get_geolocation():
"""
Get user's geolocation with improved error handling.
Returns:
tuple: (latitude, longitude) or (None, None) if location not available
"""
location = None
# Custom JavaScript for geolocation
location_script = """
<script>
function getStreamlitLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
window.parent.postMessage({
type: 'streamlit:setComponentValue',
key: 'location',
value: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
}
}, '*');
},
(error) => {
window.parent.postMessage({
type: 'streamlit:setComponentValue',
key: 'location',
value: {error: error.message}
}, '*');
},
{
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
}
);
} else {
window.parent.postMessage({
type: 'streamlit:setComponentValue',
key: 'location',
value: {error: "Geolocation is not supported"}
}, '*');
}
}
getStreamlitLocation();
</script>
"""
# Add location script component
location = st.components.v1.html(location_script, height=0)
# Retrieve location data if available
if location:
if isinstance(location, dict) and 'latitude' in location and 'longitude' in location:
return location['latitude'], location['longitude']
if isinstance(location, dict) and 'error' in location:
st.error(f"Location Error: {location['error']}")
return None, None
def find_nearby_pharmacies(latitude, longitude, max_distance=20):
"""
Find pharmacies within a specified distance from a given location.
"""
try:
# Initialize Overpass API
api = overpy.Overpass()
# Construct Overpass query to find pharmacies
query = f"""
[out:json];
(
node["amenity"="pharmacy"](around:{max_distance * 1000},{latitude},{longitude});
way["amenity"="pharmacy"](around:{max_distance * 1000},{latitude},{longitude});
relation["amenity"="pharmacy"](around:{max_distance * 1000},{latitude},{longitude});
);
out center;
"""
# Execute the query
result = api.query(query)
# Store nearby pharmacies
nearby_pharmacies = []
# Process pharmacies
for pharmacy in result.nodes + result.ways + result.relations:
# Get pharmacy location
if hasattr(pharmacy, 'center_lat') and hasattr(pharmacy, 'center_lon'):
pharmacy_lat = pharmacy.center_lat
pharmacy_lon = pharmacy.center_lon
else:
pharmacy_lat = pharmacy.lat
pharmacy_lon = pharmacy.lon
# Calculate distance
distance = geodesic((latitude, longitude), (pharmacy_lat, pharmacy_lon)).kilometers
# Prepare pharmacy details
pharmacy_info = {
'name': pharmacy.tags.get('name', 'Unnamed Pharmacy'),
'address': pharmacy.tags.get('addr:full', 'No address'),
'latitude': pharmacy_lat,
'longitude': pharmacy_lon,
'distance': round(distance, 2)
}
nearby_pharmacies.append(pharmacy_info)
# Sort pharmacies by distance
nearby_pharmacies.sort(key=lambda x: x['distance'])
return nearby_pharmacies
except Exception as e:
st.error(f"Error finding pharmacies: {e}")
return []
def create_map(latitude, longitude, pharmacies):
"""
Create an interactive map with pharmacy markers.
"""
# Create a map centered on the user's location
m = folium.Map(location=[latitude, longitude], zoom_start=12)
# Add marker for user's location
folium.Marker(
[latitude, longitude],
popup='Your Location',
icon=folium.Icon(color='red', icon='home')
).add_to(m)
# Color palette for pharmacy markers
color_palette = ['blue', 'green', 'purple', 'orange', 'darkred', 'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue']
# Add markers for pharmacies
for i, pharmacy in enumerate(pharmacies):
# Cycle through color palette
marker_color = color_palette[i % len(color_palette)]
# Create popup with pharmacy details
popup_text = f"""
<b>{pharmacy['name']}</b><br>
Address: {pharmacy['address']}<br>
Distance: {pharmacy['distance']} km
"""
folium.Marker(
[pharmacy['latitude'], pharmacy['longitude']],
popup=popup_text,
icon=folium.Icon(color=marker_color, icon='medical-cross')
).add_to(m)
return m
def main():
# App title and description
st.title('🏥 Nearby Pharmacies Finder')
st.write('Find pharmacies near your current location')
# Geolocation guidance
st.info("""
🌍 This app needs your location to find nearby pharmacies:
- Please allow location access when prompted
- If location access is denied, you can manually enter coordinates
- Ensure you have a stable internet connection
""")
# Try to get user's location
latitude, longitude = get_geolocation()
# Manual input fallback
if latitude is None or longitude is None:
st.warning("Couldn't retrieve location automatically please enter ur infos of latiitude and lagitude by mylocation website or test on this position im lived on berrechid btw")
col1, col2 = st.columns(2)
with col1:
latitude = st.number_input('Enter Latitude', value=33.0152, format="%.4f")
with col2:
longitude = st.number_input('Enter Longitude', value=-7.6242, format="%.4f")
else:
st.success(f"Location found: {latitude}, {longitude}")
# Search button
if st.button('Find Nearby Pharmacies', key='search_pharmacies'):
try:
# Find pharmacies
pharmacies = find_nearby_pharmacies(latitude, longitude)
# Display results
if pharmacies:
# Pharmacy list
st.subheader('Nearby Pharmacies')
df = pd.DataFrame(pharmacies)
st.dataframe(df[['name', 'address', 'distance']])
# Map visualization
st.subheader('Pharmacy Locations')
map_obj = create_map(latitude, longitude, pharmacies)
folium_static(map_obj)
# Statistics
st.write(f"Total pharmacies found: {len(pharmacies)}")
st.write(f"Closest pharmacy: {pharmacies[0]['name']} ({pharmacies[0]['distance']} km away)")
else:
st.warning('No pharmacies found within 20 km.')
except Exception as e:
st.error(f"An unexpected error occurred: {e}")
if __name__ == "__main__":
main()