使用mapbox 绘制台风风圈、台风路径
目录
1、台风路径信息准备与添加
1.1 数据准备,这里可以从中央气象台台风网抓取数据http://typhoon.nmc.cn/web.html
1.2 添加地图信息
2、添加台风风圈
1、使用坐标转换计算
2、使用turf.js计算台风风圈范围
3、台风路径的播放效果
1、台风路径信息准备与添加
1.1 数据准备,这里可以从中央气象台台风网抓取数据http://typhoon.nmc.cn/web.html
1.2 添加地图信息
添加台风预报路径
function addTyLine(map, typData) {// 最后的点位添加编号名称typData.points[typData.points.length - 1].forecast.forEach((element, index) => {let coordList = [];element.forecastpoints.map(item => {coordList.push([Number(item.lng), Number(item.lat)]);});if (!map.getSource(`${typData.tfid}_typhon_route_line_${element.tm}`)) {map.addSource(`${typData.tfid}_typhon_route_line_${element.tm}`, {type: 'geojson',data: {type: 'Feature',properties: {},geometry: {type: 'LineString',coordinates: coordList,},},});}if (!map.getLayer(`typhon_route_${typData.tfid}_${index}`)) {map.addLayer({id: `typhon_route_${typData.tfid}_${index}`,type: 'line',source: `${typData.tfid}_typhon_route_line_${element.tm}`,layout: {'line-join': 'round','line-cap': 'round',},paint: {'line-color': '设定颜色','line-width': 2,'line-dasharray': [0.005, 3],},});}});
}
根据数据的格式来整理成geojson添加
预报站点信息、已测路径信息、已测站点信息同理添加
2、添加台风风圈
关于台风风圈,已知的数据有台风中心点以及台风半径,而台风半径又分为西北、西南、东南、东北四个方位角,这里在网上搜集了两种方法:
1、使用坐标转换计算
已知的中心点坐标为wgs84投影类型,也就是经纬度,需将其转换为投影坐标系来计算距离,再根据距离将其转换为经纬度来添加
let coords_7 = getCircleCoords(coordList[time], radiusData);map.addSource(`currentFill_${typData.tfid}`, {type: 'geojson',data: {type: 'Feature',properties: {name: typData.name,radius: '7',},geometry: {type: 'Polygon',coordinates: coords_7,},},});map.addLayer({id: `currentFill_${typData.tfid}`,source: `currentFill_${typData.tfid}`,type: 'fill',paint: {'fill-color': ['match', ['get', 'radius'], '7', '#ffff00', '10', '#ffa911', '#ff5341'],'fill-opacity': 0.2,'fill-outline-color': ['match', ['get', 'radius'], '7', '#ffff00', '10', '#ffa911', '#ff5341'],
},});getCircleCoords(center, radiusData) {//radiusData = {// ne: 100,//nw: 120,//sw: 120,//se: 10,//};center = proj4(proj4('EPSG:4326'), proj4('EPSG:3857'), center);let _coords = [];let _angInterval = 6;let _pointNums = 360 / (_angInterval * 4);let quadrant = {// 逆时针算角度'0': 'ne','1': 'nw','2': 'sw','3': 'se'};for (let i = 0; i < 4; i++) {let _r = parseFloat(radiusData[quadrant[i]]) * 1000; // 单位是kmif (!_r) _r = 0;for (let j = i * _pointNums; j <= (i + 1) * _pointNums; j++) {let _ang = _angInterval * j;let x = center[0] + _r * Math.cos((_ang * Math.PI) / 180);let y = center[1] + _r * Math.sin((_ang * Math.PI) / 180);var coord = proj4(proj4('EPSG:3857'), proj4('EPSG:4326'), [x, y]);_coords.push(coord);}}return [_coords];
}
传入的radiusData 需包含四个半径,格式如上;
proj4.js是坐标系转换通用的库,需单独引入;
以上方法可行,但是算出来的台风风圈经过验证存在一点误差,所以这里介绍另外一种使用turf.js计算的方法,算出来的风圈范围跟官网一致;
2、使用turf.js计算台风风圈范围
drawTyphoonCircle(p, radiusData) {var center = turf.point(p);let quadrant = {// 逆时针算角度0: 'ne',1: 'sw',2: 'se',3: 'nw',};if (radiusData[quadrant[0]]) {var options = { number: 2048 };var arc_ne = turf.lineArc(center, radiusData[quadrant[0]], 0, 89.9, options);var arc_se = turf.lineArc(center, radiusData[quadrant[3]], 90, 179.9, options);var arc_sw = turf.lineArc(center, radiusData[quadrant[2]], 180, 269.9, options);var arc_nw = turf.lineArc(center, radiusData[quadrant[1]], 270, 360.1, options);var arcs = [];arcs.push(arc_ne, arc_se, arc_sw, arc_nw);var typhoonCircleCoords = [];for (var i = 0; i < arcs.length; i++) {var rawCoords1 = arcs[i].geometry.coordinates;for (var j = 0; j < rawCoords1.length; j++) {typhoonCircleCoords.push(rawCoords1[j]);}}var lineAll = turf.lineString(typhoonCircleCoords);var typhoonCirclePolygon = turf.lineToPolygon(lineAll);console.log('typhoonCirclePolygon', typhoonCirclePolygon);return typhoonCirclePolygon;} else {return;}}
这里返回直接是geojson,
3、台风路径的播放效果
设置定时器,对geojson数据源定时修改,用到的核心方法是 map.getSource(`currentPoint`).setData(geojson);记得动画播放结束后要clearInterval()哦
let time = 0
updateSource[typData.tfid] = setInterval(async () => {time++;if (!typData.points[time]) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;return;}radiusSeven = typData.points[time]?.radius7.split('|');radiusData = {ne: radiusSeven[0],nw: radiusSeven[1],sw: radiusSeven[2],se: radiusSeven[3],};// let coords_7 = getCircleCoords(coordList[time], radiusData);let coords_7 = drawTyphoonCircle(coordList[time], radiusData);const geojson_7 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_7?.geometry?.coordinates,},properties: {tfid: typData.tfid,radius: '7',},},],};radiusTen = typData.points[time].radius10.split('|');radiusTenData = {ne: radiusTen[0],nw: radiusTen[1],sw: radiusTen[2],se: radiusTen[3],};let coords_10 = drawTyphoonCircle(coordList[time], radiusTenData);const geojson_10 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_10?.geometry?.coordinates,},properties: {name: typData.name,radius: '10',},},],};let radiusTwelve = typData.points[time].radius12.split('|');let radiusTwelveData = {ne: radiusTwelve[0],nw: radiusTwelve[1],sw: radiusTwelve[2],se: radiusTwelve[3],};let coords_12 = drawTyphoonCircle(coordList[time], radiusTwelveData);const geojson_12 = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Polygon',coordinates: coords_12?.geometry?.coordinates,},properties: {name: typData.name,radius: '12',},},],};const geojson = await {type: 'FeatureCollection',features: [{type: 'Feature',geometry: {type: 'Point',coordinates: coordList[time],},},],};try {if (!coordList[time] || !typData.points[time]) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;return;}map.getSource(`currentPoint_${typData.tfid}`).setData(geojson);map.getSource(`currentFill_${typData.tfid}`).setData(geojson_7);map.getSource(`currentFill_10_${typData.tfid}`).setData(geojson_10);map.getSource(`currentFill_12_${typData.tfid}`).setData(geojson_12);} catch (err) {// If the updateSource interval is defined, clear the interval to stop updating the source.if (updateSource) {clearInterval(updateSource[typData.tfid]);updateSource[typData.tfid] = null;}throw new Error(err);}}, 100);
类似台风路径的播放效果官网上也有所介绍,https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-route/其里面的核心内容就是设置定时器更新数据源 ,当然数据源的要求是geojson, map.getSource('pointSourceName').setData(pointGeojson);
使用mapbox 绘制台风风圈、台风路径相关推荐
- 中国台风计算机,台风丹娜丝或是今年以来最怪的台风了,超级计算机:不知道登中国哪里...
原标题:台风丹娜丝或是今年以来最怪的台风了,超级计算机:不知道登中国哪里 7月17日上午,今年第5号台风丹娜丝继续在西太平洋上活动,从高清可见光卫星云图上看,它的个头仍然相当广阔,从南海到菲律宾以东都 ...
- html path 图标,Clippy – 轻松绘制 CSS clip-path 裁剪路径工具
Clippy – 轻松绘制 CSS clip-path 裁剪路径工具 4月 13, 2016 评论 Sponsor Clippy 是一个 CSS clip-atch 属性绘制工具,使用它可以轻松绘制不 ...
- SwiftUI之深入解析如何绘制徽章视图的路径和形状
一.创建徽章视图 创建徽章前需要使用 SwiftUI 的矢量绘画 API 创建一个徽章视图: 选择文件 -> 新建 -> 文件,然后从 iOS 文件模板列表中选择 SwiftUI View ...
- OL4两种绘制台风圈方式的比较
前言:今天在一个群里面看到台风圈的,感觉很好奇,就想着能否用canvas结合OL4实现下,何为台风圈先来张图: 一.实现原理 1.先画上半圆 2.在下半圆 3.最后画半圆相接线 关于canvas画圆弧 ...
- Android中绘制简单几何图形和路径Path
背景 我的博客:http://zhangsunyucong.top 马上就到2018年过年了,然后我又刚好有兴致,就来玩玩Android中的简单几何图形的绘制和使用Path类来绘制路径. Path和C ...
- 【MAPBOX基础功能】21、mapbox绘制自动旋转的图标
前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...
- 【MAPBOX基础功能】09、mapbox绘制线图层并进行添加、删除、更新、显隐等操作
前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...
- 【MAPBOX基础功能】11、mapbox绘制symbol icon图层并进行添加、删除、更新、显隐等操作
前言 官网指引,生成accesstoken,下载相关依赖请翻阅[https://blog.csdn.net/weixin_44402694/article/details/125414381?spm= ...
- 绘制西北太平洋台风频数分布填色图
研究台风路径和影响,除了直接绘制台风路径,我们还往往想知道研究的台风在海上各个经纬度的频数分布,并直观展示在地图上. 之前和大家交流过如何从台风路径数据集里提取指定条件的台风(用pandas库提取IB ...
最新文章
- JDBC 实例--JDBC通过工具类DBUtil连接到数据库,让我们不再恐惧操作数据库
- 最初学习ASP.net的时候常会遇到的问题
- Android WebView 和 javaScript的互相调用(二)
- CososJS学习笔记(1) 环境配置(填坑版,让你少走弯路!)
- 【STL源码剖析读书笔记】【第5章】关联式容器之set、map、multiset和multimap
- 带你学python基础:字符串
- 【Kafka】Kafka如何开启SSL 控制台消费与生产 代码消费与生产
- 【Dubbo源码阅读系列】服务暴露之本地暴露
- 练习4.1 根据后序和中序遍历输出先序遍历 (25 分)
- 小米手机线刷教程详解
- Google Earth Engine(GEE)——图表概述(记载图表库)
- MacOS Big Sur 11.2.3 (20D91) with Clover 5131 and OC 0.6.7 and PE 三EFI分区原版DMG黑苹果镜像
- 机器学习——马氏距离
- 统信UOS_arm64开发环境配置
- mysql查询每个部门的最高和最低工资_SQL数据库 计算出每个部门的平均工资 最高工资和最低工资 语法怎么写?...
- Pytorch、TorchVision、Python、Jetpack版本匹配问题
- 东辉职校计算机专业录取分数线,2016年上海东辉职校录取分数
- Java小游戏之掷骰子
- 《渡月桥 ~君想ふ~》
- LPDDR4x 的 学习总结(2) - SDRAM array结构浅识
热门文章
- Development Tools 错误解决
- Centos 7安装、配置SVN
- 微电网数字孪生 | 智能时代,部署源网荷储一体化管控平台
- python抓取经典评论_通过Python抓取天猫评论数据
- 免费个人网页制作指南Dreamweaver教程
- 任天堂媒体峰会召开,众多新作现场试玩
- LabVIEW与MATLAB混合编程——调用Matlab中.m的函数
- 听“元戎”首席架构师讲述华为云Serverless进化的故事
- Python爬虫实战(一) — Pixabay图片下载器
- VAPS XT航空仪表开发第一节