geolocator / app.py
latterworks's picture
Update app.py
ab01573 verified
import gradio as gr
from openai import OpenAI
import base64
from PIL import Image
import io
import json
import requests
class AdvancedGeolocator:
"""
Advanced Image-Based Geolocation System
Utilizes OpenAI's GPT-4o vision capabilities to perform precise
geographical inference from uploaded images.
"""
def __init__(self):
"""
Initialize the Geolocation System
"""
self.max_image_size = (1024, 1024) # Maximum image dimensions
self.supported_image_formats = ['JPEG', 'PNG', 'WebP']
def _preprocess_image(self, image):
"""
Preprocess the input image for analysis.
Args:
image (PIL.Image): Input image
Returns:
str: Base64 encoded image
"""
# Validate image
if image is None:
raise ValueError("No image uploaded")
# Validate image format
if image.format not in self.supported_image_formats:
raise ValueError(f"Unsupported image format. Supported formats: {', '.join(self.supported_image_formats)}")
# Resize large images while maintaining aspect ratio
image.thumbnail(self.max_image_size)
# Convert to JPEG to ensure compatibility
img_byte_arr = io.BytesIO()
image.convert('RGB').save(img_byte_arr, format='JPEG')
img_byte_arr = img_byte_arr.getvalue()
return base64.b64encode(img_byte_arr).decode('utf-8')
def geolocate_image(self, api_key, image):
"""
Analyze image to extract geolocation information.
Args:
api_key (str): OpenAI API key
image (PIL.Image): Image to analyze
Returns:
str: HTML with location details and map
"""
# Validate inputs
if not api_key:
return "Error: Please provide a valid OpenAI API key"
try:
# Preprocess image
base64_image = self._preprocess_image(image)
# Initialize OpenAI client
client = OpenAI(api_key=api_key)
# Generate location analysis
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "You are GeoLogic, an advanced AI geolocation analysis system. "
"Carefully analyze the image to identify its precise geographic location. "
"Provide accurate coordinates and detailed context."
},
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
},
{
"type": "text",
"text": "Identify the exact location of this image with precise coordinates"
}
]
}
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "LocationAnalysisResponse",
"strict": True,
"schema": {
"type": "object",
"properties": {
"coordinates": {
"type": "object",
"properties": {
"latitude": {"type": "number"},
"longitude": {"type": "number"}
},
"required": ["latitude", "longitude"]
},
"location_description": {
"type": "string",
"description": "Detailed description of the location"
}
},
"required": ["coordinates"],
"additionalProperties": False
}
}
},
temperature=0,
max_tokens=2048
)
# Parse response
result = json.loads(response.choices[0].message.content)
coords = result.get('coordinates', {})
lat = coords.get('latitude', 0)
lon = coords.get('longitude', 0)
# Create interactive map HTML
map_html = self._generate_location_map(lat, lon)
return map_html
except ValueError as ve:
return f"Input Error: {str(ve)}"
except Exception as e:
return f"Analysis Error: {str(e)}"
def _generate_location_map(self, lat, lon):
"""
Generate an interactive location map with context.
Args:
lat (float): Latitude
lon (float): Longitude
Returns:
str: HTML with interactive map and location details
"""
map_html = f"""
<div style="text-align: center; font-family: Arial, sans-serif;">
<h3>Location Analysis</h3>
<p><strong>Coordinates:</strong> {lat:.4f}, {lon:.4f}</p>
<iframe
width="100%"
height="450"
frameborder="0"
scrolling="no"
marginheight="0"
marginwidth="0"
src="https://www.openstreetmap.org/export/embed.html?bbox={lon-0.05}%2C{lat-0.05}%2C{lon+0.05}%2C{lat+0.05}&amp;layer=mapnik&amp;marker={lat}%2C{lon}">
</iframe>
<p>
<a href="https://www.openstreetmap.org/?mlat={lat}&mlon={lon}&zoom=12"
target="_blank"
style="text-decoration: none; background-color: #4CAF50; color: white; padding: 10px 15px; border-radius: 5px;">
View Larger Map
</a>
</p>
</div>
"""
return map_html
def create_geolocator_interface():
"""
Create Gradio interface for the Advanced Geolocator.
Returns:
gr.Interface: Configured Gradio interface
"""
geolocator = AdvancedGeolocator()
return gr.Interface(
fn=geolocator.geolocate_image,
inputs=[
gr.Textbox(
label="OpenAI API Key",
placeholder="Enter your OpenAI API key",
type="password"
),
gr.Image(
label="Upload Image",
type="pil",
description="Upload an image for geolocation analysis"
)
],
outputs=gr.HTML(label="Location Results"),
title="Advanced GeoLocator",
description="Analyze images to identify precise geographic locations using AI"
)
def main():
"""
Launch the Geolocator application.
"""
interface = create_geolocator_interface()
interface.launch()
if __name__ == "__main__":
main()