modified: app.py

new file:   static/styles.css
	modified:   templates/index.html
This commit is contained in:
SimolZimol
2024-09-09 11:34:25 +02:00
parent 4a3d98be11
commit 1917109990
3 changed files with 69 additions and 46 deletions

47
app.py
View File

@@ -1,59 +1,52 @@
from flask import Flask, jsonify, request, render_template
from wetterdienst.provider.dwd.forecast import DWDForecastRequest
from wetterdienst.provider.dwd.metadata import DWDStationParameter
from wetterdienst.provider.dwd.metadata.resolution import Resolution
from wetterdienst.provider.dwd.observation import DwdObservationRequest, DwdObservationResolution
from wetterdienst.util.geo import Coordinates
from geopy.geocoders import Nominatim
import os
from datetime import datetime, timedelta
app = Flask(__name__, static_folder='static', template_folder='templates')
# Funktion, um die Koordinaten anhand eines Ortsnamens oder einer PLZ zu erhalten
# Function to get coordinates based on the user location
def get_coordinates(location):
geolocator = Nominatim(user_agent="wetterdienst")
geolocator = Nominatim(user_agent="wetterdienst_app")
location = geolocator.geocode(location)
if location:
return Coordinates(location.latitude, location.longitude)
return None
# Funktion, um Wetterdaten von der DWD-API basierend auf den Koordinaten zu erhalten
# Function to get weather data from DWD API
def get_weather_data(location):
coords = get_coordinates(location)
if not coords:
return {"error": "Ort nicht gefunden."}
return {"error": "Location not found."}
# DWD-Anfrage für die nächsten 10 Tage
request = DWDForecastRequest(
parameter=[DWDStationParameter.TEMPERATURE_AIR_MEAN_200, DWDStationParameter.WIND_SPEED, DWDStationParameter.PRECIPITATION_HEIGHT],
resolution=Resolution.HOURLY,
coordinates=coords
request = DwdObservationRequest(
parameter=["temperature_air_mean_200", "precipitation_height", "wind_speed"],
resolution=DwdObservationResolution.HOURLY,
start_date=(datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d"),
end_date=(datetime.now() + timedelta(days=10)).strftime("%Y-%m-%d")
)
forecast = request.values.all().df
stations = request.filter_by_distance(latlon=(coords.latitude, coords.longitude), distance=30)
values = stations.values.all().df
weather_data = []
for _, row in forecast.iterrows():
weather_data.append({
"date": row["datetime"].strftime("%Y-%m-%d"),
"temperature": row["temperature_air_mean_200"],
"wind_speed": row["wind_speed"],
"precipitation": row["precipitation_height"],
"cloud_cover": row.get("cloud_cover", 0) # Wenn nicht verfügbar, setze auf 0
})
if values.empty:
return {"error": "No data available for the selected location."}
weather_data = values.to_dict(orient='records')
return weather_data
# Route für die Startseite
# Route for rendering the HTML frontend
@app.route('/')
def index():
return render_template('index.html')
# API für die Wetterdaten
@app.route('/api/weather')
# API endpoint for fetching weather data based on user input
@app.route('/api/weather', methods=['GET'])
def weather():
location = request.args.get('location')
if not location:
return jsonify({"error": "Ort nicht angegeben."}), 400
return jsonify({"error": "Please provide a location."}), 400
data = get_weather_data(location)
if "error" in data:

27
static/styles.css Normal file
View File

@@ -0,0 +1,27 @@
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f0f8ff;
}
h1 {
margin-top: 20px;
}
.location-input {
margin: 20px;
}
.weather-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.weather-day {
border: 1px solid #ccc;
background-color: #fff;
margin: 10px;
padding: 15px;
width: 200px;
}

View File

@@ -1,48 +1,51 @@
<!DOCTYPE html>
<html lang="de">
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wettervorhersage</title>
<title>Weather Forecast</title>
<link rel="stylesheet" href="/static/styles.css">
</head>
<body>
<h1>Wettervorhersage für 10 Tage</h1>
<!-- Eingabefeld für den Ort -->
<h1>10-Day Weather Forecast</h1>
<!-- Input for location -->
<div class="location-input">
<label for="location">Geben Sie einen Ort ein:</label>
<input type="text" id="location" placeholder="Stadt oder PLZ">
<button onclick="loadWeatherData()">Wetter anzeigen</button>
<label for="location">Enter a location (city or coordinates):</label>
<input type="text" id="location" placeholder="City or coordinates">
<button onclick="loadWeatherData()">Get Weather</button>
</div>
<!-- Wetteranzeige -->
<!-- Weather display -->
<div class="weather-container" id="weather-container"></div>
<script>
async function loadWeatherData() {
const location = document.getElementById('location').value;
if (!location) {
alert('Bitte geben Sie einen Ort ein!');
alert('Please provide a location.');
return;
}
// Fetch Wetterdaten basierend auf dem eingegebenen Ort
const response = await fetch(`/api/weather?location=${location}`);
const data = await response.json();
// Wetterdaten in der HTML anzeigen
const container = document.getElementById('weather-container');
container.innerHTML = ''; // Vorherige Daten löschen
container.innerHTML = ''; // Clear previous data
if (data.error) {
container.innerHTML = `<p>Error: ${data.error}</p>`;
return;
}
data.forEach(day => {
const dayDiv = document.createElement('div');
dayDiv.className = 'weather-day';
dayDiv.innerHTML = `
<h3>${day.date}</h3>
<p>Temperatur: ${day.temperature}°C</p>
<p>Wind: ${day.wind_speed} km/h</p>
<p>Niederschlag: ${day.precipitation} mm</p>
<p>Wolken: ${day.cloud_cover}%</p>
<h3>Date: ${day.date}</h3>
<p>Temperature: ${day.temperature_air_mean_200} °C</p>
<p>Precipitation: ${day.precipitation_height} mm</p>
<p>Wind Speed: ${day.wind_speed} km/h</p>
`;
container.appendChild(dayDiv);
});