跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Java大前端java

基于 Leaflet 的 WebGIS 省域区县天气可视化实现

基于 Leaflet 和 SpringBoot 构建省域区县天气可视化系统。后端采用 PostgreSQL 存储空间数据,通过行政区划代码关联天气信息。前端利用 Leaflet 加载 GeoJSON 图层,根据气温数值映射颜色色带并展示图例。处理了区县名称不一致的数据清洗问题,实现了湖南省与西藏自治区的天气实况地图展示,支持碰撞检测优化标签显示。

MqEngine发布于 2026/4/11更新于 2026/7/2034 浏览
基于 Leaflet 的 WebGIS 省域区县天气可视化实现

一、空间数据基础

本节对相关的空间数据基础做简单介绍,内容需要使用到省级空间范围、区县行政空间范围以及区县驻地等信息进行检索。为了在 WebGIS 展示时将天气数据直接与行政区划关联,我们在天气表中预留了行政区划编码的字段。

1、省域空间检索

省域信息有两个使用场景:一是省级行政范围的展示,二是通过百度天气接口获取具体天气信息时,首先需要通过省级行政区划代码或者下级区县信息,然后循环调用官方接口来获取天气信息。省域信息及表结构如下:

select * from biz_province;

上图中返回的 code 就是该省份对应的行政区划代码,如:130000 表示河北省。有了这个代码之后查询下级的区县信息,查询语句如下(以河北省为例):

select * from biz_area t where t.province_code = '130000';

通过以上的 SQL 查询就可以获取到指定省份的下属区县信息,后续就可以根据该区县 code 获取天气信息。

2、区县天气信息检索

为了实现区县的天气信息,需要涉及的数据表如下:

序号表名说明
1biz_weather_now实时天气信息表
2biz_area区县信息表
3biz_geographic_name城市信息表

篇幅有限,这里直接给出区县天气信息检索的 SQL(以查询 2025 年 8 月 17 日的湖南省 430000 的区县天气信息为例):

SELECT t2.*, T.province_code, T.province_name, T.area_code, T.area_name, t1.geom, st_asgeojson ( T.geom ) geomJson, st_x ( t1.geom ) lon, st_y ( t1.geom ) lat FROM biz_weather_now t2, biz_area T, biz_geographic_name t1 WHERE to_char( t2.uptime, 'YYYY-MM-DD' ) = '2025-08-17' AND T.province_code = '430000' AND T.area_name = t1.NAME AND T.area_code = t2.location_code AND st_contains(t.geom, t1.geom) ORDER BY t.area_code;

经过数据库客户端查询返回的结果集包含地理信息和天气数据。

二、天气数据简介

天气变化的复杂性和不确定性,使得准确、及时地获取和展示天气信息成为一项极具挑战性的任务。传统的天气预报方式往往只能提供较为宏观的天气趋势,对于具体的区县级天气状况描述不够细致。天气数据是整个研究内容的核心,这里的天气信息数据源以百度天气为例,通过查询获取区域内的天气信息。

1、省域天气数据获取

在后台查询区县和获取对应的天气信息,核心的 Java 代码如下:

/** * - 批量处理省级数据 * @throws InterruptedException */ 
@Test 
public void bdWeather2PGWithProvince() throws InterruptedException { 
    String provinceCode = "430000"; 
    Random random = new Random(); 
    QueryWrapper<Area> queryWrapper = new QueryWrapper<Area>(); 
    queryWrapper.like("province_code", provinceCode); 
    List<Area> areaList = areaService.list(queryWrapper); 
    if(StringUtils.isNotEmpty(areaList)) { 
        for (Area area : areaList) { 
            String areaCode = area.getAreaCode(); 
            HttpResponse<String> result = baiduWeatherApiService.getWeather(areaCode, DATA_TYPE); 
            Gson gson = new Gson(); 
            BdWeatherDTO bdWeatherInfo = gson.fromJson(result.getBodyResult(), BdWeatherDTO.class); 
            WeatherInfoDTO bdResult = bdWeatherInfo.getResult(); 
            //将天气信息持久化到数据库中 
            if(null != bdResult) { 
                Long weatherId = IdWorker.getId(); 
                bdResult.getWeatherNow().setPkId(weatherId); 
                bdResult.getWeatherNow().setLocationCode(areaCode); 
                weatherService.insertWeatherInfo(bdResult); 
            } 
            Thread.sleep(1500 + random.nextInt(1000)); 
        } 
    } 
}

