唤醒80年代记忆:基于百度地图的一次老式天气预报的WebGIS构建之旅

唤醒80年代记忆:基于百度地图的一次老式天气预报的WebGIS构建之旅

目录

一、省会城市信息构建

1、省会城市空间查询

2、Java后台查询

二、Java省会城市天气查询

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

2、响应对象属性介绍

3、省会天气实况展示

三、WebGIS应用构建

1、背景音乐集成

2、城市标记及天气展示

3、城市轮播

4、成果展示

四、总结


前言

        在数字技术飞速发展的今天,我们常常沉浸于各种高科技带来的便捷与震撼之中,却容易忽视那些曾经陪伴我们成长、承载着时代记忆的旧事物。80年代的天气预报,便是这样一份珍贵的文化遗产。它以简洁而质朴的方式,传递着天气信息,也传递着那个时代的气息。那种对自然的敬畏、对信息的渴望,以及一家人共同分享的温馨氛围,都深深烙印在我们的记忆中。然而,随着时间的推移,天气预报的形式已经发生了翻天覆地的变化。高清的画面、精准的数据、个性化的推送……这些现代技术带来的便利固然令人欣喜,但也在一定程度上让我们失去了那份对天气预报本身的纯粹情感。于是,一个想法在心中萌生:能不能用现代的技术手段,重现80年代的天气预报,让那些旧时光的记忆重新回到我们的生活中?WebGIS技术的出现,为我们提供了这样一个绝佳的机会。它能够将地理信息与网络技术相结合,实现地图的可视化展示和数据的动态交互。而百度天气作为国内领先的天气数据服务平台,提供了丰富而准确的天气信息。将两者相结合,我们或许能够构建出一个既具有80年代风格,又融合了现代技术优势的天气预报系统。

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

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

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

一、省会城市信息构建

        在进行省会城市天气预报的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.150302306","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.853297824","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.064316153","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 html; 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 += "<div+getRandomColor()+";' animation-spaceInDown><div ><b>"+dataJson.city + "&nbsp;" + dataJson.w_name + "&nbsp;"+ dataJson.temp +"℃</b><span></span></div>"; html += "<div>" + ""+ dataJson.two+ " ℃</div>"; html += "</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、成果展示

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

        如果您也感兴趣,跟随博文一起来动手实践吧。这里录了一个最终的视频效果,如果感兴趣可以看看:https://live.ZEEKLOG.net/v/504506

四、总结

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

Read more

零基础搭建FPGA下载环境:USB-Blaster驱动安装篇

零基础搭建FPGA下载环境:从“找不到电缆”到一键烧录 你有没有过这样的经历? 花了一整天装好 Quartus,写完第一个 Hello, FPGA 的流水灯代码,满心期待点击“Programmer”——结果弹出一句冰冷提示: “Can’t initialize hardware – no JTAG cable found.” 设备管理器里一片空白,或者一个带着黄色感叹号的“未知设备”孤零零挂着。 别慌,这几乎是每个 FPGA 新手必踩的坑。而罪魁祸首,往往就是那个小小的黑色 USB 接口模块—— USB-Blaster 。 今天我们就来彻底解决这个问题。不讲虚的,不堆术语,手把手带你把驱动装上、让 Quartus 认出来、把程序烧进去。哪怕你是第一次接触硬件开发,也能照着做成功。 为什么 USB-Blaster 总是“插了没反应”? 先搞清楚一件事:

Pi0机器人VLA大模型在昇腾A2平台上的测评

Pi0机器人VLA大模型在昇腾A2平台上的测评

Pi0机器人VLA大模型在昇腾A2平台上的测评文档 * 写在最前面 🌈你好呀!我是 是Yu欸🚀 感谢你的陪伴与支持~ 欢迎添加文末好友🌌 在所有感兴趣的领域扩展知识,不定期掉落福利资讯(*^▽^*) 写在最前面 版权声明:本文为原创,遵循 CC 4.0 BY-SA 协议。转载请注明出处。 随着人工智能技术的持续神户以及人形机器人产业的快速发展,算力在提升机器人运动控制精度、实时响应能力与智能化水平方面的作用日益凸显。为实现降本增效,国产化算力代替需求不断攀升,本文基于国产化适配的 Pi0机器 VLA大模型,在昇腾 Atlas 800I A2服务器上完成部署与测试,结果表明:该模型在推理性能、推理精度及功能完整性等方面,不仅实现了与英伟达同级别硬件相当的算力表现,更在部分场景下表现出更优的运行效率。 这一成果充分表明:经过深度适配的国产大模型与国产算力平台,已具备支撑高端人形机器人智能化发展的核心技术能力。国产算力在人形机器人领域的应用场景广阔,正加速迈向自主可控、高效可靠的全新阶段。 一、测评概述 1.1 测试目的 本测评旨在验证Pi0机器人视觉

春晚机器人营销破局:从168亿曝光到转化闭环,数智联AI团队解码2026增长新范式

当除夕夜的钟声敲响,全球超过168亿人次的目光聚焦于同一个舞台,这不仅是一场文化盛宴,更成为了顶尖科技企业争夺品牌心智、验证技术实力的终极考场。从宇树科技“机器牛”的灵动起舞,到智元机器人的“自办春晚”与999元体验计划引爆社交网络,2025-2026年的春晚,已然演变为一场现象级的“机器人营销大战”。 这场战役背后,远非简单的品牌曝光。它是一场集国家级技术信用背书、高密度内容共创、全域即时转化于一体的综合实力较量。成功者,如参与官方节目的四家企业,在开播2小时内实现了电商搜索量暴增300%,订单增长150%,并一举包揽了相关品类68%的搜索流量。而另辟蹊径者,如智元,则以零赞助成本,通过差异化策略同样实现了声量与转化的双丰收。 这不禁让众多企业主深思:春晚机器人营销的底层逻辑究竟是什么?巨额投入背后,如何衡量真实ROI?对于大多数无法豪掷数千万上亿预算的企业,其中的方法论能否被借鉴、迁移,用于自身的AI转型与营销增长? 今天,就让我们深入拆解这场顶级营销范式的核心,并探寻如何将其精髓应用于更广泛的商业场景,实现可持续的智能增长。 [外链图片转存中…(img-K2FjEqKS-

【机器人】复现 StreamVLN 具身导航 | 流式VLN | 连续导航

【机器人】复现 StreamVLN 具身导航 | 流式VLN | 连续导航

StreamVLN 通过在线、多轮对话的方式,输入连续视频,输出动作序列。 通过结合语言指令、视觉观测和空间位姿信息,驱动模型生成导航动作(前进、左转、右转、停止)。 论文地址:StreamVLN: Streaming Vision-and-Language Navigation via SlowFast Context Modeling 代码地址:https://github.com/OpenRobotLab/StreamVLN 本文分享StreamVLN 复现和模型推理的过程~ 下面是示例效果: 1、创建Conda环境 首先创建一个Conda环境,名字为streamvln,python版本为3.9; 然后进入streamvln环境,执行下面命令: conda create -n streamvln python=3.9 conda activate streamvln 2、 安装habitat仿真环境