目录

前言

一、未来天气需求

1、需求描述

2、百度天气支撑

二、Java实现

1、核心类图

2、Ruoyi核心处理

三、Thymeleaf集成

1、逐日预报展示

2、逐小时预报展示

3、Thymeleaf集成小问题

四、总结


前言

        在当今数字化时代,天气预报不仅是人们日常生活中的重要参考,更是关乎社会经济运行、公共安全和可持续发展的关键因素。从个人的出行计划到企业的生产调度,从农业生产的精准安排到城市应急管理体系的高效运作,准确、及时且具有前瞻性的天气信息都扮演着不可或缺的角色。然而,传统的天气预报模式已经难以满足现代社会对气象信息的高精度、高时效性和个性化的需求。在这样的背景下,我们使用百度天气携手 Ruoyi 开发框架,开启了一场面向未来的预报实战之旅,旨在通过技术创新和平台升级,为用户提供更智能、更精准、更全面的气象服务。

        百度天气服务,不仅有当下的实时数据,同时包括面向未来的逐日和未来24小时的逐小时预报信息。因此我们可以使用百度天气来提高面向未来的天气预报服务,也可以当成重要的信息渠道来源。本文将重点详细讲解如何基于Ruoyi来集成百度天气服务,如何在Thymeleaf中展示天气实况、逐日天气预报和逐小时天气报表,通过实例的讲解,为用户提供量身定制的天气预报内容和相关建议,真正实现从“千人一面”到“千人千面”的服务转变。

一、未来天气需求

        本节将详细介绍面向未来天气的业务需求以及使用百度天气如何进行核心数据的支撑。

1、需求描述

        未来天气预报将向更高精度、更全面的时空覆盖方向发展。这意味着不仅要在时间上提供从短期(小时级别)到逐日(数天或者数月)的预报,还要在空间上实现从全球到局部地区的精细化预测。天气预报将不再局限于传统的温度、降水等基本气象要素,而是拓展到综合的地球环境要素预报。这包括空气质量、紫外线强度等与人们生活息息相关的环境信息。这种综合预报能够为不同需求的用户提供更全面的参考,比如为户外运动爱好者提供紫外线,为健康防护提供空气质量预报。未来的天气预报将广泛应用于多个场景,包括但不限于农业、交通、旅游、能源和城市应急管理。例如,在农业领域,精准的天气预报可以帮助农民更好地安排种植和收获时间,减少自然灾害带来的损失;在交通领域,实时的天气信息能够帮助优化交通流量,减少事故风险。

2、百度天气支撑

        天气数据是一个多源的数据,如果要单向管理这些数据来源,势必要付出极大地时间进行管理,这无疑增加了我们的管理成本。那么我们其实可以基于丰富的互联网接口,比如百度天气来作为天气信息数据的基础支撑。百度天气服务的未来预报信息如下:

        可以看到,该接口服务中不仅包含了未来7天的天气预报,同时也包含未来24小时的逐小时天气预报,通过一个接口就基本满足了我们的需要。下面我们将详细介绍如何结合Web界面实现信息的具体查看等操作。

二、Java实现

        本节将详细介绍Java的核心实现,主要介绍两个方面的内容,一个是核心类图,第二个是使用Ruoyi框架进行核心开发。通过本节的介绍,可以掌握如何进行后台业务的实际开发。

1、核心类图

        百度天气的核心类图如上,关于百度天气信息的相关信息和抓取方法,可以参考以下链接GSON 框架下百度天气 JSON 数据转 JavaBean 的实战攻略基于 MybatisPlus 将百度天气数据存储至 PostgreSQL 数据库的实践。博文详细的介绍了如何使用Java进行百度天气信息的查询,如果需要离线处理,也可以使用PG数据库进行存储,为后续的天气综合分析提供数据基础。

2、Ruoyi核心处理

        这里使用的是Ruoyi的单体开发模式,后台使用Java进行数据处理。我们开发一个后台的控制器,用于调用百度的天气接口,并且将前期数据反序列化成目标对象,并设置到上下文对象中,在后续的Thymeleaf框架中进行数据的展示。控制器的核心方法如下:

/**
* - 跳转区县天气预报
* @return
*/
@RequiresPermissions("eq:weather:forecast:view")
@GetMapping("/weather/forecast/{id}")
public String weatherForecast(@PathVariable("id") Long id,ModelMap mmap) {
	mmap.put("areaId", id);
	Area area = areaService.getById(id);
	Gson gson = new Gson();
	HttpResponse result = baiduWeatherServcie.getWeather(String.valueOf(area.getAreaCode()), "all", BAIDU_CLIENT_AK);
	if(StringUtils.isNotEmpty(result.getBodyResult())) {
		BdWeatherDTO weatherInfo = gson.fromJson(result.getBodyResult(), BdWeatherDTO.class);
		mmap.put("weatherInfo", weatherInfo.getResult());
	}
	mmap.put("area", area);
	return prefix + "/forecast";
}

三、Thymeleaf集成

        Thymeleaf是Ruoyi单体框架的默认前端渲染引擎,这里我们将详细介绍在前端引擎中进行逐日的数据展示和逐小时的预报集成展示,在集成的过程当中也遇到了一个小问题。这些内容都在本节中进行详细的展示。

1、逐日预报展示

        在SpringMvc中,在后台的控制器中设置了需要展示的对象之后,在Html页面中就可以取出对象信息来进行展示。我们将当前实时天气和逐日预报信息作为表格数据进行集中展示,核心代码如下:

一、实时天气
所在省份 [[${area.provinceName}]] 所在城市 [[${area.cityName}]]
实时温度 [[${weatherInfo.weatherNow.temp}]]℃ 体感温度 [[${weatherInfo.weatherNow.feelsLike}]]℃
相对湿度 [[${weatherInfo.weatherNow.rh}]]% 风力 [[${weatherInfo.weatherNow.windDir}]]/[[${weatherInfo.weatherNow.windClass}]]
1小时累计降水量 [[${weatherInfo.weatherNow.prec1h}]]mm 云量 [[${weatherInfo.weatherNow.clouds}]]%
能见度 [[${weatherInfo.weatherNow.vis}]]m 空气质量 [[${weatherInfo.weatherNow.aqi}]]
pm25 [[${weatherInfo.weatherNow.pm25}]]μg/m3 pm10 [[${weatherInfo.weatherNow.pm10}]]μg/m3
二氧化氮 [[${weatherInfo.weatherNow.no2}]]μg/m3 二氧化硫 [[${weatherInfo.weatherNow.so2}]]μg/m3
臭氧/td> [[${weatherInfo.weatherNow.o3}]]μg/m3 一氧化碳浓度 [[${weatherInfo.weatherNow.co}]]mg/m3
二、未来7日天气
日期 星期 温度 白天风力 晚上风力 天气现象
[[${forecast.week}]] [[${forecast.high}]]℃-[[${forecast.low}]]℃ [[${forecast.wdDay}]] [[${forecast.wcDay}]] [[${forecast.wdNight}]] [[${forecast.wcNight}]] [[${forecast.textDay}]]

        将程序发布后,打开页面可以看到以下信息展示界面:

        页面左边将展示实时天气信息,比如实时温度、风力风向、湿度、云量等数据,右边则展示未来7天的逐日天气信息,包括温度、白天风力、晚上风力、天气描述等信息。

2、逐小时预报展示

        面向未来的逐小时天气预报展示,我们使用Echarts图表的形式展示,为了丰富展示图表的样式,我们需要同时展示四个指标:温度、降水量、湿度、云量,其中温度和湿度使用折线图,降水量和云量使用的是柱状图。html展示核心代码如下:

三、24小时实况曲线

echarts集成多坐标系源码如下:

var charts = new Array();
var forecasthoursEchart;
var colors = [ '#5793f3', '#d14a61', '#675bba', '#c04aab',  '#a6c30f'];
var legendData = new Array();//图例对象
var tempfcData = new Array();//温度(℃)
var rhData = new Array();//湿度(%)
var prec1hData = new Array();//降水量
var cloudsData = new Array();//云量
$(function() {
    //遍历
    forecasthours.forEach(function(forecast) {
        legendData.push(forecast.dataTimeStr);
        tempfcData.push(forecast.tempFc);
        rhData.push(forecast.rh);
        prec1hData.push(forecast.prec1h);
        cloudsData.push(forecast.clouds);
     });
     forecasthoursEchart = echarts.init(document.getElementById("forecasthours-echart"));
     var option = {
        color : colors,
        tooltip : {
        	trigger : 'axis'
        },
        grid : {
        	right : '20%'
        },
        toolbox : {
        	feature : {
        		dataView : {
        			show : false,
        			readOnly : false
        		},
        		restore : {
        			show : false
        		},
        		saveAsImage : {
        			show : false
        		}
            }
        },
        legend : {
        	data : [ '温度(℃)', '湿度(%)', '降水量(mm)','云量(%)']
        },
        xAxis : [ {
        	type : 'category',
        	axisTick : {
        		alignWithLabel : false
        	},
        	axisLabel:{
        		rotate:30 // x轴旋转30度
        	},
        	data : legendData
        } ],
        yAxis : [ {
        	type : 'value',
        	name : '温度(℃)',
        	nameLocation:"middle",
        	min : -10,
        	max : 50,
        	position : 'left',
        	axisLine : {
        		//show: true,
        		lineStyle : {
        			color : colors[0]
        		}
        	},
        	axisLabel : {
        		formatter : '{value}'
        	},
        	nameTextStyle:{
        		padding : [0,0,25,0]
        	}
        	}, {
        		type : 'value',
        		name : '湿度(%)',
        		nameLocation:"middle",
        		min : 0,
        		max : 120,
        		position : 'right',
        		axisLabel : {
        			formatter : '{value}'
        		},
        		axisLine : {
        			show: true,
        			lineStyle : {
        			color : colors[1]
        			}
        		},
        		axisTick: {
        			show: true,
        			lineStyle: {
        			color: colors[1]
        			}
        		},
        		nameTextStyle:{
        			padding : [20,0,0,0]
        		    }
        		}, {
        		type : 'value',
        			name : '降水量(mm)',
        			nameLocation:"middle",
        			min : 0,
        			max : 50,
        			position : 'right',
        			offset : 60,
        			axisLabel : {
        				formatter : '{value}'
        			},
        			axisLine : {
        				//show: true,
        				lineStyle : {
        					color : colors[2]
        				}
        			},
        			nameTextStyle:{
        				padding : [20,0,0,0]
        			}
        		}, {
        			type : 'value',
        			name : '云量(%)',
        			nameLocation:"middle",
        			min : 0,
        			max : 100,
        			position : 'left',
        			offset : 65,
        			axisLabel : {
        				formatter : '{value}'
        			},
        			axisLine : {
        				show: true,
        				lineStyle : {
        					color : colors[3]
        				}
        			},
        			axisTick: {
        				show: true,
        				lineStyle: {
        					color: colors[3]
        				}
        			}
        		}],
        		series : [
      				{
      					name : '温度(℃)',
      					type : 'line',
      					data : tempfcData
      				},
      				{
      					name : '湿度(%)',
      					type : 'line',
      					yAxisIndex : 1,
      					data : rhData
      				},
      				{
      					name : '降水量(mm)',
      					type : 'bar',
      					yAxisIndex : 2,
      					data : prec1hData
      				} ,
      				{
      					name : '云量(%)',
      					type : 'bar',
      					yAxisIndex : 3,
      					data : cloudsData
      				}]
        	};
    forecasthoursEchart.setOption(option,true);
    $(window).resize(forecasthoursEchart.resize);
    charts.push(forecasthoursEchart);
    $(window).resize(function() {
	  for(var i = 0; i < charts.length; i++) {
	        charts[i].resize();
	  }
    });
});

         将程序发布后,打开页面可以看到以下信息展示界面:

3、Thymeleaf集成小问题

        使用Thymeleaf直接访问后台的集合对象时,集合对象设置了时间属性,在前台访问时,不能按照我们的预期进行格式化,在控制台打印信息如下:

        如果遇到以上问题,怎么处理,这里分享一种解决办法,如果遇到时间格式化不一致,可以在后台的JavaBean中增加一个转换get方法,核心代码如下:

public String getDataTimeStr() {
	SimpleDateFormat dateFormat = new SimpleDateFormat("dd日HH时");
	return dateFormat.format(this.getDataTime());
}

        经过上述的改造即可完成准确的时间转换。

四、总结

        以上就是本文的主要内容,本文将重点详细讲解如何基于Ruoyi来集成百度天气服务,如何在Thymeleaf中展示天气实况、逐日天气预报和逐小时天气报表,通过实例的讲解,为用户提供量身定制的天气预报内容和相关建议,真正实现从“千人一面”到“千人千面”的服务转变。行文仓促,定有许多的不足之处,欢迎各位朋友在评论区批评指正,不胜感激。