运行以上代码即可实现省域区县天气的入库处理。

2、区县名称不一致

由于区县信息和城市信息的采集和整理的时候可能存在不一致的情况。比如在行政区划调整的过程,有的县级名称可能会改成区,以长沙市为例,望城县就改成了望城区。在区县信息表中名称为望城区,而在城市信息表中可能还叫望城县,为了保证在查询能关联查到,因此需要将两张表的数据进行清理统一,修改方法可以参考相关的官方名称,修改成统一的名称即可。

三、SpringBoot 后台实现

本文采用 SpringBoot 框架为 WebGIS 提供后台服务,主要涉及的功能有天气数据查询的实现。主要从以下两个方面来进行,第一个是后台的天气的数据查询实现,第二个是 Java 的控制层的具体实现。

1、Java 后台天气数据查询

使用 Java 进行区县天气数据查询比较简单,首先基于 MybatisPlus 需要定义数据视图对象,关键的 Java 代码如下所示:

package com.yelang.project.meteorology.mapper; 
import java.util.List; 
import org.apache.ibatis.annotations.Param; 
import org.apache.ibatis.annotations.Select; 
import com.baomidou.mybatisplus.core.mapper.BaseMapper; 
import com.yelang.project.meteorology.domain.AreaWeatherVO; 
import com.yelang.project.meteorology.domain.WeatherNow; 

public interface WeatherNowMapper extends BaseMapper<WeatherNow>{ 
    final static String GET_WEATHER_BYPROVINCE_ANDDAY = "<script>" + 
        " SELECT t2.*,T.province_code,T.province_name,T.city_code,T.city_name,T.area_code,T.area_name, " + 
        " t1.geom,st_asgeojson ( T.geom ) geomJson,st_x ( t1.geom ) lon,st_y ( t1.geom ) lat " + 
        " FROM biz_weather_now t2,biz_area T,biz_geographic_name t1 " + 
        " WHERE to_char( t2.uptime, 'YYYY-MM-DD' ) = #{day} AND T.province_code = #{provinceCode} " + 
        " AND T.area_name = t1.NAME AND T.area_code = t2.location_code AND st_contains(t.geom, t1.geom) " + 
        " ORDER BY t.area_code " + 
        "</script>"; 
    /** * - 根据省份和日期查询区县城市天气视图对象列表 * @return */ 
    @Select(GET_WEATHER_BYPROVINCE_ANDDAY) 
    List<AreaWeatherVO> getWeatherByProvinceAndday(@Param("provinceCode") String provinceCode,@Param("day") String day); 
}

查询结果对应的视图对象代码如下,为了最大程度的实现对象的复用,视图对象集成了实时天气对象 JavaBean:

package com.yelang.project.meteorology.domain; 
import java.io.Serializable; 
import com.baomidou.mybatisplus.annotation.TableField; 
import lombok.Data; 
import lombok.EqualsAndHashCode; 
import lombok.ToString; 

@Data 
@ToString(callSuper=true)//callSuper=true 表示输出父类属性 
@EqualsAndHashCode(callSuper=false) 
public class AreaWeatherVO extends WeatherNow implements Serializable{ 
    private static final long serialVersionUID = -7559774548761847068L; 
    @TableField(exist = false,value= "province_code") 
    private String provinceCode; 
    @TableField(exist = false,value= "province_name") 
    private String provinceName; 
    @TableField(exist = false,value= "city_code") 
    private String cityCode; 
    @TableField(exist = false,value= "city_name") 
    private String cityName; 
    @TableField(exist = false,value= "area_name") 
    private String areaName; 
    @TableField(exist = false) 
    private String geomJson; 
    private String lat; 
    private String lon; 
}

2、控制层实现

控制层作为接收前端的请求并且返回响应数据的重要组件,这里主要提供展示界面的跳转以及区县天气数据列表的获取,核心代码如下:

