|
import os
|
|
import json
|
|
import requests
|
|
from flask import Flask, request, jsonify, send_from_directory
|
|
from flask_cors import CORS
|
|
|
|
# Configure Flask app
|
|
app = Flask(__name__, static_folder='.')
|
|
CORS(app) # Enable CORS for all origins
|
|
|
|
# --- Open-Meteo API Configuration ---
|
|
OPENMETEO_BASE_URL = "https://api.open-meteo.com/v1/forecast"
|
|
|
|
WEATHER_VARIABLES = [
|
|
"temperature_2m",
|
|
"relative_humidity_2m",
|
|
"precipitation",
|
|
"weathercode",
|
|
"windspeed_10m",
|
|
"windgusts_10m",
|
|
"pressure_msl"
|
|
]
|
|
|
|
DAILY_VARIABLES = [
|
|
"precipitation_sum",
|
|
"temperature_2m_max",
|
|
"temperature_2m_min"
|
|
]
|
|
|
|
# --- Data Fetching Functions ---
|
|
|
|
def get_weather_data(lat, lon):
|
|
"""Fetches current and recent weather data from Open-Meteo."""
|
|
try:
|
|
params = {
|
|
"latitude": lat,
|
|
"longitude": lon,
|
|
"current": ",".join(WEATHER_VARIABLES),
|
|
"daily": ",".join(DAILY_VARIABLES),
|
|
"past_days": 1,
|
|
"timezone": "auto",
|
|
"forecast_days": 1
|
|
}
|
|
print(f"Fetching weather data for ({lat}, {lon})...")
|
|
response = requests.get(OPENMETEO_BASE_URL, params=params)
|
|
response.raise_for_status() # Raise an HTTPError for bad responses
|
|
data = response.json()
|
|
print("Weather data fetched successfully.")
|
|
|
|
current = data.get('current', {})
|
|
daily = data.get('daily', {})
|
|
|
|
weather_info = {
|
|
"source": "Open-Meteo API",
|
|
"latitude": data.get('latitude'),
|
|
"longitude": data.get('longitude'),
|
|
"temperature_celsius_current": current.get('temperature_2m'),
|
|
"temperature_celsius_max_daily": daily.get('temperature_2m_max', [None])[0],
|
|
"temperature_celsius_min_daily": daily.get('temperature_2m_min', [None])[0],
|
|
"humidity_percent_current": current.get('relative_humidity_2m'),
|
|
"precipitation_mm_current": current.get('precipitation'),
|
|
"precipitation_mm_past_24h": daily.get('precipitation_sum', [None])[0],
|
|
"windspeed_kmh_current": current.get('windspeed_10m'),
|
|
"windgusts_kmh_current": current.get('windgusts_10m'),
|
|
"pressure_hpa_current": current.get('pressure_msl'),
|
|
"weathercode_current": current.get('weathercode')
|
|
}
|
|
return weather_info
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
print(f"Error fetching weather data: {e}")
|
|
return {"error": "Could not fetch weather data", "details": str(e)}
|
|
except Exception as e:
|
|
print(f"An unexpected error occurred while processing weather data: {e}")
|
|
return {"error": "An unexpected error occurred with weather data", "details": str(e)}
|
|
|
|
|
|
def get_non_weather_data_simulated(lat, lon):
|
|
"""
|
|
Simulates getting non-weather data.
|
|
This is still simplified based on rough India geography.
|
|
"""
|
|
lat = float(lat)
|
|
lon = float(lon)
|
|
|
|
data = {
|
|
"source": "Simulated/Inferred Data",
|
|
"latitude": lat,
|
|
"longitude": lon,
|
|
"elevation_meters": 50, # Base elevation
|
|
"proximity_to_coast_km": 800, # Base distance
|
|
"proximity_to_major_river_km": 200, # Base distance
|
|
"soil_type": "general",
|
|
"vegetation_density": "moderate",
|
|
"historical_disaster_frequency": "medium",
|
|
"population_density": "moderate"
|
|
}
|
|
|
|
# Adjust simulated data based on location approximations for India
|
|
if 8 <= lat <= 37 and 68 <= lon <= 97: # Basic India bounds
|
|
if lat > 28 or lon > 90: # Himalayan region, North East
|
|
data["elevation_meters"] = 1500 + max(0, lat - 28)*100 + max(0, lon - 90)*50
|
|
data["soil_type"] = "mountainous/hilly"
|
|
data["vegetation_density"] = "high"
|
|
data["historical_disaster_frequency"] = "high (Landslides, Earthquakes, Floods)"
|
|
data["proximity_to_major_river_km"] = min(data["proximity_to_major_river_km"], 10) if lat > 28 else data["proximity_to_major_river_km"]
|
|
|
|
|
|
if 15 <= lat <= 25 and 70 <= lon <= 85: # Central India, Deccan
|
|
data["elevation_meters"] = 500 + max(0, lat - 15)*30
|
|
data["soil_type"] = "black soil/plateau"
|
|
data["vegetation_density"] = "moderate to low"
|
|
data["historical_disaster_frequency"] = "medium (Droughts, Heatwaves, Wildfires)"
|
|
data["population_density"] = "moderate to high"
|
|
|
|
if lat < 22 and lon > 75: # South India, Coastal East/West
|
|
east_coast_dist = abs(lon - 82) * 111
|
|
west_coast_dist = abs(lon - 74) * 111
|
|
data["proximity_to_coast_km"] = min(east_coast_dist, west_coast_dist, data["proximity_to_coast_km"])
|
|
data["elevation_meters"] = 50 + max(0, (22-lat)*10)
|
|
data["soil_type"] = "coastal alluvial/laterite"
|
|
data["historical_disaster_frequency"] = "high (Cyclones, Floods, Heatwaves)"
|
|
data["population_density"] = "high"
|
|
|
|
|
|
if lat > 25 and lon < 80: # North India, Gangetic plains
|
|
data["elevation_meters"] = 50 + max(0, lat-25)*10
|
|
data["proximity_to_major_river_km"] = min(data["proximity_to_major_river_km"], 5)
|
|
data["soil_type"] = "alluvial"
|
|
data["historical_disaster_frequency"] = "high (Floods, Heatwaves, Droughts)"
|
|
data["population_density"] = "very high"
|
|
|
|
# Add some minor random variation
|
|
import random
|
|
data["elevation_meters"] = max(0, data["elevation_meters"] + random.randint(-10, 10))
|
|
data["proximity_to_coast_km"] = max(0, data["proximity_to_coast_km"] + random.randint(-20, 20))
|
|
data["proximity_to_major_river_km"] = max(0, data["proximity_to_major_river_km"] + random.randint(-5, 5))
|
|
|
|
return data
|
|
|
|
# --- Flask Routes ---
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return send_from_directory('.', 'index.html')
|
|
|
|
# API endpoint to get location-based data (weather + simulated)
|
|
@app.route('/get_location_data', methods=['POST'])
|
|
def get_location_data():
|
|
data = request.get_json()
|
|
lat = data.get('lat')
|
|
lon = data.get('lon')
|
|
|
|
if lat is None or lon is None:
|
|
return jsonify({"error": "Latitude and Longitude are required"}), 400
|
|
|
|
try:
|
|
# Get real weather data
|
|
weather_data = get_weather_data(lat, lon)
|
|
if "error" in weather_data:
|
|
# If weather data fetch fails, return the error
|
|
return jsonify({"error": f"Failed to get weather data: {weather_data['details']}"}), 500
|
|
|
|
# Get simulated non-weather data
|
|
non_weather_data = get_non_weather_data_simulated(lat, lon)
|
|
|
|
# Combine all data
|
|
location_data = {
|
|
"latitude": lat,
|
|
"longitude": lon,
|
|
"weather_data": weather_data,
|
|
"non_weather_data": non_weather_data
|
|
}
|
|
|
|
# Return the combined data
|
|
return jsonify(location_data)
|
|
|
|
except Exception as e:
|
|
print(f"An error occurred while getting location data: {e}")
|
|
return jsonify({"error": f"An internal server error occurred: {str(e)}"}), 500
|
|
|
|
if __name__ == '__main__':
|
|
# Run the Flask app
|
|
# Change port if 5000 is in use
|
|
app.run(debug=True, port=5000) |