AirScout/ScoutBase/ScoutBase.Data/GLOBE.cs

867 wiersze
37 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
using System.Globalization;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Forms;
using System.Configuration;
using System.Data;
using ScoutBase.Data;
using Newtonsoft.Json;
using ScoutBase.Core;
namespace ScoutBase.Data
{
[System.ComponentModel.DesignerCategory("")]
public class DataTableGLOBE : DataTable
{
public DataTableGLOBE()
: base()
{
// set table name
TableName = "GLOBE";
// create all specific columns
DataColumn FileIndex = this.Columns.Add("FileIndex", typeof(string));
DataColumn FileName = this.Columns.Add("Filename", typeof(string));
DataColumn MinLat = this.Columns.Add("MinLat", typeof(double));
DataColumn MaxLat = this.Columns.Add("MaxLat", typeof(double));
DataColumn MinLon = this.Columns.Add("MinLon", typeof(double));
DataColumn MaxLon = this.Columns.Add("MaxLon", typeof(double));
DataColumn MinElv = this.Columns.Add("MinElv", typeof(int));
DataColumn MaxElv = this.Columns.Add("MaxElv", typeof(int));
DataColumn Rows = this.Columns.Add("Rows", typeof(int));
DataColumn Columns = this.Columns.Add("Columns", typeof(int));
DataColumn Version = this.Columns.Add("Version", typeof(int));
DataColumn URL = this.Columns.Add("URL", typeof(string));
DataColumn Status = this.Columns.Add("Status", typeof(string));
DataColumn Local = this.Columns.Add("Local", typeof(bool));
DataColumn LastUpdated = this.Columns.Add("LastUpdated", typeof(string));
// create primary key
DataColumn[] keys = new DataColumn[1];
keys[0] = FileIndex;
this.PrimaryKey = keys;
}
}
[Serializable]
[System.ComponentModel.DesignerCategory("")]
public class JSONArrayGLOBE : Object
{
public string version = "";
public int full_count = 0;
public List<List<string>> tiles;
public JSONArrayGLOBE()
{
version = "";
full_count = 0;
tiles = new List<List<string>>();
}
public JSONArrayGLOBE(GLOBEDictionary globe)
{
version = globe.Version;
full_count = globe.Tiles.Count;
tiles = new List<List<string>>();
for (int i = 0; i < full_count; i++)
{
List<string> l = new List<string>();
GLOBETileDesignator tile = globe.Tiles.Values.ElementAt(i);
l.Add(tile.FileIndex);
l.Add(tile.FileName);
l.Add(tile.MinLat.ToString("F8", CultureInfo.InvariantCulture));
l.Add(tile.MaxLat.ToString("F8", CultureInfo.InvariantCulture));
l.Add(tile.MinLon.ToString("F8", CultureInfo.InvariantCulture));
l.Add(tile.MaxLon.ToString("F8", CultureInfo.InvariantCulture));
l.Add(tile.MinElv.ToString());
l.Add(tile.MaxElv.ToString());
l.Add(tile.Rows.ToString());
l.Add(tile.Columns.ToString());
l.Add(tile.URL.ToString());
l.Add(tile.Status.ToString());
l.Add(tile.Local.ToString());
l.Add(tile.LastUpdated.ToString("u"));
tiles.Add(l);
}
}
}
public enum GLOBETILESTATUS
{
UNDEFINED = 'U',
BAD = 'B',
GOOD = 'G',
}
/// <summary>
/// Holds the GLOBE tile information
/// </summary>
[System.ComponentModel.DesignerCategory("")]
public class GLOBETileDesignator
{
public string FileIndex;
public string FileName = "";
public double MinLat = 0;
public double MaxLat = 0;
public double MinLon = 0;
public double MaxLon = 0;
public int MinElv = int.MaxValue;
public int MaxElv = int.MinValue;
public int Rows = 0;
public int Columns = 0;
public int Version = 0;
public string URL = "";
public GLOBETILESTATUS Status;
public bool Local;
public DateTime LastUpdated;
public GLOBETileDesignator(string fileindex, string filename, double minlat, double maxlat, double minlon, double maxlon, int minelv, int maxelv, int rows, int columns, int version, string url, GLOBETILESTATUS status, bool local)
: this(fileindex, filename, minlat, maxlat, minlon, maxlon, minelv, maxelv, rows, columns, version, url, status, local, DateTime.UtcNow) { }
public GLOBETileDesignator(string fileindex, string filename, double minlat, double maxlat, double minlon, double maxlon, int minelv, int maxelv, int rows, int columns, int version, string url, GLOBETILESTATUS status, bool local, DateTime lastupdated)
{
FileIndex = fileindex;
FileName = filename;
MinLat = minlat;
MaxLat = maxlat;
MinLon = minlon;
MaxLon = maxlon;
MinElv = minelv;
MaxElv = maxelv;
Rows = rows;
Columns = columns;
Version = version;
URL = url;
Status = status;
Local = local;
LastUpdated = lastupdated;
}
}
public class URLInfo
{
public string Index;
public int Version;
public string Status;
public string URL;
public URLInfo(string index, int version, string status, string url)
{
Index = index;
Version = version;
Status = status;
URL = url;
}
}
/// <summary>
/// Holds the GLOBE Elevation Model in a directory structure.
/// Returns the elevation of any point referenced with latitude and longitude.
/// </summary>
/// <param name="Latitude">The latitude of point.</param>
/// <param name="Longitude">The The longitude of point.</param>
/// <returns>An elevation value according to lat/lon.</returns>
/// <summary>
/// Holds a GLOBE tile collction
/// </summary>
[System.ComponentModel.DesignerCategory("")]
public class GLOBEDictionary : Object
{
public string Version
{
get
{
return System.Reflection.Assembly.GetAssembly(typeof(ScoutBaseDatabase)).GetName().Version.ToString();
}
}
public string Name
{
get
{
return "GLOBE";
}
}
private bool changed = false;
public bool Changed
{
get
{
return changed;
}
}
public SortedDictionary<string, GLOBETileDesignator> Tiles = new SortedDictionary<string, GLOBETileDesignator>();
private int elv_missing_flag = -500;
public GLOBEDictionary()
{
}
public GLOBEDictionary(DataTable table)
{
// create dictionary from data table
FromTable(table);
// reset changed flag
changed = false;
}
public void Clear()
{
// clean up tile dictionary
if (Tiles != null)
{
if (Tiles.Count > 0)
changed = true;
Tiles.Clear();
}
}
public bool IsGLOBEFile(string filename)
{
// checks for a valid filename with/witout extension
// filename must have a xxxx. notation
// [0]: 'A'..'P'
// [1],[2]: nn = version
// [3]: 'G','B','S','T' = status
// 'S' and 'T' are not used
if (String.IsNullOrEmpty(filename))
return false;
string upperfilename = Path.GetFileNameWithoutExtension(filename).ToUpper();
// return on extension not empty
string extension = Path.GetExtension(filename);
if (!String.IsNullOrEmpty(extension))
return false;
char index = upperfilename[0];
char status = upperfilename[3];
// check length of filename
if (upperfilename.Length != 4)
return false;
// check allowed chars
if ((index < 'A')
|| (index > 'P')
|| !Char.IsDigit(upperfilename[1])
|| !Char.IsDigit(upperfilename[2])
|| ((status != 'G') && (status != 'B'))
)
return false;
//check length
long l = 0;
switch (index)
{
case 'A':
case 'B':
case 'C':
case 'D':
case 'M':
case 'N':
case 'O':
case 'P':
l = 4800 * 10800 * 2;
break;
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
l = 6000 * 10800 * 2;
break;
}
if (l != new System.IO.FileInfo(filename).Length)
return false;
return true;
}
public GLOBETileDesignator GetTileFromPoint(double lat, double lon)
{
foreach (GLOBETileDesignator tile in this.Tiles.Values)
{
if ((lat > tile.MinLat) &&
(lat <= tile.MaxLat) &&
(lon >= tile.MinLon) &&
(lon < tile.MaxLon) &&
tile.Local)
return tile;
}
return null;
}
public GLOBETileDesignator GetTileInfoFromFile(string filename)
{
if (!IsGLOBEFile(filename))
return null;
string upperfilename = Path.GetFileNameWithoutExtension(filename).ToUpper();
char index = upperfilename[0];
int vresion = System.Convert.ToInt32(upperfilename.Substring(1, 2));
char status = upperfilename[3];
GLOBETileDesignator tile = null;
switch (index)
{
case 'A':
tile = new GLOBETileDesignator("A", filename, 50.0, 90.0, -180.0, -90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'B':
tile = new GLOBETileDesignator("B", filename, 50.0, 90.0, -90.0, -0.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'C':
tile = new GLOBETileDesignator("C", filename, 50.0, 90.0, 0.0, 90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'D':
tile = new GLOBETileDesignator("D", filename, 50.0, 90.0, 90.0, 180.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'E':
tile = new GLOBETileDesignator("E", filename, 0.0, 50.0, -180.0, -90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'F':
tile = new GLOBETileDesignator("F", filename, 0.0, 50.0, -90.0, -0.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'G':
tile = new GLOBETileDesignator("G", filename, 0.0, 50.0, 0.0, 90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'H':
tile = new GLOBETileDesignator("H", filename, 0.0, 50.0, 90.0, 180.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'I':
tile = new GLOBETileDesignator("I", filename, -50.0, 0.0, -180.0, -90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'J':
tile = new GLOBETileDesignator("J", filename, -50.0, 0.0, -90.0, -0.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'K':
tile = new GLOBETileDesignator("K", filename, -50.0, 0.0, 0.0, 90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'L':
tile = new GLOBETileDesignator("L", filename, -50.0, 0.0, 90.0, 180.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'M':
tile = new GLOBETileDesignator("M", filename, -90.0, -50.0, -180.0, -90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'N':
tile = new GLOBETileDesignator("N", filename, -90.0, -50.0, -90.0, -0.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'O':
tile = new GLOBETileDesignator("O", filename, -90.0, -50.0, 0.0, 90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
case 'P':
tile = new GLOBETileDesignator("P", filename, -90.0, -50.0, 90.0, 180.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, true);
break;
default:
return null;
}
try
{
int.TryParse(upperfilename.Substring(1, 2), out tile.Version);
tile.Status = (GLOBETILESTATUS)Enum.ToObject(typeof(GLOBETILESTATUS), upperfilename[3]);
}
catch (Exception ex)
{
// do nothing
}
return tile;
}
public void Scan()
{
try
{
SortedDictionary<string, GLOBETileDesignator> localtiles = GetAllTilesFromLocalDir();
SortedDictionary<string, GLOBETileDesignator> webtiles = GetAllTilesFromWeb();
// save all new tiles in a separate directory
// reset all tiles which are not available anymore, add missing with default values
Tiles.Clear();
// add all local tiles
foreach (GLOBETileDesignator tile in localtiles.Values)
{
Console.WriteLine("Scanning tile: " + tile.FileName + "...");
// search for index in webtiles and grab url if found
GLOBETileDesignator webtile;
if (webtiles.TryGetValue(tile.FileIndex, out webtile))
{
// same version found on web --> update url
if (webtile.Version == tile.Version)
{
tile.URL = webtile.URL;
}
else if (webtile.Version > tile.Version)
{
// newer tile found on web
// reset tile information
tile.FileName = "";
tile.Version = webtile.Version;
tile.MinElv = int.MaxValue;
tile.MaxElv = int.MinValue;
tile.Status = webtile.Status;
tile.Local = false;
tile.URL = webtile.URL;
}
// remove web tile info
webtiles.Remove(webtile.FileIndex);
}
Update(tile);
}
// add rest of web tiles
foreach (GLOBETileDesignator tile in webtiles.Values)
{
Update(tile);
}
}
catch (Exception ex)
{
// do nothing
}
}
private SortedDictionary<string, GLOBETileDesignator> GetAllTilesFromLocalDir()
{
// return empty dictionary if path not found
if (!Directory.Exists(global::ScoutBase.Data.Properties.Settings.Default.GLOBE_DataPath))
return new SortedDictionary<string, GLOBETileDesignator>();
SortedDictionary<string, GLOBETileDesignator> localtiles = new SortedDictionary<string, GLOBETileDesignator>();
FileInfo[] GLOBEfiles = new DirectoryInfo(global::ScoutBase.Data.Properties.Settings.Default.GLOBE_DataPath).GetFiles("????.*");
foreach (FileInfo file in GLOBEfiles)
{
try
{
GLOBETileDesignator tile = GetTileInfoFromFile(file.FullName);
if (tile != null)
{
// valid tile found, complete tile information
// check min/max info
GLOBETileDesignator oldtile;
if ((tile.MaxElv == int.MinValue) || (tile.MinElv == int.MaxValue))
{
// try to get cached min/max info
if (Tiles.TryGetValue(tile.FileIndex, out oldtile))
{
tile.MinElv = oldtile.MinElv;
tile.MaxElv = oldtile.MaxElv;
}
// still no min/max info?
if ((tile.MaxElv == int.MinValue) || (tile.MinElv == int.MaxValue))
{
// calculate min/max elevation
CalcMinMaxElevation(ref tile);
}
}
if (localtiles.TryGetValue(tile.FileIndex, out oldtile))
{
if ((tile.Status == GLOBETILESTATUS.GOOD) && (tile.Version > oldtile.Version))
{
//remove outdated tile
localtiles.Remove(oldtile.FileIndex);
}
}
localtiles.Add(tile.FileIndex, tile);
}
}
catch (Exception ex)
{
}
}
return localtiles;
}
private SortedDictionary<string, GLOBETileDesignator> GetAllTilesFromWeb()
{
// check for valid urls
if (string.IsNullOrEmpty(global::ScoutBase.Data.Properties.Settings.Default.GLOBE_URLs))
return new SortedDictionary<string, GLOBETileDesignator>();
// split urls if necessary
string[] globeurls;
if (global::ScoutBase.Data.Properties.Settings.Default.GLOBE_URLs.Contains("\r\n"))
globeurls = global::ScoutBase.Data.Properties.Settings.Default.GLOBE_URLs.Split(new string[] { "\r\n" }, StringSplitOptions.None);
else
{
globeurls = new string[1];
globeurls[0] = global::ScoutBase.Data.Properties.Settings.Default.GLOBE_URLs;
}
// create a searchable index of all available tiles from web
SortedDictionary<string, URLInfo> urls = new SortedDictionary<string,URLInfo>();
foreach (string globeurl in globeurls)
{
HTTPDirectorySearcher s = new HTTPDirectorySearcher();
List<HTTPDirectoryItem> l = s.GetDirectoryInformation(globeurl);
foreach (HTTPDirectoryItem item in l)
{
try
{
// find possible file names
if (item.Name.Contains(".zip"))
{
string fileindex = item.Name.Split('.')[0].ToUpper().Substring(0,1);
int version = System.Convert.ToInt32(item.Name.Split('.')[0].ToUpper().Substring(1,2));
string status = item.Name.Split('.')[0].ToUpper().Substring(3,1);
URLInfo url = new URLInfo(fileindex, version, status, item.AbsolutePath);
URLInfo oldurl;
if (urls.TryGetValue(fileindex, out oldurl))
{
if ((url.Status == "G") && (url.Version > oldurl.Version))
urls.Remove(oldurl.Index);
}
urls.Add(url.Index, url);
}
}
catch
{
}
}
}
// initally generate tile info
SortedDictionary<string, GLOBETileDesignator> globetiles = new SortedDictionary<string, GLOBETileDesignator>();
GLOBETileDesignator globetile;
globetile = new GLOBETileDesignator("A", "", 50.0, 90.0, -180.0, -90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("B", "", 50.0, 90.0, -90.0, -0.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("C", "", 50.0, 90.0, 0.0, 90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("D", "", 50.0, 90.0, 90.0, 180.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("E", "", 0.0, 50.0, -180.0, -90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("F", "", 0.0, 50.0, -90.0, -0.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("G", "", 0.0, 50.0, 0.0, 90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("H", "", 0.0, 50.0, 90.0, 180.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("I", "", -50.0, 0.0, -180.0, -90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("J", "", -50.0, 0.0, -90.0, -0.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("K", "", -50.0, 0.0, 0.0, 90.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("L", "", -50.0, 0.0, 90.0, 180.0, int.MaxValue, int.MinValue, 6000, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("M", "", -90.0, -50.0, -180.0, -90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("N", "", -90.0, -50.0, -90.0, -0.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("O", "", -90.0, -50.0, 0.0, 90.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
globetile = new GLOBETileDesignator("P", "", -90.0, -50.0, 90.0, 180.0, int.MaxValue, int.MinValue, 4800, 10800, 0, "", GLOBETILESTATUS.UNDEFINED, false);
globetiles.Add(globetile.FileIndex, globetile);
SortedDictionary<string, GLOBETileDesignator> webtiles = new SortedDictionary<string, GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in globetiles.Values)
{
// search tile in web tile index
URLInfo url;
if (urls.TryGetValue(tile.FileIndex, out url))
{
// add tile if found
tile.URL = url.URL;
tile.Version = url.Version;
try
{
tile.Status = (GLOBETILESTATUS)url.Status[0];
}
catch
{
}
webtiles.Add(tile.FileIndex, tile);
}
}
return webtiles;
}
public void CalcMinMaxElevation(ref GLOBETileDesignator tile)
{
try
{
// open file to get more information
if (tile.Local && ((tile.MinElv == int.MaxValue) || (tile.MaxElv == int.MinValue)))
{
using (BinaryReader br = new BinaryReader(File.OpenRead(tile.FileName)))
{
tile.MinElv = int.MaxValue;
tile.MaxElv = int.MinValue;
long l = br.BaseStream.Length / 2;
for (int i = 0; i < l; i++)
{
short s = br.ReadInt16();
if (s != elv_missing_flag)
{
if (s < tile.MinElv)
tile.MinElv = s;
if (s > tile.MaxElv)
tile.MaxElv = s;
}
}
}
}
}
catch (Exception ex)
{
}
}
public void FromTable(DataTable dt)
{
if (dt == null)
return;
this.Clear();
foreach (DataRow row in dt.Rows)
{
string index = row["FileIndex"].ToString();
string filename = row["FileName"].ToString();
double minlat = System.Convert.ToDouble(row["MinLat"]);
double maxlat = System.Convert.ToDouble(row["MaxLat"]);
double minlon = System.Convert.ToDouble(row["MinLon"]);
double maxlon = System.Convert.ToDouble(row["MaxLon"]);
int minelv = System.Convert.ToInt32(row["MinElv"]);
int maxelv = System.Convert.ToInt32(row["MaxElv"]);
int rows = System.Convert.ToInt32(row["Rows"]);
int columns = System.Convert.ToInt32(row["Columns"]);
int version = System.Convert.ToInt32(row["Version"]);
string url = row["URL"].ToString();
GLOBETILESTATUS status = (GLOBETILESTATUS)Enum.Parse(typeof(GLOBETILESTATUS), row["Status"].ToString());
bool local = System.Convert.ToBoolean(row["Local"]);
DateTime lastupdated = DateTime.UtcNow;
try
{
try
{
lastupdated = DateTime.ParseExact(row["LastUpdated"].ToString(), "yyyy-MM-dd HH:mm:ssZ", CultureInfo.InvariantCulture);
lastupdated = lastupdated.ToUniversalTime();
}
catch
{
}
Update(new GLOBETileDesignator(index,filename,minlat,maxlat,minlon, maxlon, minelv, maxelv, rows, columns,version, url, status, local,lastupdated));
}
catch
{
}
}
}
public DataTable ToTable()
{
DataTableGLOBE dt = new DataTableGLOBE();
foreach (KeyValuePair<string, GLOBETileDesignator> tile in Tiles)
{
DataRow row = dt.NewRow();
row["FileIndex"] = tile.Value.FileIndex;
row["Filename"] = tile.Value.FileName;
row["MinLat"] = tile.Value.MinLat;
row["MaxLat"] = tile.Value.MaxLat;
row["MinLon"] = tile.Value.MinLon;
row["MaxLon"] = tile.Value.MaxLon;
row["MinElv"] = tile.Value.MinElv;
row["MaxElv"] = tile.Value.MaxElv;
row["Rows"] = tile.Value.Rows;
row["Columns"] = tile.Value.Columns;
row["Version"] = tile.Value.Version;
row["URL"] = tile.Value.URL;
row["Status"] = tile.Value.Status.ToString();
row["Local"] = tile.Value.Local;
row["LastUpdated"] = tile.Value.LastUpdated.ToString("u");
dt.Rows.Add(row);
}
return dt;
}
public DataTable FromJSONArray(string filename)
{
if (!File.Exists(filename))
return new DataTableGLOBE();
try
{
using (StreamReader sr = new StreamReader(File.OpenRead(filename)))
{
string json = sr.ReadToEnd();
JSONArrayGLOBE a = JsonConvert.DeserializeObject<JSONArrayGLOBE>(json);
// check version
if (String.Compare(Version, a.version) != 0)
{
// do upgrade/downgrade stuff here
}
else
{
foreach (List<string> l in a.tiles)
{
string fileindex = l[0];
string FileName = l[1];
double minlat = System.Convert.ToDouble(l[2], CultureInfo.InvariantCulture);
double maxlat = System.Convert.ToDouble(l[3], CultureInfo.InvariantCulture);
double minlon = System.Convert.ToDouble(l[4], CultureInfo.InvariantCulture);
double maxlon = System.Convert.ToDouble(l[5], CultureInfo.InvariantCulture);
int minelv = System.Convert.ToInt32(l[6]);
int maxelv = System.Convert.ToInt32(l[7]);
int rows = System.Convert.ToInt32(l[8]);
int columns = System.Convert.ToInt32(l[9]);
int version = System.Convert.ToInt32(l[10]);
string url = l[11];
GLOBETILESTATUS status = GLOBETILESTATUS.UNDEFINED;
try
{
status = (GLOBETILESTATUS)Enum.Parse(typeof(GLOBETILESTATUS), l[12]);
}
catch
{
}
bool local = System.Convert.ToBoolean(l[13]);
DateTime lastupdated = DateTime.UtcNow;
try
{
lastupdated = System.Convert.ToDateTime(l[4]);
}
catch
{
}
Update(new GLOBETileDesignator(fileindex, filename, minlat, maxlat, minlon, maxlon, minelv, maxelv, rows, columns, version,url, status, local, lastupdated));
}
}
}
return ToTable();
}
catch (Exception ex)
{
}
return new DataTableGLOBE();
}
public string ToJSONArray()
{
JSONArrayGLOBE a = new JSONArrayGLOBE(this);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.FloatFormatHandling = FloatFormatHandling.String;
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(a, settings);
return json;
}
public void Update(GLOBETileDesignator tile)
{
// return on null
if (tile == null)
return;
GLOBETileDesignator entry = null;
lock (this)
{
if (Tiles.TryGetValue(tile.FileIndex, out entry))
{
entry.FileIndex = tile.FileIndex;
entry.FileName = tile.FileName;
entry.MinLat = tile.MinLat;
entry.MaxLat = tile.MaxLat;
entry.MinLon = tile.MinLon;
entry.MaxLon = tile.MaxLon;
entry.MinElv = tile.MinElv;
entry.MaxElv = tile.MaxElv;
entry.Rows = tile.Rows;
entry.Columns = tile.Columns;
entry.Version = tile.Version;
entry.URL = tile.URL;
entry.Status = tile.Status;
entry.Local = tile.Local;
entry.LastUpdated = tile.LastUpdated;
changed = true;
}
else
{
this.Tiles.Add(tile.FileIndex, new GLOBETileDesignator(tile.FileIndex, tile.FileName, tile.MinLat, tile.MaxLat, tile.MinLon, tile.MaxLon, tile.MinElv, tile.MaxElv, tile.Rows, tile.Columns, tile.Version, tile.URL, tile.Status, tile.Local, tile.LastUpdated));
changed = true;
}
}
}
public List<GLOBETileDesignator> GetAllTiles()
{
List<GLOBETileDesignator> l = new List<GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in Tiles.Values)
{
l.Add(tile);
}
return l;
}
public List<GLOBETileDesignator> GetLocalTiles()
{
List<GLOBETileDesignator> l = new List<GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in Tiles.Values)
{
if (tile.Local)
l.Add(tile);
}
return l;
}
public List<GLOBETileDesignator> GetLocalTiles(double minlat, double maxlat, double minlon, double maxlon)
{
Rect area = new Rect(minlon, minlat, maxlon - minlon, maxlat - minlat);
List<GLOBETileDesignator> a = GetLocalTiles();
List<GLOBETileDesignator> l = new List<GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in a)
{
Rect r = new Rect(tile.MinLon, tile.MinLat, tile.MaxLon - tile.MinLon, tile.MaxLat - tile.MinLat);
if (tile.Local && area.IntersectsWith(r))
l.Add(tile);
}
return l;
}
public List<GLOBETileDesignator> GetAvailableTiles()
{
List<GLOBETileDesignator> l = new List<GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in Tiles.Values)
{
if (!String.IsNullOrEmpty(tile.URL))
l.Add(tile);
}
return l;
}
public List<GLOBETileDesignator> GetAvailableTiles(double minlat, double maxlat, double minlon, double maxlon)
{
Rect area = new Rect(minlon, minlat, maxlon - minlon, maxlat - minlat);
List<GLOBETileDesignator> a = GetAvailableTiles();
List<GLOBETileDesignator> l = new List<GLOBETileDesignator>();
foreach (GLOBETileDesignator tile in a)
{
Rect r = new Rect(tile.MinLon, tile.MinLat, tile.MaxLon - tile.MinLon, tile.MaxLat - tile.MinLat);
if (!tile.Local && area.IntersectsWith(r))
l.Add(tile);
}
return l;
}
public void DownloadTile(GLOBETileDesignator tile)
{
if (tile == null)
return;
if (String.IsNullOrEmpty(tile.URL))
return;
AutoDecompressionWebClient cl = new AutoDecompressionWebClient();
string filename = Path.GetFileName(tile.URL.Substring(tile.URL.LastIndexOf('/')));
cl.DownloadFile(tile.URL, Path.Combine(Properties.Settings.Default.GLOBE_DataPath, filename));
}
}
}