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

基于 WebGIS 实现 80 年代风格老式天气预报系统

综述由AI生成如何利用现代技术构建具有 80 年代风格的天气预报系统。首先通过 SQL 查询获取全国省会城市空间信息,并在 Java 后台封装查询接口。其次集成百度天气开放平台 API,根据经纬度获取实时及预报数据。最后使用 Leaflet 框架在 WebGIS 中展示城市标记、天气信息及轮播动画,并集成背景音乐。项目结合了后端数据处理与前端可视化技术,实现了复古风格的天气播报功能。

LinuxPan发布于 2026/4/5更新于 2026/5/2437 浏览
基于 WebGIS 实现 80 年代风格老式天气预报系统

前言

在数字技术飞速发展的今天,我们常常沉浸于各种高科技带来的便捷与震撼之中,却容易忽视那些曾经陪伴我们成长、承载着时代记忆的旧事物。80 年代的天气预报,便是这样一份珍贵的文化遗产。WebGIS 技术的出现,为我们提供了这样一个绝佳的机会。它能够将地理信息与网络技术相结合,实现地图的可视化展示和数据的动态交互。而百度天气作为国内领先的天气数据服务平台,提供了丰富而准确的天气信息。将两者相结合,我们或许能够构建出一个既具有 80 年代风格,又融合了现代技术优势的天气预报系统。

文章配图

我们的目标是构建一个能够唤醒 80 年代记忆的老式天气预报系统。这个播报系统需要播放我们熟悉的天气预报背景音乐。在播报形式上,播报内容将涵盖基本的天气信息,如温度、时间和明日天气等。尽管界面和播报形式是 80 年代的风格,但数据来源却是现代的。我们将整合百度天气提供的实时数据,确保天气信息的准确性和及时性。通过 WebGIS 技术,我们可以在地图上直观地展示不同地区的天气情况,用户可以通过简单的操作查看全国各地的天气预报。

在构建这样一个系统的过程中,我们面临着诸多技术挑战。为此,我们将采用现代的前端开发技术,如 HTML5、CSS3 和 JavaScript,结合 WebGIS 框架,实现一个既复古又现代的界面。其次,80 年代的语音播报风格与现代的语音合成技术存在较大差异。此外,我们还需要编写一套符合当时风格的播报脚本,确保播报内容的准确性和趣味性。最后,整合百度天气数据并将其与 WebGIS 地图相结合,需要解决数据格式转换、地图渲染优化等问题。我们将利用 WebGIS 平台提供的数据接口和地图渲染工具,实现数据的无缝对接和高效展示。

一、省会城市信息构建

在进行省会城市天气预报的 WebGIS 可视化开发之前,首先我们需要对全国的省会城市信息进行查询。在后面调用百度天气接口时也需要使用省会城市名称。因此这里首先介绍如何查询省会城市空间信息以及如何在 Java 中进行后台的城市信息查询。

1、省会城市空间查询

在之前的文章中,我们介绍了城市点位信息和省份信息,在进行省会城市信息查询时,也同样需要使用这几张表。查询语句如下:

SELECT T.NAME cityName, T.pinYin, T.bz, T.slx, tc.code provinceCode, tc.NAME provinceName, st_x(T.geom) cityLon, st_y(T.geom) cityLat, dict.dict_label provinceAbbreviations, st_asgeojson(tc.geom) geomJson 
FROM biz_geographic_name T, biz_province tc, sys_dict_data dict 
WHERE T.bz IN ('省会城市', '直辖市', '首都') AND st_contains(tc.geom, T.geom) AND dict.dict_value = tc.code 
ORDER BY tc.code

在 Navicat 客户端中执行以上语句后,可以在客户端看到以下查询结果:

文章配图

在后面的操作中,我们就需要使用这个返回结果中的省会城市的中心点经纬度的位置来进行天气的查询,最后返回给前台进行使用。

2、Java 后台查询

在 SQL 中实现上述的查询之后,接下来我们就可以将相关的查询逻辑封装成 Java 接口,来供前端调用。在 Java 中的 Mapper 类来实现以上的查询服务,Mapper.java 的核心代码如下:

