kopia lustrzana https://github.com/dl2alf/AirScout
303 wiersze
11 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|