Unity如何免费持续获取卫星云图、雷达云图等天气数据图片,制作动态天气应用

后期上传demo

先看gif:
Unity如何免费持续获取卫星云图、雷达云图等天气数据图片,制作动态天气应用_第1张图片

步入正题了,如何做一款实时更新的天气预报software?
1.确定需要的数据,天气状况、最高/最低气温、当前气温、大气压、湿度、降水量、能见度、当前风向风速、PM2.5、卫星云图、雷达回波
2.前面的我觉得只要能打开浏览器都能搞定,找相关的数据接口,api。网上有很多,收费,不收费,限量收费。各种各样的很多,大多数返回数据是json类型,就不多做累述了。自行查找。
3.最后两个卫星云图、雷达回波,没有对应的api接口,于是另寻出路。
4.中国气象台网站,第一次进来的时候我也是蒙圈的,html网页数据怎么获取,又没有指定接口,而且也不知道规律。很难搞。
5.对比数据,挨个下载图片进行循环播放,达到动态雷达图的效果。

通过上图不难看出,数据来源是按照分钟级别来刷新的。而且最近的一张图大约是当前时间往前推20分钟。最后一张图是当前时间往前推2小时20分钟。毕竟卫星传回地球,然后再解析上传,是需要时间的。所以能理解。但是这样不规律的数据是很头疼的。
只能通过一分一分的往前推,判断该时间是否有雷达图数据,有的话就下载(UnityWebRequestTexture)存储然后继续上一分钟判断,没有的话就继续上一分钟判断。从而达到获取2小时20分钟之内的所有雷达图数据。再进行循环播放,达到动态雷达图的效果。
每个周期有15张左右图片。
分析图片网址规律:
右键点击图片,新标签打开图片。

上图可以看出,有两个时间戳,第一个时间戳是UTC时间(国际时间)的 “年/月/日”,第二个时间戳是UTC时间(国际时间)的 “年月日时分00000”。.JPG之后的数据经过测试,属于无用数据,可以直接忽略。
注:把图片下载下来,注意图片的尺寸,ui尺寸对应上。
规律找到,通过计算、改变时间戳拼接成网址,就能挨个下载当前网站所有的雷达图数据了。

