optimise station database by stripping unused info

This commit is contained in:
2021-07-29 21:07:53 +02:00
parent 3eccbaa8b8
commit 3b43051200
8 changed files with 202 additions and 5 deletions

View File

@@ -1,20 +1,29 @@
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace NonaBGS.EDDB {
public class API {
private static readonly string EDDB_SYSTEMS_ARCHIVE = "https://eddb.io/archive/v6/systems_populated.json";
private static readonly string EDDB_STATIONS_ARCHIVE = "https://eddb.io/archive/v6/stations.json";
private string cache_folder = null;
private readonly WebClient client = new WebClient();
private string systems_file = null;
private string stations_file = null;
private string stations_file_short = null;
public delegate void DatabaseAvailableDelegate();
public event DatabaseAvailableDelegate SystemsAvailable;
public event DatabaseAvailableDelegate StationsAvailable;
public string SystemsFile => systems_file;
public string StationsFile => stations_file;
public string StationsFileShort => stations_file_short;
public string Cache {
get => cache_folder;
@@ -28,19 +37,70 @@ namespace NonaBGS.EDDB {
private void Initialise(string cache_folder) {
this.cache_folder = cache_folder;
systems_file = Path.Combine(this.cache_folder, "systems_populated.json");
client.DownloadDataCompleted += Client_DownloadDataCompleted;
stations_file = Path.Combine(this.cache_folder, "stations.json");
stations_file_short = Path.Combine(this.cache_folder, "stations_short.json");
}
private void DownloadFile(string url, string file, DatabaseAvailableDelegate notifier) {
WebClient client = new WebClient();
client.DownloadDataCompleted += Client_DownloadDataCompleted;
client.DownloadFileAsync(new Uri(url), file, notifier);
}
private void TranslateStations() {
if (!HaveStationsFile) {
return;
}
Dictionary<int, List<string>> systems = new Dictionary<int, List<string>>();
using (var str = new StreamReader(StationsFile)) {
using (var reader = new JsonTextReader(str)) {
JArray obj = (JArray)JToken.ReadFrom(reader);
foreach (JObject child in obj.Children<JObject>()) {
int system_id = child.Value<int>("system_id");
string name = child.Value<string>("name");
if (!systems.ContainsKey(system_id)) {
systems.Add(system_id, new List<string>());
}
systems[system_id].Add(name);
}
}
}
JObject short_stations = new JObject();
foreach(int ids in systems.Keys) {
JArray station_names = new JArray();
foreach(string system in systems[ids]) {
station_names.Add(system);
}
short_stations.Add(ids.ToString(), station_names);
}
using (var outstr = new StreamWriter(stations_file_short)) {
using (var jwriter = new JsonTextWriter(outstr)) {
short_stations.WriteTo(jwriter);
}
}
}
public void Download(bool force) {
if (!HaveSystemsFile || force) {
DownloadFile(EDDB_SYSTEMS_ARCHIVE, systems_file, SystemsAvailable);
} else if (HaveSystemsFile) {
SystemsAvailable?.Invoke();
}
if (!HaveStationsFile || force) {
DownloadFile(EDDB_STATIONS_ARCHIVE, stations_file, StationsAvailable);
} else if (HaveStationsFile) {
StationsAvailable?.Invoke();
}
}
public void Download() {
@@ -51,6 +111,14 @@ namespace NonaBGS.EDDB {
get { return systems_file != null && File.Exists(systems_file); }
}
public bool HaveStationsFile {
get { return stations_file != null && File.Exists(stations_file); }
}
public bool HaveStationsFileShort {
get { return stations_file_short != null && File.Exists(stations_file_short); }
}
public PopulatedSystems MakePopulatedSystems() {
if (!HaveSystemsFile) {
throw new InvalidOperationException("no local systems file downloaded");
@@ -59,6 +127,18 @@ namespace NonaBGS.EDDB {
return PopulatedSystems.FromFile(SystemsFile);
}
public Stations MakeStations() {
if (!HaveStationsFile) {
throw new InvalidOperationException("no local systems file downloaded");
}
if (!HaveStationsFileShort) {
TranslateStations();
}
return Stations.FromFile(StationsFileShort);
}
private void Client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) {
DatabaseAvailableDelegate notifier = e.UserState as DatabaseAvailableDelegate;
notifier?.Invoke();

View File

@@ -1,6 +1,6 @@
using System.IO;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json.Linq;
@@ -9,6 +9,7 @@ namespace NonaBGS.EDDB {
private string json_file = null;
private JArray root = null;
private string[] system_names = null;
private Dictionary<string, int> to_id;
public static PopulatedSystems FromFile(string file) {
PopulatedSystems pop = new PopulatedSystems();
@@ -16,10 +17,21 @@ namespace NonaBGS.EDDB {
pop.json_file = file;
pop.root = JArray.Parse(content);
pop.Initialise();
return pop;
}
private void Initialise() {
MakeSystemNames();
to_id = root.ToDictionary(x => x.Value<string>("name"), x => x.Value<int>("id"));
}
public int ToId(string name) {
return to_id.First(x => string.Compare(x.Key, name, true) == 0).Value;
}
private void MakeSystemNames() {
if (root == null) {
throw new InvalidDataException("no JSON loaded");

51
EDDB/Stations.cs Normal file
View File

@@ -0,0 +1,51 @@
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json.Linq;
namespace NonaBGS.EDDB {
public class Stations {
private JObject root = null;
private Dictionary<int, List<string>> by_system_id = null;
public JObject JSON => root;
private Stations() {
}
private void Initialise() {
by_system_id = new Dictionary<int, List<string>>();
foreach (var station in root.Properties()) {
int id = int.Parse(station.Name);
var names = root.Value<JArray>(id.ToString()).Values<string>().ToArray();
if (!by_system_id.ContainsKey(id)) {
by_system_id[id] = new List<string>();
}
by_system_id[id].AddRange(names);
}
}
public static Stations FromFile(string filename) {
string alltext = File.ReadAllText(filename);
Stations stations = new Stations {
root = JObject.Parse(alltext),
};
stations.Initialise();
return stations;
}
public string[] StationNamesBySystemId(int systemid, string filter) {
if (!by_system_id.ContainsKey(systemid)) {
return new string[0];
}
return by_system_id[systemid]
.Where(x => CultureInfo.InvariantCulture.CompareInfo.IndexOf(x, filter, CompareOptions.IgnoreCase) > -1)
.ToArray()
;
}
}
}