AirScout/RainScout.Radars/RadarEU_CZ.cs

303 wiersze
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Net;
using RainScout.Core;
using System.Security.Cryptography.X509Certificates;
using System.ComponentModel;
using System.Net.Cache;
using System.IO;
using System.IO.IsolatedStorage;
using GMap.NET;
using GMap.NET.Projections;
using Newtonsoft.Json;
namespace RainScout.Radars
{
[Serializable]
public class RadarEU_CZ : RainScout.Radars.GenericRadar
{
string BaseURL = "http://www.radareu.cz/data/radar/";
// Radar images
private Bitmap IntensityImage = null;
private Bitmap CloudTopsImage = null;
private Bitmap LightningImage = null;
// values
private int[,] LightningValues = null;
// Radar legend
private ValueColorTable CloudTopsLegend = new ValueColorTable();
private ValueColorTable IntensityLegend = new ValueColorTable();
private ValueColorTable LightningLegend = new ValueColorTable();
// update cylce in seconds
private int UpdateCycle = 5 * 60;
// map zoom level
private readonly int MapZoom = 20;
public RadarEU_CZ()
{
Name = "Radar EU";
Source = "http://www.radareu.cz";
Left = -14.5;
Right = 45.25;
Top = 72.5;
Bottom = 31.0;
RadarLayers.Add(RADARLAYER.INTENSITY);
RadarLayers.Add(RADARLAYER.LIGHTNING);
// initialize intensity dictionary
IntensityLegend.Add(-1,Color.FromArgb(112, 0, 0, 0));
IntensityLegend.Add(0,Color.Transparent);
IntensityLegend.Add(1, Color.FromArgb(255, 1, 1, 1));
IntensityLegend.Add(4,Color.FromArgb(255, 55, 1, 117));
IntensityLegend.Add(8,Color.FromArgb(255, 7, 0, 246));
IntensityLegend.Add(16,Color.FromArgb(255, 0, 114, 198));
IntensityLegend.Add(20,Color.FromArgb(255, 1, 162, 1));
IntensityLegend.Add(24,Color.FromArgb(255, 0, 195, 5));
IntensityLegend.Add(28,Color.FromArgb(255, 50, 214, 2));
IntensityLegend.Add(32,Color.FromArgb(255, 155, 229, 7));
IntensityLegend.Add(36,Color.FromArgb(255, 221, 218, 0));
IntensityLegend.Add(40,Color.FromArgb(255, 247, 181, 1));
IntensityLegend.Add(44,Color.FromArgb(255, 254, 129, 3));
IntensityLegend.Add(48,Color.FromArgb(255, 251, 86, 0));
IntensityLegend.Add(52,Color.FromArgb(255, 252, 2, 6));
IntensityLegend.Add(56,Color.FromArgb(255, 150, 6, 10));
IntensityLegend.Add(60,Color.FromArgb(255, 255, 255, 255));
}
private Bitmap GetRadarImage(DateTime utc)
{
// gets actual radar image from url
string imagename = "radar.anim." + utc.ToString("yyyyMMdd") + "." + utc.ToString("HHmm") + ".0.png";
Bitmap image1 = null;
Bitmap image2 = null;
string url = BaseURL + imagename;
try
{
var request = WebRequest.Create(url);
using (var response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
image1 = new Bitmap(stream);
}
}
// crop image
Rectangle crop = new Rectangle();
crop.X = 2;
crop.Y = 2;
crop.Width = image1.Width - crop.X;
crop.Height = image1.Height - crop.Y;
image2 = new Bitmap(crop.Width, crop.Height);
using (Graphics g = Graphics.FromImage(image2))
{
g.DrawImage(image1, -crop.X, -crop.Y);
}
image2.Save("RadarEU_CZ.png");
this.Timestamp = utc;
}
catch (Exception ex)
{
// do nothing
return null;
}
return image2;
}
public void GetRadarImages()
{
// get current date and time string
DateTime utc = DateTime.UtcNow;
// round it to 15min interval
if (utc.Minute < 15)
utc = new DateTime(utc.Year, utc.Month, utc.Day, utc.Hour, 0, 0, DateTimeKind.Utc);
else if (utc.Minute < 30)
utc = new DateTime(utc.Year, utc.Month, utc.Day, utc.Hour, 15, 0, DateTimeKind.Utc);
else if (utc.Minute < 45)
utc = new DateTime(utc.Year, utc.Month, utc.Day, utc.Hour, 30, 0, DateTimeKind.Utc);
else if (utc.Minute < 60)
utc = new DateTime(utc.Year, utc.Month, utc.Day, utc.Hour, 45, 0, DateTimeKind.Utc);
Bitmap bm = GetRadarImage(utc);
if (bm == null)
{
// call failed --> try with 1 period earlier
utc = utc - new TimeSpan(0, 15, 0);
GetRadarImage(utc);
}
IntensityImage = bm;
GetLightningFromJSON();
// SaveLightningValuesAsCSV();
}
private void GetLightningFromJSON()
{
if (IntensityImage == null)
return;
int zoom = 5;
GPoint dsttl = MercatorProjection.Instance.FromLatLngToPixel(new PointLatLng(this.Top, this.Left), zoom);
GPoint dstbr = MercatorProjection.Instance.FromLatLngToPixel(new PointLatLng(this.Bottom, this.Right), zoom);
int dstwidth = (int)dstbr.X - (int)dsttl.X;
int dstheight = (int)dstbr.Y - (int)dsttl.Y;
LightningValues = new int[dstwidth, dstheight];
string baseurl = "https://map.blitzortung.org/GEOjson/getjson.php?f=s&n=";
for (int i = 0; i <=23; i++)
{
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(baseurl + i.ToString("00"));
RequestCachePolicy policy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
request.CachePolicy = policy;
request.CookieContainer = new CookieContainer();
request.Referer = "https://map.blitzortung.org/";
// get html page
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
string json = reader.ReadToEnd();
dynamic root = JsonConvert.DeserializeObject(json);
foreach (dynamic entry in root)
{
double lon = entry[0];
double lat = entry[1];
DateTime time = entry[2];
int age = (int)(DateTime.UtcNow - time).TotalMinutes;
GPoint p = MercatorProjection.Instance.FromLatLngToPixel(new PointLatLng(lat,lon), zoom);
int x = (int)p.X - (int)dsttl.X;
int y = (int)p.Y - (int)dsttl.Y;
if ((x > 1) && (x < dstwidth - 1) && (y >= 1) && (y < dstheight - 1))
{
LightningValues[x, y] = age;
LightningValues[x, y + 1] = age;
LightningValues[x + 1, y] = age;
LightningValues[x + 1, y + 1] = age;
}
}
}
}
}
catch (Exception ex)
{
}
}
}
public override Bitmap GetRadarImage()
{
// check for last update and get new images if necessary
if (Timestamp.AddSeconds(UpdateCycle) < DateTime.UtcNow)
{
GetRadarImages();
}
return IntensityImage;
}
public override int[,] GetRadarLayer(RADARLAYER layer)
{
// check for last update and get new images if necessary
if (Timestamp.AddSeconds(UpdateCycle) < DateTime.UtcNow)
{
GetRadarImages();
}
switch (layer)
{
case RADARLAYER.INTENSITY: return GetValuesFromImage(IntensityImage, IntensityLegend, NEARESTCOLORSTRATEGY.RGB);
case RADARLAYER.LIGHTNING: return LightningValues;
}
return null;
}
private int[,] GetValuesFromImage(Bitmap image, ValueColorTable legend, NEARESTCOLORSTRATEGY strategy)
{
if (image == null)
return null;
int[,] values = new int[image.Width, image.Height];
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color c = image.GetPixel(x, y);
try
{
if (c.A == 0)
values[x, y] = 0;
else if ((c.A > 0) && (c.A < 255))
values[x, y] = -1;
else
{
int v = legend.GetValueFromColor(c, strategy);
values[x, y] = v;
}
}
catch (Exception ex)
{
Console.WriteLine("Error getting color at (" + x.ToString() + "," + y.ToString() + ") - " + c.ToString() + ": " + ex.Message);
}
}
}
return values;
}
private void SaveLightningValuesAsCSV()
{
if (LightningImage == null)
return;
using (StreamWriter sw = new StreamWriter(File.OpenWrite("LightningValues.csv")))
{
for (int x = 0; x < LightningImage.Width; x++)
{
sw.Write(x.ToString() + ";");
}
sw.WriteLine();
for (int x = 0; x < LightningImage.Height; x++)
{
for (int y = 0; y < LightningImage.Width; y++)
{
Color c = LightningImage.GetPixel(y, x);
sw.Write(LightningLegend.GetValueFromColor(c, NEARESTCOLORSTRATEGY.RGB).ToString() + ";");
}
sw.WriteLine();
}
}
}
}
}