package com.yelang.project.meteorology.controller; 
import java.util.List; 
import org.apache.shiro.authz.annotation.RequiresPermissions; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.ResponseBody; 
import com.yelang.framework.web.controller.BaseController; 
import com.yelang.framework.web.domain.AjaxResult; 
import com.yelang.project.meteorology.domain.AreaWeatherVO; 
import com.yelang.project.meteorology.service.IWeatherNowService; 

@Controller 
@RequestMapping("/met/province/weather") 
public class ProvinceWeatherController extends BaseController{ 
    private String prefix = "meteorology/weather"; 
    @Autowired 
    private IWeatherNowService weatherNowService; 
    
    @RequiresPermissions("met:province:weather:map") 
    @GetMapping("/province") 
    public String province(){ 
        return prefix + "/province"; 
    } 
    
    @RequiresPermissions("met:province:weather:list") 
    @GetMapping("/list/{pcode}") 
    @ResponseBody 
    public AjaxResult ewsnProvinceList(@PathVariable("pcode") String pcode){ 
        String day = "2025-08-17"; 
        List<AreaWeatherVO> dataList = weatherNowService.getWeatherByProvinceAndday(pcode,day); 
        return AjaxResult.success().put("data", dataList); 
    } 
}

四、WebGIS 前端实现

在众多可用于 WebGIS 开发的工具和库中,Leaflet 凭借其轻量级、易上手、功能强大且高度可定制的特点脱颖而出,成为众多开发者在地理信息可视化项目中的首选工具之一。本节将重点介绍如何使用 Leaflet 来进行 WebGIS 开发和实现。在面向天气的应用中,主要进行气温颜色和数据的展示两个部分。

1、气温颜色及图例初始化

为了直观的展示天气的气温信息,我们首先对气温的值、颜色、气温描述等信息进行定义。气温颜色色带(colormap)是一种常用的工具,用于将数值范围映射到颜色范围。以下是详细的气温颜色色带表格:

气温范围 (℃)颜色描述十六进制颜色代码RGB 颜色表示 (R, G, B)
45℃以上深红色#8B0000(139, 0, 0)
40℃ - 45℃红色#FF0000(255, 0, 0)
35℃ - 40℃橙红色#FF4500(255, 69, 0)
30℃ - 35℃橙色#FFA500(255, 165, 0)
25℃ - 30℃黄色#FFFF00(255, 255, 0)
20℃ - 25℃浅绿色#90EE90(144, 238, 144)
15℃ - 20℃绿色#00FF00(0, 255, 0)
10℃ - 15℃青色#00FFFF(0, 255, 255)
5℃ - 10℃浅蓝色#ADD8E6(173, 216, 230)
0℃ - 5℃蓝色#0000FF(0, 0, 255)
-5℃ - 0℃深蓝色#4169E1(65, 105, 225)
-10℃ - -5℃紫色#800080(128, 0, 128)
-15℃ - -10℃深紫色#4B0082(75, 0, 130)
-20℃ - -15℃黑色#000000(0, 0, 0)

在 JavaScript 中定义以上信息:

//气温及颜色配置 
var weatherColorList = [ 
    {name:"-20℃ - -15℃",color:"#000000",rgb:new Color(0,0,0),colorDesc:"黑色"}, 
    {name:"-15℃ - -10℃",color:"#4B0082",rgb:new Color(75,0,130),colorDesc:"深紫色"}, 
    {name:"-10℃ - -5℃",color:"#800080",rgb:new Color(128,0,128),colorDesc:"紫色"}, 
    {name:"-5℃ - 0℃",color:"#4169E1",rgb:new Color(65,105,225),colorDesc:"深蓝色"}, 
    {name:"0℃ - 5℃",color:"#0000FF",rgb:new Color(0,0,255),colorDesc:"蓝色"}, 
    {name:"5℃ - 10℃",color:"#ADD8E6",rgb:new Color(173,216,230),colorDesc:"浅蓝色"}, 
    {name:"10℃ - 15℃",color:"#00FFFF",rgb:new Color(0,255,255),colorDesc:"青色"}, 
    {name:"15℃ - 20℃",color:"#00FF00",rgb:new Color(0,255,0),colorDesc:"绿色"}, 
    {name:"20℃ - 25℃",color:"#90EE90",rgb:new Color(144,238,144),colorDesc:"浅绿色"}, 
    {name:"25℃ - 30℃",color:"#FFFF00",rgb:new Color(255,255,0),colorDesc:"黄色"}, 
    {name:"30℃ - 35℃",color:"#FFA500",rgb:new Color(255,165,0),colorDesc:"橙色"}, 
    {name:"35℃ - 40℃",color:"#FF4500",rgb:new Color(255,69,0),colorDesc:"橙红色"}, 
    {name:"40℃ - 45℃",color:"#FF0000",rgb:new Color(255,0,0),colorDesc:"红色"}, 
    {name:"45℃以上",color:"#8B0000",rgb: new Color(139,0,0),colorDesc:"深红色"} 
];

