Spaces:
Running
Running
import gradio as gr | |
import requests | |
import folium | |
from folium import plugins | |
import io | |
from PIL import Image | |
import base64 | |
import json | |
import tempfile | |
import os | |
# Function to get location coordinates using Nominatim (OpenStreetMap) | |
def get_location_coordinates(location_name): | |
try: | |
# Add Pakistan context to improve search results | |
search_query = f"{location_name}, Pakistan" | |
url = f"https://nominatim.openstreetmap.org/search?format=json&q={search_query}" | |
headers = {'User-Agent': 'LocationApp/1.0'} | |
response = requests.get(url, headers=headers) | |
data = response.json() | |
if data: | |
first_result = data[0] | |
return { | |
'lat': float(first_result['lat']), | |
'lon': float(first_result['lon']), | |
'display_name': first_result['display_name'], | |
'success': True | |
} | |
return {'success': False, 'error': 'Location not found in Pakistan'} | |
except Exception as e: | |
return {'success': False, 'error': str(e)} | |
# Function to create a static map image using OpenStreetMap | |
def create_static_map_image(lat, lon, zoom=15, width=600, height=400): | |
try: | |
# Use OpenStreetMap static map (alternative approach) | |
# We'll use a tile server to get a map image | |
zoom_level = min(18, max(0, zoom)) | |
# Get a map tile for the coordinates | |
tile_url = f"https://tile.openstreetmap.org/{zoom_level}/{int((lon + 180) / 360 * (2 ** zoom_level))}/{int((1 - math.log(math.tan(math.radians(lat)) + 1 / math.cos(math.radians(lat))) / math.pi) / 2 * (2 ** zoom_level))}.png" | |
response = requests.get(tile_url) | |
if response.status_code == 200: | |
img = Image.open(io.BytesIO(response.content)) | |
# Convert to base64 | |
buffered = io.BytesIO() | |
img.save(buffered, format="PNG") | |
img_str = base64.b64encode(buffered.getvalue()).decode() | |
return f"data:image/png;base64,{img_str}" | |
# Fallback: Use static map service | |
static_map_url = f"https://static-maps.yandex.ru/1.x/?ll={lon},{lat}&z={zoom}&size={width},{height}&l=map" | |
response = requests.get(static_map_url) | |
if response.status_code == 200: | |
img = Image.open(io.BytesIO(response.content)) | |
buffered = io.BytesIO() | |
img.save(buffered, format="PNG") | |
img_str = base64.b64encode(buffered.getvalue()).decode() | |
return f"data:image/png;base64,{img_str}" | |
return None | |
except Exception as e: | |
print(f"Error creating static map: {e}") | |
return None | |
# Simplified static map using a service that works | |
def get_simple_static_map(lat, lon, zoom=15, width=600, height=400): | |
try: | |
# Use a reliable static map service | |
url = f"https://maps.googleapis.com/maps/api/staticmap?center={lat},{lon}&zoom={zoom}&size={width}x{height}&maptype=roadmap&markers=color:red%7C{lat},{lon}" | |
# For demo purposes, we'll use a placeholder since Google Maps requires API key | |
# Create a simple placeholder image with coordinates | |
from PIL import Image, ImageDraw, ImageFont | |
import math | |
# Create a blank image | |
img = Image.new('RGB', (width, height), color='lightblue') | |
draw = ImageDraw.Draw(img) | |
# Add text with coordinates | |
try: | |
font = ImageFont.load_default() | |
text = f"Location: {lat:.4f}, {lon:.4f}\nZoom: {zoom}" | |
draw.text((10, 10), text, fill='black', font=font) | |
except: | |
draw.text((10, 10), f"Coordinates: {lat:.4f}, {lon:.4f}", fill='black') | |
# Draw a simple marker | |
center_x, center_y = width // 2, height // 2 | |
draw.ellipse([center_x-10, center_y-10, center_x+10, center_y+10], fill='red') | |
# Convert to base64 | |
buffered = io.BytesIO() | |
img.save(buffered, format="PNG") | |
img_str = base64.b64encode(buffered.getvalue()).decode() | |
return f"data:image/png;base64,{img_str}" | |
except Exception as e: | |
print(f"Error creating simple map: {e}") | |
return None | |
# Main function to handle location search | |
def search_location(location_query, map_zoom): | |
if not location_query.strip(): | |
return "Please enter a location name", None, None, None | |
# Get coordinates | |
result = get_location_coordinates(location_query) | |
if not result['success']: | |
return f"Error: {result.get('error', 'Unknown error')}", None, None, None | |
lat, lon = result['lat'], result['lon'] | |
display_name = result['display_name'] | |
# Create simple static map image | |
map_image = get_simple_static_map(lat, lon, map_zoom) | |
if map_image: | |
# Prepare location info | |
info_text = f""" | |
**π Location Found in Pakistan:** | |
- **Name:** {display_name} | |
- **Coordinates:** {lat:.6f}, {lon:.6f} | |
- **Latitude:** {lat:.6f} | |
- **Longitude:** {lon:.6f} | |
**πΊοΈ Map View:** | |
- Static map view of the location | |
- Zoom level: {map_zoom} | |
""" | |
# Additional services links | |
services_html = f""" | |
<div style="margin-top: 20px; padding: 10px; background: #f0f8ff; border-radius: 8px; border: 2px solid #007bff;"> | |
<h4>π Open in other services:</h4> | |
<p style="margin: 10px 0;"> | |
<a href="https://www.google.com/maps?q={lat},{lon}" target="_blank" style="color: #007bff; text-decoration: none; font-weight: bold;">π Google Maps</a> | | |
<a href="https://www.openstreetmap.org/#map={map_zoom}/{lat}/{lon}" target="_blank" style="color: #007bff; text-decoration: none; font-weight: bold;">πΊοΈ OpenStreetMap</a> | | |
<a href="https://maps.apple.com/?q={lat},{lon}" target="_blank" style="color: #007bff; text-decoration: none; font-weight: bold;">π Apple Maps</a> | |
</p> | |
</div> | |
""" | |
return info_text, map_image, services_html, f"{lat},{lon}" | |
return "Error creating map. Please try again.", None, None, None | |
# Function to get nearby places information | |
def get_nearby_places(coordinates): | |
if not coordinates: | |
return "No coordinates available. Please search for a location first." | |
try: | |
lat, lon = map(float, coordinates.split(',')) | |
# Simulate nearby places for demo | |
places = [ | |
"β’ Local Mosque (place of worship)", | |
"β’ Restaurant (food)", | |
"β’ Market (shopping)", | |
"β’ Park (recreation)", | |
"β’ School (education)", | |
"β’ Hospital (healthcare)" | |
] | |
return "**πͺ Nearby Places (simulated):**\n" + "\n".join(places) | |
except Exception as e: | |
return f"Error: {str(e)}" | |
# Gradio interface with Pakistan theme | |
with gr.Blocks(title="Pakistan Location Finder", theme="soft") as demo: | |
gr.Markdown("# π΅π° Pakistan Location Finder") | |
gr.Markdown("Discover and explore locations across Pakistan!") | |
with gr.Row(): | |
with gr.Column(scale=3): | |
location_input = gr.Textbox( | |
label="Enter location in Pakistan", | |
placeholder="e.g., Faisal Mosque, Islamabad", | |
lines=1 | |
) | |
zoom_slider = gr.Slider( | |
minimum=10, | |
maximum=20, | |
value=15, | |
step=1, | |
label="Map Zoom Level" | |
) | |
search_btn = gr.Button("π Search Location", variant="primary") | |
with gr.Accordion("Explore Nearby", open=False): | |
gr.Markdown("### Discover nearby places") | |
nearby_btn = gr.Button("Find Nearby Places") | |
nearby_output = gr.Markdown(label="Nearby Places") | |
with gr.Column(scale=7): | |
output_info = gr.Markdown(label="Location Information") | |
map_output = gr.Image( | |
label="Location Map", | |
interactive=False, | |
height=400 | |
) | |
services_output = gr.HTML() | |
coordinates_output = gr.Textbox(visible=False) | |
# Set up event handlers | |
search_btn.click( | |
fn=search_location, | |
inputs=[location_input, zoom_slider], | |
outputs=[output_info, map_output, services_output, coordinates_output] | |
) | |
# Handle nearby places search | |
nearby_btn.click( | |
fn=get_nearby_places, | |
inputs=[coordinates_output], | |
outputs=[nearby_output] | |
) | |
# Example locations in Pakistan | |
gr.Examples( | |
examples=[ | |
["Faisal Mosque Islamabad"], | |
["Badshahi Mosque Lahore"], | |
["Mazar e Quaid Karachi"], | |
["Hunza Valley"], | |
["Lahore Fort"], | |
["Islamabad"] | |
], | |
inputs=location_input, | |
label="π΅π° Popular Pakistan Locations" | |
) | |
gr.Markdown(""" | |
### π How to use: | |
1. Enter any location name in Pakistan | |
2. Adjust the zoom level if needed | |
3. Click "Search Location" to find and view the location | |
4. Use "Find Nearby Places" to discover amenities around the location | |
### π― Features: | |
- Search any location in Pakistan | |
- View coordinates and address information | |
- Simple map visualization | |
- Discover nearby places | |
- Quick links to open in other mapping services | |
*Note: Uses OpenStreetMap data for location information* | |
""") | |
# Run the app | |
if __name__ == "__main__": | |
demo.launch(share=True, server_name="0.0.0.0") |