全国疫情精准定点动态更新(.net core)
前言
疫情远比我们在年初想的发展迅速,在过年前还计划着可以亲戚聚聚,结果都泡汤了,开始了自家游。
在初三的时候,看到那个丁香医生,觉得不够详细,比如说我想看下周边城市的疫情情况,但是我地理不好,根本不清楚其他城市的位置。
当时我想的是做一张地图标注各个城市的数量,及严重程度。然后我用python去爬虫,晚上成功了,第二点防爬了。当然拦不住我的,我使用元素爬取的方式也行。
但是这种方式需要运行crome内核渲染,然后要隔一段时间更新,我已经放弃了我买的windows,原因是贵,且自己贫苦。
当时我认为疫情很快会得到控制,所以我就放弃了。
前几天在博客园看到有人写了一个爬取的demo,那个api返回的数据相当标准,所以我有产生了想法。
看下我做的效果吧:
密密麻麻的,这是啥呢?完全没有可视度。
放大分析下。
1.我根据中国不同的省份,根据不同人数显示不同的颜色,且放上去会显示当前疫情。
颜色可以通过左侧控制,上下有两个箭头可以上拉下拉,选取区域,如下图:
2.当地图放大后,可以看到更多的细节,比如说如果数量达到100后我就会让当前位置,加入警报,当然随着数量越多该位置的点更大,且冒泡提升更大。
放大后效果如下图:
好了看下大概思路吧,本博客只介绍思路,项目开源,写的随意,不要介意,地址在末尾贴出。
正文
第一步
我想的肯定是获取数据,在前几天看到一篇博客,上面介绍一个非常标准的api,我没有去找那篇博客了,在此感谢,如果该博主觉得需要贴出地址,请联系我,毕竟博文给与了我help。
HttpClient httpClient = new HttpClient { BaseAddress = new Uri("https://view.inews.qq.com/") };
HttpResponseMessage httpResponseMessage = httpClient.GetAsync("g2/getOnsInfo?name=disease_h5").GetAwaiter().GetResult();
var result = httpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
nCoVData data = JsonConvert.DeserializeObject<nCoVData>(result);
nCoVDataDetail nCoVDataDetail = JsonConvert.DeserializeObject<nCoVDataDetail>(data.Data);
通过格式化将json成c# 对象。
nCoVDataDetail.AreaTree 就是各个省的信息。
因为数量较多,我无法去截图数据在此介绍格式。
public class AreaTree
{
public AreaTree()
{
this.Today = new Today();
this.Total = new Overview();
this.Children = new List<Children>();
}
//国家名字
public string Name { get; set; }
//今天的变化情况
public Today Today { get; set; }
//总数量
public Overview Total { get; set; }
//省或者直辖市
public List<Children> Children { get; set; }
}
public class Children
{
//省名或者直辖市名
public string Name { get; set; }
// 今日变化
public Today Today { get; set; }
// 统计
public Overview Total { get; set; }
//省下面的区,直辖市下面的区
public List<Children> children { get; set; }
}
模型就是这样的。
第二步
我需要确定每个地方的经纬度,这样我才能在地图上定位.
这时候我想到了百度地图。
private static mapv3 GetHttpRequest(string areaAddress)
{
HttpClient httpClient = new HttpClient { BaseAddress = new Uri("http://api.map.baidu.com/") };
HttpResponseMessage httpResponseMessage = httpClient.GetAsync("geocoding/v3/?address=" + areaAddress + "&output=json&ak=你的key").GetAwaiter().GetResult();
var result = httpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
mapv3 data = JsonConvert.DeserializeObject<mapv3>(result);
return data;
}
这个时候需要你去百度地图注册你的key了,免费哈。
看下mapv3模型,在这里我只介绍用到的经纬度,其他的自己看官网。吐槽一下,官网的文档绝对是程序员写的。
public class mapv3
{
public int status { get; set; }
public result result { get; set; }
}
status 为状态0就ok,其他不ok。
看下result:
public class result
{
public location location { get; set; }
public int precise { get; set; }
public int confidence { get; set; }
public int comprehension { get; set; }
public string level { get; set; }
}
其他不介绍了,用不上,详细看官网,在这里只介绍location。
public class location
{
public double lng { get; set; }
public double lat { get; set; }
}
这两个就是经纬度。
第三步
整理数据与echarts数据格式相对应,echarts是可视化的插件。
echarts经纬度是这样的格式:
{
"位置":[经,纬]
}
经纬度地址需要存取。
private static Dictionary<string, double[]> dic = new Dictionary<string, double[]>();
我使用dictionary,因为我需要鉴别是否已经存在了,方便查询。
下面是整体格式化:
private static void GetPositionOfJson(IList<AreaTree> areaTrees)
{
// 考虑到查询成本
echartsModels = new List<EchartsModel>();
echartsMapModels = new List<EchartsMapModel>();
pronvincedic =new List<EchartsModel>();
EchartsModel echartsModel = new EchartsModel();
EchartsMapModel echartsMapModel = new EchartsMapModel();
foreach (var country in areaTrees)
{
var CountryName = country.Name;
if (CountryName != "中国")
{
//only china 其他国家不管
continue;
}
var provinceRank = "省";
foreach (var province in country.Children)
{
if (province.Name == "北京" || province.Name == "天津" || province.Name == "上海" || province.Name == "重庆")
{
provinceRank = "市";
}
var provinceName = province.Name + provinceRank;
//加入统计 因为西藏省区
if (!dic.Keys.Contains(province.Name))
{
var fullName = provinceName + province.Name;
mapv3 mapv3 = GetHttpRequest(fullName);
if (mapv3.status == 0)
{
var location = mapv3.result.location;
double[] d = new double[] { location.lng, location.lat };
dic.Add(province.Name, d);
}
}
EchartsModel echartsModelPClone = (EchartsModel)echartsModel.clone();
echartsModelPClone.name = province.Name;
echartsModelPClone.value = province.Total.Confirm;
pronvincedic.Add(echartsModelPClone);
//颜色
EchartsMapModel echartsMapModelClone = (EchartsMapModel)echartsMapModel.clone();
echartsMapModelClone.name = province.Name;
//总感染人数
EchartsModel InfectSum = (EchartsModel)echartsModel.clone();
InfectSum.name = "感染人数";
InfectSum.value = province.Total.Confirm;
//治愈人数
EchartsModel CureSum = (EchartsModel)echartsModel.clone();
CureSum.name = "治愈人数";
CureSum.value = province.Total.Heal;
//沉重的死亡人数
EchartsModel HeadSum = (EchartsModel)echartsModel.clone();
HeadSum.name = "死亡人数";
HeadSum.value = province.Total.Dead;
List<EchartsModel> echartsModelMapList = new List<EchartsModel>();
echartsModelMapList.Add(InfectSum);
echartsModelMapList.Add(CureSum);
echartsModelMapList.Add(HeadSum);
echartsMapModelClone.value = echartsModelMapList;
echartsMapModels.Add(echartsMapModelClone);
foreach (var city in province.children)
{
if (!dic.Keys.Contains(city.Name))
{
var fullName = provinceName + city.Name;
mapv3 mapv3 = GetHttpRequest(fullName);
if (mapv3.status == 0)
{
var location = mapv3.result.location;
double[] d = new double[] { location.lng, location.lat };
dic.Add(city.Name, d);
}
}
//后续需要优化部分
EchartsModel echartsModelClone= (EchartsModel)echartsModel.clone();
echartsModelClone.name = city.Name;
echartsModelClone.value = city.Total.Confirm;
echartsModels.Add(echartsModelClone);
}
}
}
}
分析下:
下面是装载经纬度的:
foreach (var city in province.children)
{
if (!dic.Keys.Contains(city.Name))
{
var fullName = provinceName + city.Name;
mapv3 mapv3 = GetHttpRequest(fullName);
if (mapv3.status == 0)
{
var location = mapv3.result.location;
double[] d = new double[] { location.lng, location.lat };
dic.Add(city.Name, d);
}
}
//后续需要优化部分
EchartsModel echartsModelClone= (EchartsModel)echartsModel.clone();
echartsModelClone.name = city.Name;
echartsModelClone.value = city.Total.Confirm;
echartsModels.Add(echartsModelClone);
}
判断不包含,然后去通过百度查询。
EchartsModel 是传递echarts模型中的散点格式。
echarts格式是{name:"",value:""},这时候散点就会显示数字和名字了。
因为每个城市创建数量过多,所以我采用克隆的方式进行处理。
其他我就不介绍了,源码公开逻辑也不复杂。
有一个地方需要介绍下:
if (province.Name == "北京" || province.Name == "天津" || province.Name == "上海" || province.Name == "重庆")
{
provinceRank = "市";
}
为什么我这么做,因为这几个是直辖市。
比如我要查询武汉经纬度,肯定湖北省武汉。
查询北京的朝阳区,肯定是北京市朝阳区。如果是输入北京朝阳区是不准的。
第四步
当我把经纬度,保存在字典中,我每次我重启的时候需要查询一次,这非常耗时,我将会保存为json格式,然后存在本地,重启的时候,我将会读取,这里我贴代码。
当然我启动的时候我要初始化,且数据必须动态更新哈,所以我每隔一个小时去更新数据。
timer.LoadMap();
//初始化
timer.getData(null,null);
//每隔一小时执行一次
System.Timers.Timer timerOneHour= new System.Timers.Timer(60 * 60 * 1000);
timerOneHour.Elapsed += new System.Timers.ElapsedEventHandler(timer.getData);
timerOneHour.AutoReset = true;
第五步
前端根据数据渲染。
我个人觉得能够介绍的只有颜色和大小。
visualMap: {
show: true,
min: 0,
max: 2000,
left: 'left',
top: 'bottom',
text: ['高', '低'], // 文本,默认为数值文本
calculable: true,
seriesIndex: [1],
pieces: [{
}],
inRange: {
color: ["#F2FE96",'#FFFF00', '#A5CC82',"#BF444C"], // 绿到黄到红
}
},
设定省份的数量区间是0-2000,颜色在这区间变动:
color: ["#F2FE96",'#FFFF00', '#A5CC82',"#BF444C"]
散点和气泡大小如下:
symbolSize: function (val) {
num = val[2] / 5;
num = num > 50 ? 50 : num;
num = num < 10 ? 10 : num;
return num;
}
最大为50,最小为10。
下面是如果value>100,那么让它显示危险标志。
{
name: 'item>100',
type: 'effectScatter',
coordinateSystem: 'geo',
data: convertData(data.sort(function (a, b) {
return b.value - a.value;
}).filter(function (item) {
return item.value >= 100
})
)
,
symbolSize: function (val) {
num = (val[2] / 10);
num = num > 50 ? 50 : num
if (val[2] == 0) {
num = 0;
}
return num;
},
showEffectOn: 'render',
rippleEffect: {
brushType: 'stroke'
},
hoverAnimation: true,
label: {
normal: {
formatter: '{b}',
position: 'right',
show: false
}
},
itemStyle: {
normal: {
color: 'red',
shadowBlur: 10,
shadowColor: 'red'
}
},
zlevel: 1
},
总结
愿疫情快速结束,带好口罩,保护自己,保护他人。人人为我,我为人人。
本来,我想在我的服务器上部署的,但是黑客太多,本人安全防护水平太低了。
所以上传到github,没有数据库,直接可运行。.net core 库,2.2,可自行更换,写的随意,见谅。
需要替换百度的key,因为我已经去掉了。如果实在不想去注册,可评论发到你的邮箱。
github地址:
https://github.com/aoximin/ViralCollapse
全国疫情精准定点动态更新(.net core)的更多相关文章
- 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)
原文:如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀) 我们都知道可以通过在 Visual Studio 中设置输出路径(OutputPath)来更改项目输 ...
- .NET6运行时动态更新限流阈值
昨天博客园撑不住流量又崩溃了,很巧正在编写这篇文章,于是产生一个假想:如果博客园用上我这个限流组件会怎么样呢? 用户会收到几个429错误,并且多刷新几次就看到了内容,不会出现完全不可用. 还可以降低查 ...
- 微软Azure配置中心 App Configuration (三):配置的动态更新
写在前面 我在前文: <微软Azure配置中心 App Configuration (一):轻松集成到Asp.Net Core>已经介绍了Asp.net Core怎么轻易的接入azure ...
- JSPatch – 动态更新iOS APP
原文:http://blog.cnbang.net/works/2767/ JSPatch是最近业余做的项目,只需在项目中引入极小的引擎,就可以使用JavaScript调用任何Objective-C的 ...
- JAVA代码热部署,在线不停服动态更新
本地debug的时候,可以实时编译并更新代码,线上也可以不停服来动态更新类,即所说的java热部署. JDK代理的两种方式: 1.premain方式是Java SE5开始就提供的代理方式,但其必须 ...
- elasticsearch同义词及动态更新
第一种:参考地址:http://dev.paperlesspost.com/setting-up-elasticsearch-synonyms/271.Add a synonyms file.2.Cr ...
- 在Android中实现service动态更新UI界面
之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...
- Android中动态更新ListView(转)
在使用ListView时,会遇到当ListView列表滑动到最底端时,添加新的列表项的问题,本文通过代码演示如何动态的添加新的列表项到ListView中.实现步骤:调用ListView的setOnSc ...
- Js多国时间动态更新
Js多国时间动态更新 点击下载
随机推荐
- wpf 画五角星函数
public void ABC() { var canvas = new Canvas(); Content = canvas; var points = new List<Point>( ...
- Linux Cgroup浅析
cgroup从2.6.4引入linux内核主线,目前默认已启用该特性.在cgroup出现之前,只能对一个进程做资源限制,比如通过sched_setaffinity设置进程cpu亲和性,使用ulimit ...
- Spring Cloud(二):Web服务客户端之Ribbon
上文介绍了服务如何通过Eureka实现注册,以及如何从Eureka获取已经注册的服务列表.那么拿到注册服务列表后, 如何进行服务调用?一个简单的实现是可以从被调用服务的实例列表中选择一个服务实例,通过 ...
- 一文读懂MapReduce 附流量解析实例
1.MapReduce是什么 Hadoop MapReduce是一个软件框架,基于该框架能够容易地编写应用程序,这些应用程序能够运行在由上千个商用机器组成的大集群上,并以一种可靠的,具有容错能力的方式 ...
- linux入门系列7--管道符、重定向、环境变量
前面文章我们学习了linux基础命令,如果将不同命令组合使用则可以成倍提高工作效率.本文将学习重定向.管道符.通配符.转义符.以及重要的环境变量相关知识,为后面的shell编程打下基础. 一.IO重定 ...
- USACO简介导论
1000: USACO简介 时间限制: 1 Sec 内存限制: 128 MB提交: 8 解决: 7[提交] [状态] [讨论版] [命题人:外部导入] 题目描述 来源/分类 USACO-00 ...
- C# 中 ConfigureAwait 相关答疑FAQ
C# 中 ConfigureAwait 相关答疑FAQ 在前段时间经常看到园子里有一些文章讨论到 ConfigureAwait,刚好今天在微软官方博客看到了 Stephen Toub 前不久的一篇答疑 ...
- LCA - 求任意两点间的距离
There are n houses in the village and some bidirectional roads connecting them. Every day peole alwa ...
- 使用log4j把日志写到mysql数据库
log4j可以支持将log输出到文件,数据库,甚至远程服务器,本教程以mysql数据库为例来讲解: 作者:Jesai 没有伞的孩子,只能光脚奔跑! 1.数据库设计 数据库表 表4-1日志表(log) ...
- JS ES6补充
补充点:1.let const 2.字符串模板 3.箭头函数 4.对象的单体模式 5.面向对象 一.定义变量 A.var 特点: 1.定义全局变量 2.可以重复定义 3.变量名提升 <!DOC ...