static final String FIND_PROVINCEABBREVIATIONS_LIST = "<script>" + " SELECT T.name cityName,T.pinYin,T.bz,T.slx,tc.code provinceCode,tc.NAME provinceName, " + " st_x(T.geom) cityLon,st_y(T.geom) cityLat,dict.dict_label provinceAbbreviations, " + " st_asgeojson(tc.geom) geomJson " + " FROM biz_geographic_name T,biz_province tc,sys_dict_data dict " + " WHERE T.bz IN('省会城市', '直辖市', '首都') AND st_contains(tc.geom, T.geom) AND dict.dict_value = tc.code " + " order by tc.code " + "</script>";
@Select(FIND_PROVINCEABBREVIATIONS_LIST)
List<ProvinceAbbreviationsVo> findProvinceAbbreviations();

当然,为了方便方法的复用,这里我们将 Mapper 的查询能力封装成一个通用的方法,在 Service 中进行实现,通过提供对外方法,供第三方服务进行调用。Service 的调用比较简单,代码如下:

@Override
public List<ProvinceAbbreviationsVo> findProvinceAbbreviations() {
    return this.baseMapper.findProvinceAbbreviations();
}

最后实现一个 Controller 来将 Service 的服务接口对外提供出来。

二、Java 省会城市天气查询

有了这个查询省会天气的服务之后,接下来我们就可以根据不同省会城市的经纬度,利用百度天气接口的国内经纬度查询能力,直接返回对应城市的天气以及未来的天气预报。本节就来深入介绍一下如何使用经纬度来进行查询天气,并且对相应对象的属性进行一个简单的介绍。

1、与百度开放平台集成天气

为了实现根据省会城市的经纬度来查询所在城市的天气信息,首先我们需要定义百度天气接口的方法,定义方法如下:

/**
 * - 根据经纬度和坐标类型查询指定地点的天气信息
 * @param location 经纬度,经度在前纬度在后,逗号分隔。支持类型:bd09mc/bd09ll/wgs84/gcj02
 * @param data_type 请求数据类型。数据类型有:now/fc/index/alert/fc_hour/all,控制返回内容,默认值无
 * @param coordtype 支持类型:wgs84/bd09ll/bd09mc/gcj02 默认值:wgs84
 * @return
 */
@GetHttpInterface("/")
public HttpResponse<String> getByLocation(@QueryPar("location") String location, @QueryPar("data_type") String data_type, @QueryPar("coordtype") String coordtype);

有了这个接口之后,接下来我们就可以从前面获取的省会城市列表中来进行循环调用,传入省会城市的经纬度位置就可以实现天气情况的查询。调用实例代码如下:

/**
 * 获取省会城市天气预报信息
 * @throws InterruptedException
 */
@Test
public void testGetProvinceWeather() throws InterruptedException {
    Random random = new Random();
    List<LinkedHashMap<String, Object>> provinceWeatherData = new ArrayList<LinkedHashMap<String, Object>>(34);
    List<ProvinceAbbreviationsVo> provinceList = geographicNameService.findProvinceAbbreviations();
    Gson gson = new Gson();
    for (ProvinceAbbreviationsVo vo : provinceList) {
        //经纬度,经度在前纬度在后,逗号分隔。
        String location = vo.getCityLon() + "," + vo.getCityLat();
        //lat:39.066114,lon:117.213135,w_name:"晴",city:"天津",temp:"3-14",color:"#03a9f4",two:"11/22 3-12"
        HttpResponse<String> result = baiduWeatherApiService.getByLocation(location, DATA_TYPE, "wgs84");
        if(StringUtils.isNotEmpty(result.getBodyResult())) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("lat", vo.getCityLat());
            map.put("lon", vo.getCityLon());
            map.put("city", vo.getCityName());
            BdWeatherDTO bdWeatherInfo = gson.fromJson(result.getBodyResult(), BdWeatherDTO.class);
            WeatherInfoDTO weatherInfoDTO = bdWeatherInfo.getResult();
            map.put("w_name", weatherInfoDTO.getWeatherNow().getText());
            List<WeatherForecasts> forecasts = weatherInfoDTO.getForecasts();
            if(StringUtils.isNotEmpty(forecasts)) {
                WeatherForecasts today = forecasts.get(0);
                map.put("temp", today.getLow() + "-" + today.getHigh());
                WeatherForecasts tomorrow = forecasts.get(1);
                Date tempDate = tomorrow.getDate();
                String two = (tempDate.getMonth() + 1) + "-" + tempDate.getDate() + " " + tomorrow.getLow() + "-" + tomorrow.getHigh();
                map.put("two", two);
            }
            provinceWeatherData.add(map);
        }
        Thread.sleep(1500 + random.nextInt(1000));
    }
    String weatherStr = gson.toJson(provinceWeatherData);
    System.out.println(provinceWeatherData);
    System.out.println(weatherStr);
}

