大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。

💞当前专栏:Python毕业设计

精彩专栏推荐👇🏻👇🏻👇🏻

🎀 Java毕业设计
🌎微信小程序毕业设计

开发环境

  • 开发语言:Java
  • 框架:springboot
  • JDK版本:JDK1.8
  • 服务器:tomcat7
  • 数据库:mysql 5.7
  • 数据库工具:Navicat12
  • 开发软件:eclipse/myeclipse/idea
  • Maven包:Maven3.3.9
  • 浏览器:谷歌浏览器

演示视频

基于spark的西南天气数据的分析与应用 演示录像

论文目录

【如需全文或源码请按文末获取联系】
在这里插入图片描述
在这里插入图片描述

一、项目简介

通过多数据源采集西南地区长时间序列天气数据,利用Spark技术对原始数据进行清洗、转换与集成,构建高质量气象数据集。从空气质量、白天和夜晚天气状况、高温、风向、降水等多个维度对数据进行深入分析,并借助Matplotlib、Seaborn、Plotly Express等库进行可视化展示。同时,紧密结合农业、交通、能源等行业需求,分析天气数据与行业活动的关联,如构建农业气象灾害预警模型、依天气调整交通管制措施、为能源生产与调度提供决策支持等。

二、系统设计

2.1软件功能模块设计

用户功能涵盖天气信息浏览,可查看西南地区各城市实时及历史天气数据,包括气温、降水、空气质量等;支持气象要素查询,按城市、时间范围等条件精准检索数据;设有用户注册登录功能,方便个性化设置与数据收藏。此外,具备数据可视化看板功能,以图表形式直观呈现气象数据变化趋势;提供收藏功能,用户可保存关注的气象数据与分析结果。管理员功能包含用户信息管理,审核用户注册、处理账号异常;负责气象数据管理,更新、维护数据准确性与完整性;具备系统公告发布管理功能,及时向用户传达系统更新、重要气象信息等。

三、系统项目部分截图

3.1空气质量分析与可视化

通过Spark分析西南地区空气质量数据,计算AQI等指标,探究时空分布规律。利用Matplotlib库,以柱状图展示不同城市空气质量等级占比,直观呈现区域空气质量差异。
在这里插入图片描述

3.2白天天气分析与可视化

对西南地区白天天气状况数据进行整理,分析晴天、多云等天气类型的出现频率及与气温、降水的关联。借助Seaborn库,以计数图展现不同城市白天天气类型分布。
在这里插入图片描述

3.3晚上天气分析与可视化

聚焦于西南地区夜晚天气特征,分析夜间天气状况的变化规律及对生活的潜在影响。运用PlotlyExpress绘制夜间天气状况的时间序列图,展示天气演变。
在这里插入图片描述

3.4高温统计分析与可视化

利用Spark统计西南地区高温数据,分析高温日数的时空变化及对生产生活的影响。使用Matplotlib绘制高温日数的空间分布图,直观展示高温区域分布。
在这里插入图片描述

3.5降水统计分析与可视化

通过Spark处理西南地区降水数据,统计降水量、降水日数等指标并分析其变化趋势。利用PlotlyExpress绘制降水量的箱线图,展示不同区域降水差异。
在这里插入图片描述

四、部分核心代码

package com.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.*;
import java.lang.*;
import java.math.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import com.utils.ValidatorUtils;
import com.utils.DeSensUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;

import com.entity.TianqiinfoEntity;
import com.entity.view.TianqiinfoView;

import com.service.TianqiinfoService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MPUtil;
import com.utils.MapUtils;
import com.utils.CommonUtil;
import java.io.IOException;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.JavaPairRDD;
import scala.Tuple2;

/**
 * 天气信息
 * 后端接口
 * @author 
 * @email 
 * @date 2025-03-10 13:20:33
 */
@RestController
@RequestMapping("/tianqiinfo")
public class TianqiinfoController {
    @Autowired
    private TianqiinfoService tianqiinfoService;
    @Autowired
    private JavaSparkContext javaSparkContext;






    



