You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
5.2 KiB
132 lines
5.2 KiB
import java.net.URI;
|
|
import java.net.http.HttpClient;
|
|
import java.net.http.HttpRequest;
|
|
import java.net.http.HttpResponse;
|
|
import java.io.IOException;
|
|
import org.knowm.xchart.*;
|
|
|
|
public class WeatherMain {
|
|
|
|
public static void main(String[] args) {
|
|
// 西部城市列表:[城市名, 纬度, 经度]
|
|
String[][] westernCities = {
|
|
{"西安", "34.2644", "108.9494"},
|
|
{"成都", "30.5723", "104.0665"},
|
|
{"兰州", "36.0614", "103.8343"},
|
|
{"乌鲁木齐", "43.8256", "87.6168"}
|
|
};
|
|
|
|
try {
|
|
// 1. 创建 HTTP 客户端
|
|
HttpClient httpClient = HttpClient.newHttpClient();
|
|
|
|
// 2. 遍历所有城市
|
|
for (String[] city : westernCities) {
|
|
String cityName = city[0];
|
|
String latitude = city[1];
|
|
String longitude = city[2];
|
|
|
|
// 拼接 API 地址
|
|
String apiUrl = "https://api.open-meteo.com/v1/forecast"
|
|
+ "?latitude=" + latitude
|
|
+ "&longitude=" + longitude
|
|
+ "&hourly=temperature_2m"
|
|
+ "&timezone=Asia/Shanghai";
|
|
|
|
// 构建 HTTP 请求
|
|
HttpRequest request = HttpRequest.newBuilder()
|
|
.uri(URI.create(apiUrl))
|
|
.GET()
|
|
.build();
|
|
|
|
// 发送请求并获取响应
|
|
HttpResponse<String> response = httpClient.send(
|
|
request,
|
|
HttpResponse.BodyHandlers.ofString()
|
|
);
|
|
|
|
// 打印温度表格
|
|
printTemperatureTable(response.body(), cityName);
|
|
// ✅ 新增:绘制温度折线图
|
|
drawTemperatureChart(response.body(), cityName);
|
|
|
|
System.out.println("✅ " + cityName + " 天气数据获取完成!\n");
|
|
}
|
|
|
|
System.out.println("==================================");
|
|
System.out.println("🎉 所有西部城市天气数据爬取完毕!");
|
|
|
|
} catch (Exception e) {
|
|
System.err.println("❌ 爬取过程中发生错误:");
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// 打印温度表格
|
|
private static void printTemperatureTable(String jsonData, String cityName) {
|
|
try {
|
|
// 提取时间数组
|
|
int timeStart = jsonData.indexOf("\"time\":");
|
|
int timeEnd = jsonData.indexOf("],", timeStart);
|
|
String timePart = jsonData.substring(timeStart + 7, timeEnd + 1);
|
|
String[] times = timePart.replace("\"", "").replace("[", "").replace("]", "").split(",");
|
|
|
|
// 提取温度数组
|
|
int tempStart = jsonData.indexOf("\"temperature_2m\":");
|
|
int tempEnd = jsonData.indexOf("]", tempStart);
|
|
String tempPart = jsonData.substring(tempStart + 18, tempEnd + 1);
|
|
String[] temps = tempPart.replace("[", "").replace("]", "").split(",");
|
|
|
|
// 打印表头
|
|
System.out.println("==================================");
|
|
System.out.println("城市:" + cityName);
|
|
System.out.println("----------------------------------");
|
|
System.out.printf("%-20s %-10s%n", "时间", "温度(°C)");
|
|
System.out.println("----------------------------------");
|
|
|
|
// 只打印前24小时数据
|
|
int maxShow = Math.min(24, Math.min(times.length, temps.length));
|
|
for (int i = 0; i < maxShow; i++) {
|
|
System.out.printf("%-20s %-10s%n", times[i], temps[i]);
|
|
}
|
|
System.out.println("----------------------------------\n");
|
|
} catch (Exception e) {
|
|
System.out.println("⚠️ " + cityName + " 数据解析失败");
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// ✅ 新增:绘制温度折线图并保存为 PNG
|
|
private static void drawTemperatureChart(String jsonData, String cityName) throws IOException {
|
|
// 提取温度数组
|
|
int tempStart = jsonData.indexOf("\"temperature_2m\":");
|
|
int tempEnd = jsonData.indexOf("]", tempStart);
|
|
String tempPart = jsonData.substring(tempStart + 18, tempEnd + 1);
|
|
String[] temps = tempPart.replace("[", "").replace("]", "").split(",");
|
|
|
|
// 准备绘图数据(取前24小时)
|
|
double[] hours = new double[24];
|
|
double[] temperatures = new double[24];
|
|
for (int i = 0; i < 24; i++) {
|
|
hours[i] = i; // 用 0~23 代表一天中的小时
|
|
temperatures[i] = Double.parseDouble(temps[i].trim());
|
|
}
|
|
|
|
// 创建图表
|
|
XYChart chart = new XYChartBuilder()
|
|
.width(800) // 图片宽度
|
|
.height(600) // 图片高度
|
|
.title(cityName + " 逐小时温度变化")
|
|
.xAxisTitle("小时(0~23)")
|
|
.yAxisTitle("温度 (°C)")
|
|
.build();
|
|
|
|
// 添加数据系列
|
|
chart.addSeries("温度", hours, temperatures);
|
|
|
|
// 保存为 PNG 图片(项目根目录下)
|
|
String fileName = cityName + "_温度折线图.png";
|
|
BitmapEncoder.saveBitmap(chart, fileName, BitmapEncoder.BitmapFormat.PNG);
|
|
System.out.println("📊 图表已保存:" + fileName);
|
|
}
|
|
}
|