需要说明的是,这里采用线程休眠的原因是为了避免造成并发调用。当然,如果您的账号权限比较高,不受并发的限制就无所谓了。

2、响应对象属性介绍

为了方便标注,实现省会城市的实时天气信息展示以及未来一天的天气情况展示,需要定义一个标准的响应对象,通过上述代码可以看出我们使用一个 hashmap 来进行实现。示例如下:

{
  "lat":"39.903162481",
  "lon":"116.401006456",
  "city":"北京市",
  "w_name":"晴",
  "temp":"-2-10",
  "two":"12-8 -4-5"
}
序号参数名称说明
1lat纬度
2lon经度
3city城市名称
4w_name天气说明
5temp气温
6two明日天气

3、省会天气实况展示

这里以 12 月 7 日为例,使用上述程序查询出来 12 月 7 日到 12 月 8 日两天的省会城市天气预报数据如下:

[
{"lat":"39.903162481","lon":"116.401006456","city":"北京市","w_name":"晴","temp":"-2-10","two":"12-8 -4-5"},
{"lat":"39.083383854","lon":"117.193764008","city":"天津市","w_name":"晴","temp":"-2-11","two":"12-8 -2-5"},
{"lat":"38.041795673","lon":"114.509022491","city":"石家庄市","w_name":"晴","temp":"0-15","two":"12-8 -2-7"},
{"lat":"37.8699777370001","lon":"112.543459413","city":"太原市","w_name":"晴","temp":"-8-9","two":"12-8 -7-6"},
{"lat":"40.84174369","lon":"111.742890453","city":"呼和浩特市","w_name":"多云","temp":"-14--1","two":"12-8 -10-0"},
{"lat":"41.8043596680001","lon":"123.425789521","city":"沈阳市","w_name":"晴","temp":"-8-5","two":"12-8 -7-1"},
{"lat":"43.8149938920001","lon":"125.31766745","city":"长春市","w_name":"晴","temp":"-12-0","two":"12-8 -11--4"},
{"lat":"45.8019539320001","lon":"126.528652017","city":"哈尔滨市","w_name":"多云","temp":"-18--5","two":"12-8 -21--8"},
{"lat":"31.2318491390001","lon":"121.46965015","city":"上海市","w_name":"霾","temp":"10-20","two":"12-8 7-16"},
{"lat":"32.06249645","lon":"118.792223921","city":"南京市","w_name":"晴","temp":"6-19","two":"12-8 4-15"},
{"lat":"30.276062563","lon":"120.15030306","city":"杭州市","w_name":"晴","temp":"9-19","two":"12-8 7-17"},
{"lat":"31.823360144","lon":"117.222184326","city":"合肥市","w_name":"晴","temp":"3-18","two":"12-8 1-14"},
{"lat":"26.0772329970001","lon":"119.291018877","city":"福州市","w_name":"多云","temp":"14-24","two":"12-8 14-23"},
{"lat":"28.6855336350001","lon":"115.85297824","city":"南昌市","w_name":"多云","temp":"11-20","two":"12-8 10-19"},
{"lat":"36.6655797230001","lon":"116.988607998","city":"济南市","w_name":"晴","temp":"-1-15","two":"12-8 5-10"},
{"lat":"34.7474463120001","lon":"113.620086008","city":"郑州市","w_name":"晴","temp":"1-18","two":"12-8 0-11"},
{"lat":"30.5951977820001","lon":"114.299439726","city":"武汉市","w_name":"雾","temp":"3-18","two":"12-8 3-17"},
{"lat":"28.230799873","lon":"112.934511917","city":"长沙市","w_name":"霾","temp":"8-18","two":"12-8 7-17"},
{"lat":"23.1306783370001","lon":"113.259864444","city":"广州市","w_name":"多云","temp":"14-25","two":"12-8 13-25"},
{"lat":"22.819317503","lon":"108.362490315","city":"南宁市","w_name":"多云","temp":"15-23","two":"12-8 14-24"},
{"lat":"20.050034829","lon":"110.196179915","city":"海口市","w_name":"晴","temp":"18-25","two":"12-8 19-25"},
{"lat":"29.566484528","lon":"106.546994525","city":"重庆市","w_name":"晴","temp":"9-15","two":"12-8 11-17"},
{"lat":"30.574891279","lon":"104.06431153","city":"成都市","w_name":"晴","temp":"6-18","two":"12-8 8-13"},
{"lat":"26.6496315200001","lon":"106.626281501","city":"贵阳市","w_name":"多云","temp":"4-12","two":"12-8 7-15"},
{"lat":"24.88255573","lon":"102.830594244","city":"昆明市","w_name":"多云","temp":"4-16","two":"12-8 6-17"},
{"lat":"29.6558675410001","lon":"91.1700828420001","city":"拉萨市","w_name":"晴","temp":"-5-13","two":"12-8 -4-12"},
{"lat":"34.3431558230001","lon":"108.935725754","city":"西安市","w_name":"晴","temp":"2-14","two":"12-8 2-13"},
{"lat":"36.0614637570001","lon":"103.831432958","city":"兰州市","w_name":"晴","temp":"-6-7","two":"12-8 -5-8"},
{"lat":"36.6168144980001","lon":"101.775387587","city":"西宁市","w_name":"晴","temp":"-10-6","two":"12-8 -7-6"},
{"lat":"38.4870919210001","lon":"106.226758099","city":"银川市","w_name":"多云","temp":"-3-6","two":"12-8 -5-8"},
{"lat":"43.8255140370001","lon":"87.6149638000001","city":"乌鲁木齐市","w_name":"大雾","temp":"-6-1","two":"12-8 -7--1"},
{"lat":"25.036365684","lon":"121.563739724","city":"台北市","w_name":"多云","temp":"17-23","two":"12-8 18-21"}
]

