Last active
September 8, 2024 07:19
-
-
Save amupoti/5284c389405fd36dfc3b7338f2c9efcb to your computer and use it in GitHub Desktop.
Get total rain for a location given 3 different stations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from lxml import html | |
import re | |
from datetime import datetime, timedelta | |
from math import radians, sin, cos, sqrt, atan2 | |
# Function to calculate distance between two GPS coordinates (Haversine formula) | |
def haversine(lat1, lon1, lat2, lon2): | |
R = 6371.0 # Earth radius in kilometers | |
lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2]) | |
dlat = lat2 - lat1 | |
dlon = lon2 - lon1 | |
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 | |
c = 2 * atan2(sqrt(a), sqrt(1 - a)) | |
distance = R * c | |
return distance | |
# Function to get the precipitation value for a date and location | |
def get_precipitation(url): | |
response = requests.get(url) | |
if response.status_code == 200: | |
tree = html.fromstring(response.content) | |
precipitation_value = tree.xpath('//*[@id="resum-diari"]/div/table/tbody/tr[5]/td/text()') | |
if precipitation_value: | |
try: | |
# Extract and return the numeric value | |
return float(re.findall(r'\d+\.\d+', precipitation_value[0])[0]) | |
except IndexError: | |
print(f"Error extracting value from URL: {url}") | |
return 0.0 | |
else: | |
print(f"Error in GET request: {response.status_code} for URL: {url}") | |
return 0.0 | |
# Coordinates of stations and El Catllar | |
stations = { | |
"Torredembarra": {"coords": (41.145, 1.402), "code": "DK"}, | |
"Nulles": {"coords": (41.263, 1.327), "code": "VY"}, | |
"Tarragona": {"coords": (41.118, 1.244), "code": "XE"} | |
} | |
el_catllar_coords = (41.222, 1.346) | |
# Generate URLs for each day of the last six weeks | |
url_base = "https://www.meteo.cat/observacions/xema/dades?codi=" | |
num_weeks = 6 | |
days_per_week = 7 | |
# Function to generate URLs for a specific location | |
def generate_urls_for_location(code): | |
weeks = [[] for _ in range(num_weeks)] | |
for week in range(num_weeks): | |
for day in range(days_per_week): | |
date = (datetime.now() - timedelta(weeks=week, days=day)).strftime('%Y-%m-%dT00:00Z') | |
weeks[week].append(url_base + code + "&dia=" + date) | |
return weeks | |
# Get the accumulated precipitation per week for each station | |
for station_name, station_data in stations.items(): | |
print(f"Processing station: {station_name}") | |
weeks = generate_urls_for_location(station_data["code"]) | |
precipitation_per_week = [] | |
for idx, week in enumerate(weeks): | |
precipitations = [get_precipitation(url) for url in week] | |
precipitation_per_week.append(precipitations) | |
station_data["precipitation_per_week"] = [sum(week) for week in precipitation_per_week] | |
# Calculate distances from El Catllar to each station | |
for station_name, station_data in stations.items(): | |
lat, lon = station_data["coords"] | |
station_data["distance_to_catllar"] = haversine(el_catllar_coords[0], el_catllar_coords[1], lat, lon) | |
# Function to perform Inverse Distance Weighting (IDW) | |
def idw_precipitation(precipitation_values, distances): | |
inv_distances = [1 / d if d != 0 else 0 for d in distances]a | |
weighted_precipitations = [p * inv_d for p, inv_d in zip(precipitation_values, inv_distances)] | |
total_weight = sum(inv_distances) | |
return sum(weighted_precipitations) / total_weight if total_weight > 0 else 0 | |
# Estimate precipitation in El Catllar using IDW | |
precipitation_catllar_per_week = [] | |
for week_idx in range(num_weeks): | |
precipitations = [stations[station]["precipitation_per_week"][week_idx] for station in stations] | |
distances = [stations[station]["distance_to_catllar"] for station in stations] | |
estimated_precipitation = idw_precipitation(precipitations, distances) | |
precipitation_catllar_per_week.append(estimated_precipitation) | |
# Display the estimated rainfall for El Catllar | |
for week_idx, total_precipitation in enumerate(precipitation_catllar_per_week): | |
print(f"Estimated total precipitation {week_idx} week(s) ago for El Catllar: {total_precipitation:.2f} mm") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment