236 lines
8.0 KiB
JavaScript
236 lines
8.0 KiB
JavaScript
const { Client } = require('pg');
|
||
require('dotenv').config();
|
||
|
||
// 使用DATABASE_URL如果可用,否则回退到个别配置
|
||
const client = new Client(
|
||
process.env.DATABASE_URL || {
|
||
host: process.env.DATABASE_HOST || 'localhost',
|
||
port: process.env.DATABASE_PORT || 5432,
|
||
database: process.env.DATABASE_NAME || 'meteor_db',
|
||
user: process.env.DATABASE_USER || 'postgres',
|
||
password: process.env.DATABASE_PASSWORD || 'password',
|
||
}
|
||
);
|
||
|
||
// 气象站数据
|
||
const weatherStations = [
|
||
{
|
||
station_name: '北京气象站',
|
||
location: '北京',
|
||
latitude: 39.9042,
|
||
longitude: 116.4074,
|
||
altitude: 43.71,
|
||
status: 'active'
|
||
},
|
||
{
|
||
station_name: '东京气象站',
|
||
location: '东京',
|
||
latitude: 35.6762,
|
||
longitude: 139.6503,
|
||
altitude: 40.0,
|
||
status: 'active'
|
||
},
|
||
{
|
||
station_name: '伦敦气象站',
|
||
location: '伦敦',
|
||
latitude: 51.5074,
|
||
longitude: -0.1278,
|
||
altitude: 35.0,
|
||
status: 'active'
|
||
},
|
||
{
|
||
station_name: '纽约气象站',
|
||
location: '纽约',
|
||
latitude: 40.7128,
|
||
longitude: -74.0060,
|
||
altitude: 10.0,
|
||
status: 'active'
|
||
},
|
||
{
|
||
station_name: '悉尼气象站',
|
||
location: '悉尼',
|
||
latitude: -33.8688,
|
||
longitude: 151.2093,
|
||
altitude: 58.0,
|
||
status: 'maintenance'
|
||
}
|
||
];
|
||
|
||
// 天气状况列表
|
||
const weatherConditions = [
|
||
'晴朗', '多云', '阴天', '小雨', '中雨', '大雨', '雷阵雨',
|
||
'雪', '雾', '霾', '沙尘暴', '冰雹'
|
||
];
|
||
|
||
const observationQualities = ['excellent', 'moderate', 'poor'];
|
||
|
||
// 生成天气观测数据
|
||
function generateWeatherObservations(stationId, stationName, days = 30) {
|
||
const observations = [];
|
||
const now = new Date();
|
||
|
||
// 基础温度根据地区设置
|
||
let baseTempRange = { min: -10, max: 30 };
|
||
if (stationName.includes('北京')) baseTempRange = { min: -5, max: 35 };
|
||
if (stationName.includes('东京')) baseTempRange = { min: 0, max: 32 };
|
||
if (stationName.includes('伦敦')) baseTempRange = { min: 2, max: 25 };
|
||
if (stationName.includes('纽约')) baseTempRange = { min: -2, max: 30 };
|
||
if (stationName.includes('悉尼')) baseTempRange = { min: 8, max: 28 };
|
||
|
||
for (let i = 0; i < days; i++) {
|
||
// 每天生成4次观测数据 (6小时间隔)
|
||
for (let j = 0; j < 4; j++) {
|
||
const observationTime = new Date(now - i * 24 * 60 * 60 * 1000 + j * 6 * 60 * 60 * 1000);
|
||
|
||
observations.push({
|
||
weather_station_id: stationId,
|
||
observation_time: observationTime,
|
||
temperature: baseTempRange.min + Math.random() * (baseTempRange.max - baseTempRange.min),
|
||
humidity: 30 + Math.random() * 50, // 30-80%
|
||
cloud_cover: Math.random() * 100, // 0-100%
|
||
visibility: 5 + Math.random() * 45, // 5-50km
|
||
wind_speed: Math.random() * 30, // 0-30 km/h
|
||
wind_direction: Math.floor(Math.random() * 360), // 0-360度
|
||
condition: weatherConditions[Math.floor(Math.random() * weatherConditions.length)],
|
||
observation_quality: observationQualities[Math.floor(Math.random() * observationQualities.length)],
|
||
pressure: 980 + Math.random() * 60, // 980-1040 hPa
|
||
precipitation: Math.random() < 0.3 ? Math.random() * 20 : 0 // 30%概率有降水
|
||
});
|
||
}
|
||
}
|
||
|
||
return observations;
|
||
}
|
||
|
||
// 生成天气预报数据
|
||
function generateWeatherForecasts(stationId, days = 7) {
|
||
const forecasts = [];
|
||
const now = new Date();
|
||
const issuedAt = new Date();
|
||
|
||
for (let i = 1; i <= days; i++) {
|
||
// 每天生成2次预报 (12小时间隔)
|
||
for (let j = 0; j < 2; j++) {
|
||
const forecastTime = new Date(now.getTime() + i * 24 * 60 * 60 * 1000 + j * 12 * 60 * 60 * 1000);
|
||
|
||
forecasts.push({
|
||
weather_station_id: stationId,
|
||
forecast_time: forecastTime,
|
||
issued_at: issuedAt,
|
||
temperature: -5 + Math.random() * 40, // -5到35度
|
||
cloud_cover: Math.random() * 100,
|
||
precipitation: Math.random() < 0.25 ? Math.random() * 15 : 0,
|
||
visibility: 10 + Math.random() * 40,
|
||
condition: weatherConditions[Math.floor(Math.random() * weatherConditions.length)],
|
||
confidence: 0.6 + Math.random() * 0.4 // 60-100%置信度
|
||
});
|
||
}
|
||
}
|
||
|
||
return forecasts;
|
||
}
|
||
|
||
async function seedWeatherData() {
|
||
try {
|
||
await client.connect();
|
||
console.log('Connected to database');
|
||
|
||
// 清空现有数据
|
||
console.log('Clearing existing weather data...');
|
||
await client.query('DELETE FROM weather_forecasts');
|
||
await client.query('DELETE FROM weather_observations');
|
||
await client.query('DELETE FROM weather_stations');
|
||
|
||
// 插入气象站数据
|
||
console.log('Inserting weather stations...');
|
||
for (const station of weatherStations) {
|
||
const query = `
|
||
INSERT INTO weather_stations (
|
||
station_name, location, latitude, longitude, altitude, status
|
||
) VALUES ($1, $2, $3, $4, $5, $6)
|
||
RETURNING id
|
||
`;
|
||
|
||
const values = [
|
||
station.station_name, station.location, station.latitude,
|
||
station.longitude, station.altitude, station.status
|
||
];
|
||
|
||
const result = await client.query(query, values);
|
||
const stationId = result.rows[0].id;
|
||
|
||
console.log(`Inserted weather station: ${station.station_name} (ID: ${stationId})`);
|
||
|
||
// 为每个气象站生成观测数据
|
||
console.log(`Generating observations for ${station.station_name}...`);
|
||
const observations = generateWeatherObservations(stationId, station.station_name);
|
||
|
||
for (const obs of observations) {
|
||
const obsQuery = `
|
||
INSERT INTO weather_observations (
|
||
weather_station_id, observation_time, temperature, humidity,
|
||
cloud_cover, visibility, wind_speed, wind_direction, condition,
|
||
observation_quality, pressure, precipitation
|
||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||
`;
|
||
|
||
const obsValues = [
|
||
obs.weather_station_id, obs.observation_time, obs.temperature,
|
||
obs.humidity, obs.cloud_cover, obs.visibility, obs.wind_speed,
|
||
obs.wind_direction, obs.condition, obs.observation_quality,
|
||
obs.pressure, obs.precipitation
|
||
];
|
||
|
||
await client.query(obsQuery, obsValues);
|
||
}
|
||
|
||
// 为每个气象站生成预报数据
|
||
console.log(`Generating forecasts for ${station.station_name}...`);
|
||
const forecasts = generateWeatherForecasts(stationId);
|
||
|
||
for (const forecast of forecasts) {
|
||
const forecastQuery = `
|
||
INSERT INTO weather_forecasts (
|
||
weather_station_id, forecast_time, issued_at, temperature,
|
||
cloud_cover, precipitation, visibility, condition, confidence
|
||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||
`;
|
||
|
||
const forecastValues = [
|
||
forecast.weather_station_id, forecast.forecast_time, forecast.issued_at,
|
||
forecast.temperature, forecast.cloud_cover, forecast.precipitation,
|
||
forecast.visibility, forecast.condition, forecast.confidence
|
||
];
|
||
|
||
await client.query(forecastQuery, forecastValues);
|
||
}
|
||
|
||
console.log(`Generated ${observations.length} observations and ${forecasts.length} forecasts for ${station.station_name}`);
|
||
}
|
||
|
||
console.log('Weather data seeding completed successfully!');
|
||
|
||
// 显示统计信息
|
||
const stationCount = await client.query('SELECT COUNT(*) FROM weather_stations');
|
||
const observationCount = await client.query('SELECT COUNT(*) FROM weather_observations');
|
||
const forecastCount = await client.query('SELECT COUNT(*) FROM weather_forecasts');
|
||
|
||
console.log(`Total weather stations: ${stationCount.rows[0].count}`);
|
||
console.log(`Total observations: ${observationCount.rows[0].count}`);
|
||
console.log(`Total forecasts: ${forecastCount.rows[0].count}`);
|
||
|
||
} catch (error) {
|
||
console.error('Error seeding weather data:', error);
|
||
process.exit(1);
|
||
} finally {
|
||
await client.end();
|
||
console.log('Database connection closed');
|
||
}
|
||
}
|
||
|
||
// 如果直接运行此脚本
|
||
if (require.main === module) {
|
||
seedWeatherData();
|
||
}
|
||
|
||
module.exports = { seedWeatherData }; |