三、WebGIS 应用构建

本节将重点介绍如何在 WebGIS 中进行应用的构建,在使用百度天气创建好相应的省会城市列表的天气信息后,接下来要做的就是要集成经典的天气预报北京音乐,同时使用 Leaflet 来标注所有的省会城市位置,并且要展示天气信息,最后要根据位置来实现城市的轮播展示。

1、背景音乐集成

背景音乐这里我们找了一个很经典的,是我们小时候百听不厌的背景音乐。当然,大家也可以根据自己的喜好来调整。在 html 中增加一个在线视频,然后需要我们隐藏画面,只保留音乐,核心代码如下:

<!-- 视频标签,设置为循环播放,但初始时不自动播放 -->
<video loop muted>
  <source src="./weather/music.mp4" type="video/mp4">
  您的浏览器不支持 HTML5 视频。
</video>

为了隐藏画面,这里我们使用 CSS 样式的方式进行控制,代码如下:

/* 隐藏视频画面 */
video { display: none; }

为了演示的效果,我们将设置网页进行延迟播放,设置方法如下:

// 获取视频元素和按钮
var video = document.getElementById('backgroundVideo');
// 设置音量为 20%
video.volume = 0.2;
var button = document.getElementById('playButton');
// 页面加载后延迟 2 秒自动播放
window.onload = function() {
    initWeather();
    setTimeout(function() {
        video.play(); // 开始播放
        video.muted = false; // 取消静音
        preview(); // 城市天气进行轮播
    }, 5000); // 2000 毫秒(2 秒)后执行
};

2、城市标记及天气展示

城市标记及天气展示比较简单,使用 Leaflet 来进行位置的标注即可,这里给出示例代码:

function initWeather(){
    var collisionLayer = L.LayerGroup.collision({margin:3});
    for(var i=0;i<dataJson.length;i++){
        var marker = L.marker([dataJson[i].lat, dataJson[i].lon], {
            icon: L.divIcon({
                iconSize: null,
                className: '',
                popupAnchor:[5,5],
                shadowAnchor:[5,5],
                html: buildHtml(dataJson[i],i)
            })
        }).addTo(collisionLayer);
    }
    collisionLayer.addTo(map);
}

天气的信息标注代码如下,通过以上代码就可以实现今日天气和明日天气的网页展示:

function buildHtml(dataJson,index){
    var html = '';
    html += '<div class="animation-spaceInDown" style="color:' + getRandomColor() + '"><div><b>' + dataJson.city + '&nbsp;' + dataJson.w_name + '&nbsp;' + dataJson.temp + '℃</b><span></span></div></div>';
    html += '<div>' + dataJson.two + ' ℃</div>';
    return html;
}

最后还有一个随机颜色的生成,使用随机颜色是为了保证生成的页面的颜色能够更加区别明显。

function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

3、城市轮播