在 WebGIS 中需要使用色带即 colorMap 的方式对气温颜色进行定义,同时在地图中展示相应的图例(需要注意的是,这里的气温极值取 -20 和 45 度,这两个值在实际生活中可能有所调整,大家自己灵活处理),定义的关键代码如下:

var DIY_BLUE_GREEN_YELLOW_RED_SCHEME; 
$(document).ready(function () { 
    initSidebar(); 
    var legendData = new Array(); 
    var colorArray = new Array(); 
    for(var i=0;i<weatherColorList.length;i++){ 
        var _tempData = weatherColorList[i]; 
        legendData.push({ label: "\xa0\xa0"+_tempData.name , type: "rectangle", radius: 12, color: _tempData.color, fillColor: _tempData.color, fillOpacity: 0.8, weight: 2}); 
    } 
    colorArray.push(_tempData.rgb); 
    DIY_BLUE_GREEN_YELLOW_RED_SCHEME = new MultiColorScheme('', -20,45 ,colorArray); 
    initLegend(legendData); 
});

2、气温数据展示实现

为了方便对气温数据进行展示,同时考虑到区县数量是比较多的,因此在标绘展示时不要让中文标签被遮挡住,因此这里我们采用碰撞检测组件来进行辅助提升可视化效果,碰撞组件定义如下:

var collisionLayer = L.LayerGroup.collision({margin:2});

定义好碰撞组件后,接下来可以实现对气温数据展示,关键代码如下:

function previewWeather(pid,provinceCode,name){ 
    previewProvince(pid,name); 
    $.ajax({ 
        type:"get", 
        url:ctx + "/met/province/weather/list/" + provinceCode, 
        data:{}, 
        dataType:"json", 
        cache:false, 
        processData:false, 
        success:function(result){ 
            if(result.code == web_status.SUCCESS){ 
                $("#title_info").html(name+"天气实况<sub>更新时间:20250817" +"</sub>"); 
                collisionLayer.clearLayers(); 
                var dataArray = result.data; 
                if(dataArray != null && dataArray.length > 1){ 
                    var legendData = new Array(); 
                    for(var i=0;i< dataArray.length;i++){ 
                        var areaData = dataArray[i]; 
                        var color = makeColor(areaData.temp,-20,45,DIY_BLUE_GREEN_YELLOW_RED_SCHEME); 
                        var areaLayer = L.geoJSON(JSON.parse(areaData.geomJson),{style: {color:color,fillColor:color,weight:3,"opacity":0.65, fillOpacity: 0.65 }}).addTo(mymap); 
                        var myIcon = L.divIcon({ iconSize: null, className: '', popupAnchor:[5,5], shadowAnchor:[5,5], html: buildShowInfo(i,color,areaData) }); 
                        showLayerGroup.addLayer(areaLayer); 
                        //中心点位 
                        L.marker([areaData.lat, areaData.lon], { icon: myIcon}).addTo(collisionLayer); 
                        collisionLayer.addTo(showLayerGroup); 
                    } 
                } 
            }, 
            error:function(){ 
                $.modal.alertWarning("获取空间信息失败"); 
            } 
        }); 
}

五、成果展示

本节将主要描述 WebGIS 的区县天气展示,这里我们从湖南省和西藏自治区两个地区来进行展示。湖南省应该是一个比较典型的气温高的省份,而西藏则是气温比较低的省份。同时可以对比以下实际的色温展示成果。

1、湖南省天气展示

从整体来看,湖南 8 月 17 日 8 点左右的全省气温信息比之前的要好多了(整体范围从 20 度到 29 度,均小于 23 度),温差变大,体感舒适度有所提高了。接下来我们从低温前五和高温前五来看下,首先看下低温前 5 是哪些区县:

湖南省 郴州市 桂东县 20.00 
湖南省 衡阳市 南岳区 21.00 
湖南省 郴州市 汝城县 21.00 
湖南省 湘西土家族苗族自治州 花垣县 21.00 
湖南省 株洲市 炎陵县 22.00

气温从高到低前 5 区县是:

湖南省 岳阳市 岳阳楼区 29.00 
湖南省 岳阳市 云溪区 29.00 
湖南省 益阳市 资阳区 29.00 
湖南省 益阳市 赫山区 29.00 
湖南省 岳阳市 君山区 29.00

2、西藏自治区天气展示

从整体来看,西藏自治区 8 月 17 日 8 点左右的全省气温信还是比较低,这跟其高海拔有关系(整体范围从 2 度到 21 度,跨度还是非常大的)。接下来我们从低温前五和高温前五来看下,首先看下低温前 5 是哪些区县:

西藏自治区 那曲市 嘉黎县 2.00 
西藏自治区 山南市 错那县 4.00 
西藏自治区 日喀则市 亚东县 4.00 
西藏自治区 山南市 措美县 4.00 
西藏自治区 昌都市 芒康县 5.00

气温从高到低前 5 区县是:

西藏自治区 林芝市 墨脱县 21.00 
西藏自治区 林芝市 朗县 14.00 
西藏自治区 林芝市 察隅县 14.00 
西藏自治区 林芝市 波密县 14.00 
西藏自治区 山南市 曲松县 14.00

可以看到,在西藏的林芝市,其气温跟湖南是差不多的,而且林芝市温度最高的是墨脱县。不得不说,林芝市的气温是真不错,不愧是西藏江南。

六、总结

本文旨在为读者提供一份系统、实用的省域区县天气可视化实战攻略,帮助读者掌握基于 Leaflet 和 WebGIS 技术实现天气可视化的完整流程和关键技巧。通过本文的阅读,无论你是 GIS 领域的专业人士,还是对 Web 开发和地理信息可视化感兴趣的初学者,都将能够对基于 Leaflet 的省域区县天气可视化有一个全面而深入的了解,并掌握实现这一目标的具体方法和技巧。

目录

  1. 一、空间数据基础
  2. 1、省域空间检索
  3. 2、区县天气信息检索
  4. 二、天气数据简介
  5. 1、省域天气数据获取
  6. 2、区县名称不一致
  7. 三、SpringBoot 后台实现
  8. 1、Java 后台天气数据查询
  9. 2、控制层实现
  10. 四、WebGIS 前端实现
  11. 1、气温颜色及图例初始化
  12. 2、气温数据展示实现
  13. 五、成果展示
  14. 1、湖南省天气展示
  15. 2、西藏自治区天气展示
  16. 六、总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Spring Boot 与 Vue 实现 WebSocket 实时游戏匹配系统
  • 基于 SpringBoot 的电影院票务预定系统设计
  • 基于 YOLO12 的无人机航拍视角目标检测系统
  • 移动前端与 Web 前端开发的核心差异解析
  • 为何部分资深开发者对 Python 持保留态度?
  • Milvus 实战:Attu 可视化安装与 Python 整合指南
  • 垂直微调大模型与通用大模型在情感场景下的能力对比分析
  • LeetCode 移除元素与轮转数组解题思路
  • 大模型微调七步法:构建垂直领域专用模型
  • 动态规划实战:斐波那契变体与经典题目解析
  • Python GUI 开发指南:Tkinter 与 PyQt5 对比及安装教程
  • Stable Diffusion v1.5 提示词与负向提示词实战指南
  • 大模型与人类交流的底层原理
  • GitHub Copilot 学生认证零基础入门指南
  • OpenClaw 多飞书机器人配置指南
  • 低代码 + 决策流:破解企业数字化效率瓶颈
  • 【Java】Gradle 多模块项目实战:Spring Boot 微服务搭建全流程
  • 中国电信发布星辰语音大模型 支持 30 种方言混说
  • 使用 Langchain-Chatchat 部署私有化 RAG 知识库指南
  • 无线蜂窝网络:从原理到 6G 演进

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online