不说了,上实现代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class DownloadNephogram : MonoBehaviour
{
    public RawImage rawImg;//显示图片的ui
    public Dictionary Texture2DsDic = new Dictionary();//按照时间戳存储下载的图片
    public List Texture2DsNum;//记录时间戳列表  后续排序使用
    private int Year;
    private int Month;
    private int Day;
    private int Hour;
    private int Minute;

    private int BeforeHour;
    private int BackMinute;//回退时间,20分钟前有图像数据
    public int TargetHour;//目标小时,回退2小时
    public int CurrentHour;//当前小时
    public int TargetMinute;//目标分钟,回退2小时
    public int CurrentMinute;//当前分钟
    public string UrlDateTime;//日期数据  第一个时间戳
    public string UrlImageName;//图片名称数据  第二个时间戳
    public bool IsLoaded;//已经下载完成

    public float CurrentLoadNum;//当前加载的图片序列
    
    Texture2D tex2d;

    void Update()
    {
        TimeCalculate();
        UpdateRawImg();
    }
    /// 
    /// 时间戳计算、回退目标时间计算、刷新周期设置
    /// 
    void TimeCalculate()
    {
        Hour = DateTime.UtcNow.Hour;
        if (BeforeHour != Hour)//达到每小时整点更新一次
        {
            StopCoroutine("DownLoadImage");
            //Texture2Ds.Clear();
            Texture2DsDic.Clear();
            Texture2DsNum.Clear();

            IsLoaded = false;
            CurrentLoadNum = 0;

            Year = DateTime.UtcNow.Year;
            Month = DateTime.UtcNow.Month;
            Day = DateTime.UtcNow.Day;
            Hour = DateTime.UtcNow.Hour;
            Minute = DateTime.UtcNow.Minute;
            if (Minute < BackMinute)//时间回退判断
            {
                if (Hour == 0)//小时判断  如果是0点,回退就是23点
                {
                    Hour = 23;
                    Minute = 60 - Minute + BackMinute;
                    DayJudge();
                }
                else
                {
                    Hour--;
                    Minute = 60 - Minute + BackMinute;
                }
            }
            FormatTime(Year, Month, Day, Hour, Minute);
            if (Hour == 1)
                TargetHour = 23;
            else if (Hour == 0)
                TargetHour = 22;
            else
                TargetHour = Hour - 2;
            CurrentHour = Hour;
            CurrentMinute = TargetMinute = Minute;
            BeforeHour = Hour;


            ForLoopDownLoad();//
        }
    }
    /// 
    /// 天数判断
    /// 
    void DayJudge()
    {
        if (Day == 1)//月份天数判断
        {
            if (Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12)//31天
            {
                if (Month == 1)//年份判断
                    Year--;
                Day = 31;
            }
            else if (Month == 2)
            {
                if (Year % 4 == 0)//28天
                    Day = 28;
                else//27天
                    Day = 27;
            }
            else//30天的月份
                Day = 30;
        }
    }

    /// 
    /// 更新循环显示图片
    /// 
    void UpdateRawImg()
    {
        if (IsLoaded)
        {
            if (CurrentLoadNum > Texture2DsNum.Count-1)
                CurrentLoadNum = 0;

            if (Texture2DsDic.ContainsKey(Texture2DsNum[(int)CurrentLoadNum]))//判断该时间戳是否有图片,有就更新
            {
                rawImg.texture = Texture2DsDic[Texture2DsNum[(int)CurrentLoadNum]];
            }

            if (CurrentLoadNum >= 0)
            {
                CurrentLoadNum += 0.03f;
            }
        }
        else
        {
            if (Texture2DsDic.Count>0)
            {
                Texture2DsNum.Sort();
                /*因for循环下载,网速等原因使得字典存储无序;
                 所以用列表进行一次列表内的时间戳排序。
                 再用字典按序查找列表内的long类型时间戳。
                 达到顺序播放*/
                IsLoaded = true;
            }
        }
    }
    /// 
    /// 格式化时间戳
    /// 
    /// 年
    /// 月
    /// 日
    /// 小时
    /// 分钟
    void FormatTime(int year, int month, int day, int hour, int minute)
    {
        UrlDateTime = $"{year:D4}/{month:D2}/{day:D2}";
        UrlImageName = $"{year:D4}{month:D2}{day:D2}{hour:D2}{minute:D2}{"00000"}";
    }

    /// 
    /// 利用for循环开启每一分钟的下载协程,同时下载这段时间内的所有图片。达到最快的下载速度。
    /// 优点:下载速度快
    /// 缺点:下载时无序,循环播放时需要考虑排序问题;性能消耗大,因暂时没想好怎么用线程开启网络下载,目前用的笨方法,希望大神指点。
    /// 需要考虑临界时间的for循环判断,比如0点前2小时是23、22点。1点前2小时是0、23点。
    /// 
    void ForLoopDownLoad()
    {
        if (CurrentHour == 1)
        {
            for (int i = CurrentHour; i >= -1 && i <= 1; i--)
            {
                CurrentHour = i;
                if (CurrentHour == -1)
                {
                    CurrentHour = 23;
                    DayJudge();
                }

                //Debug.LogWarning(CurrentHour);
                if (1 == CurrentHour)
                {
                    if (CurrentMinute != 0)
                    {
                        for (int j = CurrentMinute; j > -1; j--)
                        {
                            CurrentMinute = j;
                            //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                    }
                    else
                    {
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");
                    }
                }
                else if (0 == CurrentHour)
                {
                    for (int j = 59; j > -1; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");
                    }
                }
                else if (23 == CurrentHour)
                {
                    for (int j = 59; j >= TargetMinute; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        if (CurrentMinute != TargetMinute)
                        {
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                        else
                        {
                            StopCoroutine("DownLoadImage");
                        }
                    }
                }
            }
        }
        else if (CurrentHour == 0)
        {
            for (int i = CurrentHour; i >= -2 && i <= 0; i--)
            {
                CurrentHour = i;
                if (CurrentHour == -1)
                {
                    CurrentHour = 23;
                    DayJudge();
                }

                if (CurrentHour == -2)
                    CurrentHour = 22;
                //Debug.LogWarning(CurrentHour);
                if (0 == CurrentHour)
                {
                    if (CurrentMinute != 0)
                    {
                        for (int j = CurrentMinute; j > -1; j--)
                        {
                            CurrentMinute = j;
                            //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                    }
                    else
                    {
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");
                    }
                }
                else if (23 == CurrentHour)
                {
                    for (int j = 59; j > -1; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");

                    }
                }
                else if (22 == CurrentHour)
                {
                    for (int j = 59; j >= TargetMinute; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        if (CurrentMinute != TargetMinute)
                        {
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                        else
                        {
                            StopCoroutine("DownLoadImage");
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = CurrentHour; i >= TargetHour; i--)
            {
                CurrentHour = i;
                //Debug.LogWarning(CurrentHour);
                if (TargetHour + 2 == CurrentHour)
                {
                    if (CurrentMinute != 0)
                    {
                        for (int j = CurrentMinute; j > -1; j--)
                        {
                            CurrentMinute = j;
                            //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                    }
                    else
                    {
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");
                    }
                }
                else if (TargetHour + 1 == CurrentHour)
                {
                    for (int j = 59; j > -1; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");
                        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                        StartCoroutine("DownLoadImage");
                    }
                }
                else if (TargetHour == CurrentHour)
                {
                    for (int j = 59; j >= TargetMinute; j--)
                    {
                        CurrentMinute = j;
                        //Debug.Log("现在是" + CurrentHour + "点" + CurrentMinute + "分");

                        if (CurrentMinute!=TargetMinute)
                        {
                            FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
                            StartCoroutine("DownLoadImage");
                        }
                        else
                        {
                            StopCoroutine("DownLoadImage");
                        }
                    }
                }
            }
        }
    }

    void ContinueLoad()
    {
        if (CurrentMinute == 0)
        {
            CurrentMinute = 59;
            if (CurrentHour != 0)
                CurrentHour--;
            else
                CurrentHour = 23;
        }
        else
        {
            CurrentMinute--;
        }
        FormatTime(Year, Month, Day, CurrentHour, CurrentMinute);
        if (TargetHour != CurrentHour || TargetMinute != CurrentMinute)
            StartCoroutine("DownLoadImage");
        else
        {

            StopCoroutine("DownLoadImage");
            IsLoaded = true;
        }
    }

    /// 
    /// 下载图片
    /// 
    /// 
    IEnumerator DownLoadImage()
    {
        using (UnityWebRequest w = UnityWebRequestTexture.GetTexture("http://image.nmc.cn/product/" + UrlDateTime + Url + UrlImageName + ".JPG"))
        {
            long rec = long.Parse(UrlImageName);
            yield return w.SendWebRequest();
            if (w.isDone)
            {
                if (w.isNetworkError || w.isHttpError)
                {
                    Debug.Log(w.error);
                }
                else
                {
                    if (w.responseCode == 200)
                    {
                        tex2d = new Texture2D(width, height, TextureFormat.RGB24, false);
                        tex2d.LoadImage(w.downloadHandler.data);
                        if (Texture2DsDic.ContainsKey(rec))
                        {
                            Texture2DsDic[rec] = tex2d;
                        }
                        else
                        {
                            Texture2DsDic.Add(rec, tex2d);
                        }
                        Texture2DsNum.Add(rec);
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(Unity)