为了实现每个省会城市都可以进行轮播,这里我们根据位置将地图的视图中心点进行重绘。最终的效果看起来就是一个会跳动的地图。这里我们使用定时器的方式来进行切换不同城市。核心代码如下:

function preview(){
    // 设置定时器,每隔 2 秒执行一次
    const intervalId = setInterval(() => {
        // 如果索引超出了数组范围,清除定时器并停止执行
        if (currentIndex >= dataJson.length) {
            currentIndex = 0;
        }
        // 获取当前索引对应的元素
        const currentElement = dataJson[currentIndex];
        //如果不为空,先移除 marker
        if(dymicMarker != null){
            map.removeLayer(dymicMarker);
        }
        dymicMarker = L.marker([currentElement.lat, currentElement.lon]).addTo(map);
        setTargetSelect(dymicMarker);
        console.log(`当前元素:${currentElement}`);
        map.setView([currentElement.lat, currentElement.lon],8);
        // 索引加 1,准备获取下一个元素
        currentIndex++;
    }, 3000);
}

function setTargetSelect(e){
    var i = 1
    var int = setInterval(() => {
        if(!e._map) clearInterval(int)
        if (i < -1) { i = 1 }
        i = i - 0.08
        if (i < 0) e.setOpacity(i * -1)
        else e.setOpacity(i)
    },60)
}

4、成果展示

经过以上的步骤,基本就可以实现带音乐播放的天气小应用。页面效果如下:

文章配图

四、总结

以上就是本文的主要内容,本文构建了一个能够唤醒 80 年代记忆的老式天气预报系统。这不仅仅是一个技术项目,更是一次情感的探索和文化的传承。通过构建这样一个 80 年代风格的天气预报系统,我们希望能够唤起更多人对那个时代的美好回忆,同时也展示现代技术在文化传承方面的巨大潜力。在未来的工作中,我们还将继续优化系统功能,增加更多互动元素,如用户自定义播报内容、分享功能等,让这个系统不仅仅是一个展示平台,更是一个能够与用户产生情感共鸣的互动空间。这是一次穿越时空的构建之旅,也是一次对过去的致敬和对未来的探索。让我们一起踏上这段旅程,用现代的技术手段,唤醒那些沉睡在记忆深处的 80 年代天气预报,让旧时光在新技术的助力下重新焕发生机。

目录

  1. 一、省会城市信息构建
  2. 1、省会城市空间查询
  3. 2、Java 后台查询
  4. 二、Java 省会城市天气查询
  5. 1、与百度开放平台集成天气
  6. 2、响应对象属性介绍
  7. 3、省会天气实况展示
  8. 三、WebGIS 应用构建
  9. 1、背景音乐集成
  10. 2、城市标记及天气展示
  11. 3、城市轮播
  12. 4、成果展示
  13. 四、总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • C++ 模板初阶:泛型编程基础与实战
  • iOS 26 系统兼容适配:UITabBar 液态玻璃效果与 WiFi 获取方案
  • iOS 26 系统兼容适配:UITabBar 液态玻璃效果与 WiFi SSID 获取
  • Python 简单小游戏与实用脚本代码示例:石头剪刀布、邮件发送等
  • FPGA 实现 CAN 总线接口与数据帧解析
  • 2026主流AI大模型横评与选型指南
  • ZeroClaw:零开销全 Rust 自主 AI 助手基础设施,与 OpenClaw 对比
  • iOS 开发针对新系统 iOS26 的 UITabBar 液态玻璃及 WiFi SSID 获取兼容适配
  • Playwright 基础教程:元素拖拽、坐标获取与文本提取实战
  • 从一句话到一张图:看懂 Stable Diffusion 的“潜空间扩散”生成流程(配图详解)
  • AI 编程工具深度对比:Cursor、Copilot、Trae 与 Claude Code
  • Web APIs:元素滚动 scroll 系列属性详解(位置与尺寸)
  • 滑动窗口算法结合例题详解
  • Python 批量给图片添加文字或图片水印实战
  • 基于 DDPG 算法的电力市场博弈策略建模与仿真(Python 复现)
  • 腾讯位置服务 AI+地图征文:选题方向与高分攻略
  • 国产点焊与弧焊机器人主流品牌推荐
  • 人工智能与机器学习在软件工程中的应用
  • Whisper 语音识别本地化部署实战指南
  • 设计支持万人并发抢购的秒杀系统架构方案

相关免费在线工具

  • 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