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

十大火炉城市体感温度实时对比(WebGIS 实现)

利用百度天气接口抓取 2025 年 8 月 30 日下午 1 点的数据,结合 WebGIS 与空间数据库,对十大火炉城市的体感温度进行可视化对比。结果显示杭州、南京、南昌体感温度 38℃,长沙 37℃,武汉、福州 35℃;西安和重庆反而凉爽,西安仅 21℃。技术实现上通过 Java 后端关联城市区域、点位与天气表,前端用 Leaflet 渲染分层地图,代码中硬编码城市代码仅为演示方便。整体呈现了火炉城市在同一天内的“火力”差异,但单日数据不能代表整个夏季的炎热程度。

霸天发布于 2026/6/20更新于 2026/10/1963 浏览
十大火炉城市体感温度实时对比(WebGIS 实现)

'火炉城市'这个说法最早是民国时期媒体对长江沿线重庆、武汉、南京的叫法,后来演变成'四大火炉'等不同版本。2017 年中国气象局国家气候中心发布过一份权威排名,夏季炎热程度前 10 的省会/直辖市依次是:重庆、福州、杭州、南昌、长沙、武汉、西安、南京、合肥、南宁。

文章配图

这份名单和民间感受出入不大,但体感温度才是实际的'火力'指标——同一气温下湿度、风速、城市热岛效应会把体感拉开很大差距。我刚好手头在跑一个关联实时天气的 WebGIS 项目,顺手把 2025 年 8 月 30 日下午 1 点这 10 个城市的体感温度拉出来做了个可视化,看看谁还在蒸笼里、谁已经入秋。

为什么长江流域总出火炉

这 10 个城市有 8 个沿长江分布,只有西安在黄河流域,南宁在珠江水系。共同点大多是河谷、盆地地形,空气流通差。重庆四周被大巴山、巫山等山脉包住,夏季热量散不出去;武汉河湖密布,水汽蒸发把湿度推高;长沙则受湘江流域和焚风效应双重影响。再加上城市热岛效应——比如武汉城区夏季能比郊区高出 3-5℃——体感就更加难熬。

数据怎么来的

分析用的数据分两类:空间数据和天气数据。

序号数据说明
1城市区域范围表 biz_city地级市 Polygon 面数据
2城市点位信息表 biz_geographic_name地名 Point 数据
3城市天气信息表百度实时天气接口,抓取时刻:2025-08-30 13:00 左右

下面这张表是后续查询的基础,把城市名和行政区划代码对应起来:

序号行政区划代码城市名称
1360100南昌市
2500000重庆市
3330100杭州市
4320100南京市
5420100武汉市
6340100合肥市
7350100福州市
8450100南宁市
9430100长沙市
10610100西安市

技术路线不复杂:通过百度天气接口把实时数据缓存到本地,再用空间查询把城市区域、点位和天气关联起来,最后丢给 Leaflet 渲染。

文章配图

后端:一个关联查询的 Mapper

核心 SQL 就是根据当天的日期(2025-08-30)和城市代码,从 biz_weather_now、biz_city、biz_geographic_name 三张表里捞出每个城市的体感温度(feels_like)以及坐标、GeoJSON。为了演示方便,我把 10 个城市代码直接写死在 SQL 的 IN 条件里了——实际项目里还是得传参数,扩展性会好很多。

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_THREEFURNACES_INFO = "<script>" +
        " SELECT t2.*,T.province_code,T.province_name,T.city_code,T.city_name, " +
        " st_asgeojson ( T.geom ) geomJson,st_x ( t1.geom ) lon,st_y ( t1.geom ) lat " +
        " FROM biz_weather_now t2,biz_city T,biz_geographic_name t1 " +
        " WHERE to_char( t2.uptime, 'YYYY-MM-DD' ) = #{day} " +
        " AND t2.location_code in ('350100','330100','360100','430100','420100','610100','320100','340100','450100','500000') " +
        " AND T.city_name = t1.NAME AND T.city_code = t2.location_code ORDER BY t2.feels_like desc " +
        "</script>";

    @Select(GET_THREEFURNACES_INFO)
    List<AreaWeatherVO> getThreeFurnacesInfo(@Param("day") String day);
}

Controller 很简单,直接返回 JSON 给前端:

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.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/threefurnaces/weather")
public class ThreeFurnacesController extends BaseController{
    private String prefix = "meteorology/weather";
    @Autowired
    private IWeatherNowService weatherNowService;

