fix: 天气预测接口更替为开源的 Open-Meteo
- 默认情况下,将结合最适合的天气模型(auto) - 预报 3天长度
This commit is contained in:
parent
d8456d165b
commit
7555c4c72b
@ -1,7 +1,6 @@
|
||||
var WeatherForecast = (function() {
|
||||
'use strict';
|
||||
|
||||
var weatherApiKey = 'Uxh4IdMuAvhSiBnsf4UUDVGF4e3YAp2B';
|
||||
var weatherEnabled = false;
|
||||
var weatherData = null;
|
||||
var currentForecastIndex = 0;
|
||||
@ -81,7 +80,6 @@ var WeatherForecast = (function() {
|
||||
contentElement.innerHTML =
|
||||
'<div class="weather-loading">' +
|
||||
'<i class="layui-icon layui-icon-loading layui-icon-anim-rotate"></i>' +
|
||||
'<p>请确保网络可访问 Windy API 服务</p>' +
|
||||
'<p>正在获取天气预测数据...</p>' +
|
||||
'</div>';
|
||||
}
|
||||
@ -140,23 +138,19 @@ var WeatherForecast = (function() {
|
||||
}
|
||||
|
||||
function fetchWeatherData(lat, lon) {
|
||||
var requestBody = {
|
||||
"lat": parseFloat(lat.toFixed(2)),
|
||||
"lon": parseFloat(lon.toFixed(2)),
|
||||
"model": "gfs",
|
||||
"parameters": ["temp", "wind", "precip", "pressure", "rh", "windGust"],
|
||||
"levels": ["surface"],
|
||||
"key": weatherApiKey,
|
||||
"hours": 72
|
||||
};
|
||||
var url = 'https://api.open-meteo.com/v1/forecast?' +
|
||||
'latitude=' + lat.toFixed(4) +
|
||||
'&longitude=' + lon.toFixed(4) +
|
||||
'¤t=temperature_2m,wind_speed_10m,wind_direction_10m,relative_humidity_2m,surface_pressure' +
|
||||
'&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m,wind_direction_10m,precipitation,surface_pressure,wind_gusts_10m' +
|
||||
'&forecast_days=3' +
|
||||
'&timezone=auto';
|
||||
|
||||
fetch('https://api.windy.com/api/point-forecast/v2', {
|
||||
method: 'POST',
|
||||
fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(requestBody)
|
||||
}
|
||||
})
|
||||
.then(function(response) {
|
||||
if (!response.ok) {
|
||||
@ -165,7 +159,7 @@ var WeatherForecast = (function() {
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data) {
|
||||
weatherData = data;
|
||||
weatherData = transformOpenMeteoData(data);
|
||||
|
||||
var currentTime = new Date().getTime();
|
||||
var closestIndex = 0;
|
||||
@ -203,6 +197,40 @@ var WeatherForecast = (function() {
|
||||
});
|
||||
}
|
||||
|
||||
function transformOpenMeteoData(data) {
|
||||
var transformed = {
|
||||
ts: [],
|
||||
'temp-surface': [],
|
||||
'wind-speed': [],
|
||||
'wind-direction': [],
|
||||
'precipitation': [],
|
||||
'rh-surface': [],
|
||||
'pressure-surface': [],
|
||||
'gust-surface': []
|
||||
};
|
||||
|
||||
if (!data.hourly || !data.hourly.time) {
|
||||
return transformed;
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.hourly.time.length; i++) {
|
||||
transformed.ts.push(new Date(data.hourly.time[i]).getTime());
|
||||
|
||||
transformed['temp-surface'].push(data.hourly.temperature_2m[i]);
|
||||
|
||||
var windSpeedMs = data.hourly.wind_speed_10m[i] ? data.hourly.wind_speed_10m[i] / 3.6 : null;
|
||||
transformed['wind-speed'].push(windSpeedMs);
|
||||
transformed['wind-direction'].push(data.hourly.wind_direction_10m[i]);
|
||||
transformed['precipitation'].push(data.hourly.precipitation[i]);
|
||||
transformed['rh-surface'].push(data.hourly.relative_humidity_2m[i]);
|
||||
transformed['pressure-surface'].push(data.hourly.surface_pressure[i]);
|
||||
var gustMs = data.hourly.wind_gusts_10m[i] ? data.hourly.wind_gusts_10m[i] / 3.6 : null;
|
||||
transformed['gust-surface'].push(gustMs);
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
|
||||
function displayCurrentForecast() {
|
||||
if (!weatherData || !weatherData.ts || weatherData.ts.length === 0) {
|
||||
displayWeatherError('无可用的天气预测数据');
|
||||
@ -213,22 +241,22 @@ var WeatherForecast = (function() {
|
||||
var forecastHtml = '<div class="weather-forecast-item"><div class="weather-param-grid">';
|
||||
|
||||
if (weatherData['temp-surface'] && weatherData['temp-surface'][i] !== null) {
|
||||
var temp = (weatherData['temp-surface'][i] - 273.15).toFixed(1);
|
||||
var temp = weatherData['temp-surface'][i].toFixed(1);
|
||||
forecastHtml += createWeatherParam('温度', temp + '°C');
|
||||
}
|
||||
|
||||
if (weatherData['wind_u-surface'] && weatherData['wind_v-surface'] &&
|
||||
weatherData['wind_u-surface'][i] !== null && weatherData['wind_v-surface'][i] !== null) {
|
||||
var windU = weatherData['wind_u-surface'][i];
|
||||
var windV = weatherData['wind_v-surface'][i];
|
||||
var windSpeed = Math.sqrt(windU * windU + windV * windV).toFixed(1);
|
||||
var windDir = getWindDirection(windU, windV);
|
||||
if (weatherData['wind-speed'] && weatherData['wind-speed'][i] !== null) {
|
||||
var windSpeed = weatherData['wind-speed'][i].toFixed(1);
|
||||
forecastHtml += createWeatherParam('风速', windSpeed + ' m/s');
|
||||
}
|
||||
|
||||
if (weatherData['wind-direction'] && weatherData['wind-direction'][i] !== null) {
|
||||
var windDir = getWindDirectionFromDegrees(weatherData['wind-direction'][i]);
|
||||
forecastHtml += createWeatherParam('风向', windDir);
|
||||
}
|
||||
|
||||
if (weatherData['past3hprecip-surface'] && weatherData['past3hprecip-surface'][i] !== null) {
|
||||
var precip = weatherData['past3hprecip-surface'][i].toFixed(1);
|
||||
if (weatherData['precipitation'] && weatherData['precipitation'][i] !== null) {
|
||||
var precip = weatherData['precipitation'][i].toFixed(1);
|
||||
forecastHtml += createWeatherParam('降水', precip + ' mm');
|
||||
}
|
||||
|
||||
@ -238,7 +266,7 @@ var WeatherForecast = (function() {
|
||||
}
|
||||
|
||||
if (weatherData['pressure-surface'] && weatherData['pressure-surface'][i] !== null) {
|
||||
var pressure = (weatherData['pressure-surface'][i] / 100).toFixed(0);
|
||||
var pressure = weatherData['pressure-surface'][i].toFixed(0);
|
||||
forecastHtml += createWeatherParam('气压', pressure + ' hPa');
|
||||
}
|
||||
|
||||
@ -291,6 +319,14 @@ var WeatherForecast = (function() {
|
||||
return directions[index];
|
||||
}
|
||||
|
||||
function getWindDirectionFromDegrees(degrees) {
|
||||
if (degrees === null || degrees === undefined) return '无风';
|
||||
|
||||
var directions = ['北', '东北', '东', '东南', '南', '西南', '西', '西北'];
|
||||
var index = Math.round(degrees / 45) % 8;
|
||||
return directions[index];
|
||||
}
|
||||
|
||||
function isEnabled() {
|
||||
return weatherEnabled;
|
||||
}
|
||||
|
||||
@ -851,7 +851,7 @@
|
||||
<div id="weatherForecastCard" class="weather-forecast-card" style="display: none;" th:if="${role=='SUPER_ADMIN'}">
|
||||
<div class="weather-card-header">
|
||||
<h3 class="weather-card-title">
|
||||
Windy 天气预测
|
||||
Open-Meteo 天气预测
|
||||
</h3>
|
||||
<button class="weather-close-btn" onclick="closeWeatherCard()">×</button>
|
||||
</div>
|
||||
@ -948,10 +948,10 @@
|
||||
</div>
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="dropdown-group" th:if="${role=='SUPER_ADMIN'}">
|
||||
<div class="dropdown-group-title">Windy 天气预测</div>
|
||||
<div class="dropdown-group-title">Open-Meteo 天气预测</div>
|
||||
<div class="dropdown-item">
|
||||
<label class="switch-label">
|
||||
<span>启用天气预测(需网络被代理)</span>
|
||||
<span>启用天气预测</span>
|
||||
<input type="checkbox" id="enableWeatherSwitch" onchange="toggleWeatherForecast()">
|
||||
<span class="switch-slider"></span>
|
||||
</label>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user