    /**
     * 后台列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,TianqiinfoEntity tianqiinfo,
                @RequestParam(required = false) Double aqistart,
                @RequestParam(required = false) Double aqiend,
                @RequestParam(required = false) Double jsliangstart,
                @RequestParam(required = false) Double jsliangend,
		HttpServletRequest request){
        //设置查询条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        if(aqistart!=null) ew.ge("aqi", aqistart);
        if(aqiend!=null) ew.le("aqi", aqiend);
        if(jsliangstart!=null) ew.ge("jsliang", jsliangstart);
        if(jsliangend!=null) ew.le("jsliang", jsliangend);


        //查询结果
		PageUtils page = tianqiinfoService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, tianqiinfo), params), params));
        Map<String, String> deSens = new HashMap<>();
        //给需要脱敏的字段脱敏
        DeSensUtil.desensitize(page,deSens);
        return R.ok().put("data", page);
    }
    
    /**
     * 前台列表
     */
	@IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params,TianqiinfoEntity tianqiinfo, 
                @RequestParam(required = false) Double aqistart,
                @RequestParam(required = false) Double aqiend,
                @RequestParam(required = false) Double jsliangstart,
                @RequestParam(required = false) Double jsliangend,
		HttpServletRequest request){
        //设置查询条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        if(aqistart!=null) ew.ge("aqi", aqistart);
        if(aqiend!=null) ew.le("aqi", aqiend);
        if(jsliangstart!=null) ew.ge("jsliang", jsliangstart);
        if(jsliangend!=null) ew.le("jsliang", jsliangend);

        //查询结果
		PageUtils page = tianqiinfoService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, tianqiinfo), params), params));
        Map<String, String> deSens = new HashMap<>();
        //给需要脱敏的字段脱敏
        DeSensUtil.desensitize(page,deSens);
        return R.ok().put("data", page);
    }



	/**
     * 列表
     */
    @RequestMapping("/lists")
    public R list( TianqiinfoEntity tianqiinfo){
       	EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
      	ew.allEq(MPUtil.allEQMapPre( tianqiinfo, "tianqiinfo")); 
        return R.ok().put("data", tianqiinfoService.selectListView(ew));
    }

	 /**
     * 查询
     */
    @RequestMapping("/query")
    public R query(TianqiinfoEntity tianqiinfo){
        EntityWrapper< TianqiinfoEntity> ew = new EntityWrapper< TianqiinfoEntity>();
 		ew.allEq(MPUtil.allEQMapPre( tianqiinfo, "tianqiinfo")); 
		TianqiinfoView tianqiinfoView =  tianqiinfoService.selectView(ew);
		return R.ok("查询天气信息成功").put("data", tianqiinfoView);
    }
	
    /**
     * 后台详情
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        TianqiinfoEntity tianqiinfo = tianqiinfoService.selectById(id);
        Map<String, String> deSens = new HashMap<>();
        //给需要脱敏的字段脱敏
        DeSensUtil.desensitize(tianqiinfo,deSens);
        return R.ok().put("data", tianqiinfo);
    }

    /**
     * 前台详情
     */
	@IgnoreAuth
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id){
        TianqiinfoEntity tianqiinfo = tianqiinfoService.selectById(id);
        Map<String, String> deSens = new HashMap<>();
        //给需要脱敏的字段脱敏
        DeSensUtil.desensitize(tianqiinfo,deSens);
        return R.ok().put("data", tianqiinfo);
    }
    



    /**
     * 后台保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody TianqiinfoEntity tianqiinfo, HttpServletRequest request){
        //ValidatorUtils.validateEntity(tianqiinfo);
        tianqiinfoService.insert(tianqiinfo);
        return R.ok().put("data",tianqiinfo.getId());
    }
    
    /**
     * 前台保存
     */
    @RequestMapping("/add")
    public R add(@RequestBody TianqiinfoEntity tianqiinfo, HttpServletRequest request){
        //ValidatorUtils.validateEntity(tianqiinfo);
        tianqiinfoService.insert(tianqiinfo);
        return R.ok().put("data",tianqiinfo.getId());
    }





    /**
     * 修改
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody TianqiinfoEntity tianqiinfo, HttpServletRequest request){
        //ValidatorUtils.validateEntity(tianqiinfo);
        //全部更新
        tianqiinfoService.updateById(tianqiinfo);
        return R.ok();
    }



    

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        tianqiinfoService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
    






    /**
     * (按值统计)
     */
    @RequestMapping("/value/{xColumnName}/{yColumnName}")
    public R value(@PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName,HttpServletRequest request) throws IOException {
        //读取文件,如果文件存在,则优先返回文件内容
        java.nio.file.Path path = java.nio.file.Paths.get("value_tianqiinfo_" + xColumnName + "_" + yColumnName + "_timeType.json");
        if(java.nio.file.Files.exists(path)) {
            String content = new String(java.nio.file.Files.readAllBytes(path), java.nio.charset.StandardCharsets.UTF_8);
            return R.ok().put("data", (new org.json.JSONArray(content)).toList());
        }
        //构建查询统计条件
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("xColumn", xColumnName);
        params.put("yColumn", yColumnName);
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
            //获取结果
        List<Map<String, Object>> result = tianqiinfoService.selectValue(params, ew);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for(Map<String, Object> m : result) {
            for(String k : m.keySet()) {
                if(m.get(k) instanceof Date) {
                    m.put(k, sdf.format((Date)m.get(k)));
                }
            }
        }
        Collections.sort(result, (map1, map2) -> {
            // 假设 total 总是存在并且是数值类型
            Number total1 = (Number) map1.get("total");
            Number total2 = (Number) map2.get("total");
            if(total1==null)
            {
                total1 = 0;
            }
            if(total2==null)
            {
                total2 = 0;
            }
            return Double.compare(total2.doubleValue(), total1.doubleValue());
        });
        return R.ok().put("data", result);
    }
    
    /**
     * (按值统计(多))
     */
    @RequestMapping("/valueMul/{xColumnName}")
    public R valueMul(@PathVariable("xColumnName") String xColumnName,@RequestParam String yColumnNameMul,HttpServletRequest request)  throws IOException {
        //读取文件,如果文件存在,则优先返回文件内容
        java.nio.file.Path path = java.nio.file.Paths.get("value_tianqiinfo_" + xColumnName + "_" + yColumnNameMul + "_timeType.json");
        if(java.nio.file.Files.exists(path)) {
            String content = new String(java.nio.file.Files.readAllBytes(path), java.nio.charset.StandardCharsets.UTF_8);
            return R.ok().put("data", (new org.json.JSONArray(content)).toList());
        }
        String[] yColumnNames = yColumnNameMul.split(",");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("xColumn", xColumnName);
        List<List<Map<String, Object>>> result2 = new ArrayList<List<Map<String,Object>>>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        for(int i=0;i<yColumnNames.length;i++) {
            params.put("yColumn", yColumnNames[i]);
            List<Map<String, Object>> result = tianqiinfoService.selectValue(params, ew);
            for(Map<String, Object> m : result) {
                for(String k : m.keySet()) {
                    if(m.get(k) instanceof Date) {
                        m.put(k, sdf.format((Date)m.get(k)));
                    }
                }
            }
            result2.add(result);
        }
        return R.ok().put("data", result2);
    }
    
    /**
     * (按值统计)时间统计类型
     */
    @RequestMapping("/value/{xColumnName}/{yColumnName}/{timeStatType}")
    public R valueDay(@PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName, @PathVariable("timeStatType") String timeStatType,HttpServletRequest request) throws IOException {
        //读取文件,如果文件存在,则优先返回文件内容
        java.nio.file.Path path = java.nio.file.Paths.get("value_tianqiinfo_" + xColumnName + "_" + yColumnName + "_"+timeStatType+".json");
        if(java.nio.file.Files.exists(path)) {
            String content = new String(java.nio.file.Files.readAllBytes(path), java.nio.charset.StandardCharsets.UTF_8);
            return R.ok().put("data", (new org.json.JSONArray(content)).toList());
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("xColumn", xColumnName);
        params.put("yColumn", yColumnName);
        params.put("timeStatType", timeStatType);
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        List<Map<String, Object>> result = tianqiinfoService.selectTimeStatValue(params, ew);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for(Map<String, Object> m : result) {
            for(String k : m.keySet()) {
                if(m.get(k) instanceof Date) {
                    m.put(k, sdf.format((Date)m.get(k)));
                }
            }
        }
        return R.ok().put("data", result);
    }
    
    /**
     * (按值统计)时间统计类型(多)
     */
    @RequestMapping("/valueMul/{xColumnName}/{timeStatType}")
    public R valueMulDay(@PathVariable("xColumnName") String xColumnName, @PathVariable("timeStatType") String timeStatType,@RequestParam String yColumnNameMul,HttpServletRequest request) throws IOException
    {
        //读取文件,如果文件存在,则优先返回文件内容
        java.nio.file.Path path = java.nio.file.Paths.get("value_tianqiinfo_" + xColumnName + "_" + yColumnNameMul + "_" + timeStatType + ".json");
        if (java.nio.file.Files.exists(path)) {
            String content = new String(java.nio.file.Files.readAllBytes(path), java.nio.charset.StandardCharsets.UTF_8);
            return R.ok().put("data", (new org.json.JSONArray(content)).toList());
        }
        String[] yColumnNames = yColumnNameMul.split(",");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("xColumn", xColumnName);
        params.put("timeStatType", timeStatType);
        List<List<Map<String, Object>>> result2 = new ArrayList<List<Map<String,Object>>>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        for(int i=0;i<yColumnNames.length;i++) {
            params.put("yColumn", yColumnNames[i]);
            List<Map<String, Object>> result = tianqiinfoService.selectTimeStatValue(params, ew);
            for(Map<String, Object> m : result) {
                for(String k : m.keySet()) {
                    if(m.get(k) instanceof Date) {
                        m.put(k, sdf.format((Date)m.get(k)));
                    }
                }
            }
            result2.add(result);
        }
        return R.ok().put("data", result2);
    }
    
    /**
     * 分组统计
     */
    @RequestMapping("/group/{columnName}")
    public R group(@PathVariable("columnName") String columnName,HttpServletRequest request) throws IOException {
        //读取文件,如果文件存在,则优先返回文件内容
        java.nio.file.Path path = java.nio.file.Paths.get("group_tianqiinfo_" + columnName + "_timeType.json");
        if(java.nio.file.Files.exists(path)){
            String content = new String(java.nio.file.Files.readAllBytes(path), java.nio.charset.StandardCharsets.UTF_8);
            return R.ok().put("data", (new org.json.JSONArray(content)).toList());
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("column", columnName);
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        List<Map<String, Object>> result = tianqiinfoService.selectGroup(params, ew);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for(Map<String, Object> m : result) {
            for(String k : m.keySet()) {
                if(m.get(k) instanceof Date) {
                    m.put(k, sdf.format((Date)m.get(k)));
                }
            }
        }
        return R.ok().put("data", result);
    }    

    /**
     * 分段统计
     */
    @RequestMapping("/sectionStat/gaowen")
    @IgnoreAuth
    public R gaowenSectionStat(HttpServletRequest request) {
        Map<String, Object> params = new HashMap<String, Object>();
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        List<Map<String, Object>> result = tianqiinfoService.gaowenSectionStat(params, ew);
        return R.ok().put("data", result);
    }
    /**
     * 分段统计
     */
    @RequestMapping("/sectionStat/aqi/city")
    @IgnoreAuth
    public R cityaqiSectionStat(HttpServletRequest request) {
        Map<String, Object> params = new HashMap<String, Object>();
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        List<Map<String, Object>> result = tianqiinfoService.cityaqiSectionStat(params, ew);
        return R.ok().put("data", result);
    }
    /**
     * 分段统计
     */
    @RequestMapping("/sectionStat/jsliang/city")
    @IgnoreAuth
    public R cityjsliangSectionStat(HttpServletRequest request) {
        Map<String, Object> params = new HashMap<String, Object>();
        //构建查询统计条件
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        List<Map<String, Object>> result = tianqiinfoService.cityjsliangSectionStat(params, ew);
        return R.ok().put("data", result);
    }



    /**
     * 总数量
     */
    @RequestMapping("/count")
    public R count(@RequestParam Map<String, Object> params,TianqiinfoEntity tianqiinfo, HttpServletRequest request){
        EntityWrapper<TianqiinfoEntity> ew = new EntityWrapper<TianqiinfoEntity>();
        int count = tianqiinfoService.selectCount(MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, tianqiinfo), params), params));
        return R.ok().put("data", count);
    }

}

获取源码或论文

如需对应的论文或源码,以及其他定制需求,也可以下方微❤联系。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