    @RequiresPermissions("met:threefurnaces:weather:map")
    @GetMapping("/index")
    public String index(){
        return prefix + "/threefurnacesmap";
    }

    @RequiresPermissions("met:threefurnaces:weather:list")
    @GetMapping("/list")
    @ResponseBody
    public AjaxResult list(){
        String day = "2025-08-30";
        List<AreaWeatherVO> dataList = weatherNowService.getThreeFurnacesInfo(day);
        return AjaxResult.success().put("data", dataList);
    }
}

前端:Leaflet 分层渲染

前端用 Leaflet。后端返回每个城市的 GeoJSON 范围、中心点坐标和体感温度,然后根据温度值从蓝绿黄红渐变中取一个颜色,分别填充区域和标记点。体感温度数值直接用 DivIcon 贴在中心点上。代码不长,核心就是遍历数据画多边形和标记:

function previewWeather(pid,provinceCode,name){
    $.ajax({
        type:"get",
        url:ctx + "/met/threefurnaces/weather/list",
        data:{},
        dataType:"json",
        cache:false,
        processData:false,
        success:function(result){
            if(result.code == web_status.SUCCESS){
                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.feelsLike,-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("获取空间信息失败");
        }
    });
}

结果:谁在蒸,谁已经凉了

所有城市展开看分布,大部分集中在东南部的长江中下游。体感温度前几名:杭州 38℃、南京 38℃、南昌 38℃,长沙 37℃;武汉和福州都是 35℃,南京实际测下来 32℃(当天短时回落)。西安和重庆反而舒服——西安体感才 21℃ 左右,有点秋天的意思了。

文章配图

8 月底了,长三角依然火力十足。杭州、南京、南昌这三个同处 38℃ 的城市,加上 37℃ 的长沙,构成了'蒸烤核心区'。想起以前在武汉汉口火车站转车去上海的体验,盛夏候车厅确实像蒸笼。经济热度最高的长三角,天气也跟着高烧不退。

文章配图

重庆和西安是意外。重庆作为传统火炉,当日体感温度降到 30℃ 以下,西安更是只有 21℃ 左右——可能是纬度偏高加上冷空气渗透,已经开始向秋天过渡。

文章配图

这个项目就是把实时天气和空间数据绑在一起,用 WebGIS 可视化出来。硬编码城市代码的写法只适合演示,线上环境应该抽象成参数。数据只是 8 月 30 日这一个时间切片,不代表整个夏季的累积热度,有兴趣可以按天拉长对比,会更全面。

目录

  1. 为什么长江流域总出火炉
  2. 数据怎么来的
  3. 后端:一个关联查询的 Mapper
  4. 前端:Leaflet 分层渲染
  5. 结果:谁在蒸,谁已经凉了

更多推荐文章

查看全部
  • TrendRadar 本地部署指南:构建个人 AI 热点情报系统
  • Node.js+Vue 公租房管理系统设计与实现
  • 2024 最新 AI 大模型产品与工具汇总
  • 基于 Milvus 与混合检索的云厂商文档智能问答系统:Java SpringBoot 实践
  • OpenClaw 跨平台 AI 助手完全使用指南:从入门到精通
  • 利用 MaaS 平台 API 构建本地智能 AI 助手
  • C++11 详解:列表初始化与右值引用移动语义
  • Spring Boot 3.x 新特性解析:Java 17 支持与 GraalVM 原生镜像
  • OpenBCI + OpenViBE + Python: 实时运动想象小球控制系统
  • Midjourney Imagine API 申请流程与使用详解
  • 大模型技术原理与应用指南:从入门到精通
  • AI 图像生成指南:从原理到实战
  • llama.cpp 量化模型部署:从模型转换到 API 服务
  • C++ Qt 网络编程:QUdpSocket、QTcpSocket 与 Http 实战
  • Copilot 配置中那些容易踩的坑及应对思路
  • 基于ASR的语音切分与说话人区分实战:算法选型与生产部署
  • Llama 与 PyTorch:大模型开发与优化的核心组合
  • 主流 AI 生成 UI 设计工具盘点:支持可编辑源文件与代码导出
  • AgentScope Java 集成 Spring AI Alibaba Workflow 指南
  • C++ 继承:面向对象代码复用的核心机制

相关免费在线工具

  • 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