modified: app.py
modified: requirements.txt modified: templates/index.html
This commit is contained in:
56
app.py
56
app.py
@@ -1,34 +1,44 @@
|
||||
from flask import Flask, jsonify, request, render_template
|
||||
from wetterdienst.provider.dwd.observation import DWDObservationRequest
|
||||
from wetterdienst.provider.dwd.forecast import DWDForecastRequest
|
||||
from wetterdienst.provider.dwd.metadata import DWDStationParameter
|
||||
from wetterdienst.provider.dwd.metadata.resolution import Resolution
|
||||
from wetterdienst.util.geo import Coordinates
|
||||
from datetime import datetime, timedelta
|
||||
from geopy.geocoders import Nominatim
|
||||
import os
|
||||
|
||||
app = Flask(__name__, static_folder='static', template_folder='templates')
|
||||
|
||||
# Funktion, um die Wetterdaten für eine gegebene Koordinate (Ort) zu erhalten
|
||||
# Funktion, um die Koordinaten anhand eines Ortsnamens oder einer PLZ zu erhalten
|
||||
def get_coordinates(location):
|
||||
geolocator = Nominatim(user_agent="wetterdienst")
|
||||
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
|
||||
def get_weather_data(location):
|
||||
# Simuliere hier die Umwandlung von Ort in Koordinaten oder ID.
|
||||
# In der Realität müsste hier eine Geolokalisierung durchgeführt werden, z.B. mit Nominatim oder einer anderen API.
|
||||
coordinates = Coordinates.from_city(location)
|
||||
coords = get_coordinates(location)
|
||||
if not coords:
|
||||
return {"error": "Ort nicht gefunden."}
|
||||
|
||||
# Die Wetterstationen in der Nähe der gegebenen Koordinaten filtern
|
||||
request = DWDObservationRequest(
|
||||
parameter=["temperature_air_mean_200", "wind_speed", "humidity"],
|
||||
resolution="daily",
|
||||
start_date=datetime.now().strftime("%Y-%m-%d"),
|
||||
end_date=(datetime.now() + timedelta(days=10)).strftime("%Y-%m-%d"),
|
||||
).filter_by_coordinates(latlon=(coordinates.lat, coordinates.lon), distance=50)
|
||||
# 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
|
||||
)
|
||||
|
||||
# Daten abrufen
|
||||
stations = request.values.all().df
|
||||
forecast = request.values.all().df
|
||||
|
||||
weather_data = []
|
||||
for index, row in stations.iterrows():
|
||||
for _, row in forecast.iterrows():
|
||||
weather_data.append({
|
||||
"date": row["date"].strftime("%Y-%m-%d"),
|
||||
"date": row["datetime"].strftime("%Y-%m-%d"),
|
||||
"temperature": row["temperature_air_mean_200"],
|
||||
"wind_speed": row["wind_speed"],
|
||||
"humidity": row["humidity"]
|
||||
"precipitation": row["precipitation_height"],
|
||||
"cloud_cover": row.get("cloud_cover", 0) # Wenn nicht verfügbar, setze auf 0
|
||||
})
|
||||
|
||||
return weather_data
|
||||
@@ -38,11 +48,17 @@ def get_weather_data(location):
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# Route für die Wetter-API, die den Ort verarbeitet
|
||||
# API für die Wetterdaten
|
||||
@app.route('/api/weather')
|
||||
def weather():
|
||||
location = request.args.get('location', default='Berlin', type=str)
|
||||
location = request.args.get('location')
|
||||
if not location:
|
||||
return jsonify({"error": "Ort nicht angegeben."}), 400
|
||||
|
||||
data = get_weather_data(location)
|
||||
if "error" in data:
|
||||
return jsonify(data), 404
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Flask
|
||||
wetterdienst
|
||||
requests
|
||||
requests
|
||||
geopy
|
||||
@@ -4,76 +4,49 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Wettervorhersage</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
form {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
input[type="text"] {
|
||||
padding: 10px;
|
||||
width: 200px;
|
||||
}
|
||||
.weather-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.weather-day {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
width: 300px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/static/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Wettervorhersage für deinen Ort</h1>
|
||||
<form id="location-form">
|
||||
<input type="text" id="location-input" placeholder="Ort oder PLZ eingeben" />
|
||||
<button type="submit">Wetter anzeigen</button>
|
||||
</form>
|
||||
<h1>Wettervorhersage für 10 Tage</h1>
|
||||
|
||||
<!-- Eingabefeld für den Ort -->
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- Wetteranzeige -->
|
||||
<div class="weather-container" id="weather-container"></div>
|
||||
|
||||
<script>
|
||||
async function loadWeatherData(location) {
|
||||
async function loadWeatherData() {
|
||||
const location = document.getElementById('location').value;
|
||||
if (!location) {
|
||||
alert('Bitte geben Sie einen Ort ein!');
|
||||
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 = ''; // Clear previous results
|
||||
|
||||
if (data.length === 0) {
|
||||
container.innerHTML = `<p>Keine Wetterdaten für diesen Ort verfügbar.</p>`;
|
||||
} else {
|
||||
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>Windgeschwindigkeit: ${day.wind_speed} km/h</p>
|
||||
<p>Luftfeuchtigkeit: ${day.humidity}%</p>
|
||||
`;
|
||||
container.appendChild(dayDiv);
|
||||
});
|
||||
}
|
||||
container.innerHTML = ''; // Vorherige Daten löschen
|
||||
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>
|
||||
`;
|
||||
container.appendChild(dayDiv);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('location-form').addEventListener('submit', function(event) {
|
||||
event.preventDefault();
|
||||
const location = document.getElementById('location-input').value;
|
||||
loadWeatherData(location);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user