diff --git a/Program.cs b/Program.cs
index ddf86c7..2b6e3af 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,15 +1,184 @@
using System;
using System.Collections.Generic;
-using System.Linq;
+using System.IO;
using System.Text;
using System.Threading.Tasks;
+using System.Json;
+using MKCoolsoft.GPXLib;
+
namespace starlineonline2gpx
{
+ class Date
+ {
+ private static DateTime UnixEpoch =
+ new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ public static TimeZoneInfo TimeZone = TimeZoneInfo.Local;
+
+ public static long minSeconds = long.MaxValue;
+ public static long maxSeconds = long.MinValue;
+
+ public static DateTime DateTimeFromUnixTimestampSeconds(long seconds)
+ {
+ if (seconds < minSeconds) minSeconds = seconds;
+ if (seconds > maxSeconds) maxSeconds = seconds;
+ return UnixEpoch.AddSeconds(seconds);
+ }
+ }
+
class Program
{
+ static decimal Minlat = decimal.MaxValue;
+ static decimal Maxlat = decimal.MinValue;
+ static decimal Minlon = decimal.MaxValue;
+ static decimal Maxlon = decimal.MinValue;
+
static void Main(string[] args)
{
+ if (args.Length > 0 && File.Exists(args[0]))
+ {
+ var path = args[0];
+ using (StreamReader sr = new StreamReader(path))
+ {
+ var json = JsonValue.Parse(sr.ReadToEnd());
+
+ GPXLib gpx = new GPXLib();
+
+ var meta = json["meta"];
+ var data = json["data"];
+ var trackNum = 0;
+ var waypointNum = 0;
+ foreach(JsonValue elem in data)
+ {
+ string type = elem["type"];
+ switch(type)
+ {
+ case "TZ":
+ ParseTimezone(gpx, elem);
+ break;
+ case "TRACK":
+ ParseTrack(gpx, elem, ++trackNum);
+ break;
+ case "NO_SIGNAL":
+ ParseNoSignal(gpx, elem);
+ break;
+ case "WAYPOINT":
+ ParseWaypoint(gpx, elem, ++waypointNum);
+ break;
+ case "STOP":
+ ParseStop(gpx, elem);
+ break;
+ default:
+ throw new NotImplementedException();
+
+ }
+ }
+
+
+ gpx.Metadata.Name = "Starline GPX Track";
+
+ var startDate = Date.DateTimeFromUnixTimestampSeconds(Date.minSeconds);
+ var endDate = Date.DateTimeFromUnixTimestampSeconds(Date.maxSeconds);
+ gpx.Metadata.Desc = String.Format("Track from {0} to {1}", startDate, endDate);
+
+ gpx.Creator = "starlineonline2gpx converter";
+
+ gpx.Metadata.Bounds.Maxlat = Maxlat;
+ gpx.Metadata.Bounds.Minlat = Minlat;
+ gpx.Metadata.Bounds.Maxlon = Maxlon;
+ gpx.Metadata.Bounds.Minlon = Minlon;
+ gpx.Metadata.Time = startDate;
+ gpx.Metadata.TimeSpecified = true;
+
+ var author = new Person();
+ author.Link.Href = @"https://github.com/DJm00n/starlineonline2gpx";
+ author.Email.Id = @"dimitriy.ryazantcev";
+ author.Email.Domain = "gmail.com";
+ author.Name = @"Dimitriy Ryazantcev";
+
+ gpx.Metadata.Author = author;
+
+
+ gpx.SaveToFile(Path.ChangeExtension(path, "gpx"));
+ }
+ }
+ }
+
+ private static void TrackMinMax(decimal lat, decimal lon)
+ {
+ if (lat < Minlat) Minlat = lat;
+ if (lat > Maxlat) Maxlat = lat;
+
+ if (lon < Minlon) Minlon = lon;
+ if (lon > Maxlon) Maxlon = lon;
+ }
+
+ private static void ParseNoSignal(GPXLib gpx, JsonValue elem)
+ {
+ //throw new NotImplementedException();
+ }
+
+ private static void ParseStop(GPXLib gpx, JsonValue elem)
+ {
+ //throw new NotImplementedException();
+ }
+
+ private static void ParseWaypoint(GPXLib gpx, JsonValue elem, int waypointNum)
+ {
+ Wpt waypoint = new Wpt
+ {
+ Name = String.Format("Waypoint {0}", waypointNum),
+ Lat = elem["x"],
+ Lon = elem["y"],
+ Ele = elem["z"],
+ EleSpecified = elem.ContainsKey("z") && elem["z"] != 0,
+ Sat = Convert.ToString((int)elem["sat_qty"]),
+ Time = Date.DateTimeFromUnixTimestampSeconds(elem["t"]),
+ TimeSpecified = elem.ContainsKey("t")
+ };
+
+ gpx.WptList.Add(waypoint);
+ TrackMinMax(waypoint.Lat, waypoint.Lon);
+ }
+
+ private static void ParseTimezone(GPXLib gpx, JsonValue elem)
+ {
+ string displayName = "Local Time Zone";
+ string standardName = "Local Time";
+ TimeSpan offset = TimeSpan.FromSeconds(elem["time_shift"]);
+ TimeZoneInfo local = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, displayName, standardName);
+ Date.TimeZone = local;
+ //TODO save this timezone somewhere in gpx file
+ }
+
+ private static void ParseTrack(GPXLib gpx, JsonValue elem, int trackNum)
+ {
+ Trkseg segment = new Trkseg();
+
+ foreach (JsonValue node in elem["nodes"])
+ {
+ Wpt wpt = new Wpt
+ {
+ Lat = node["x"],
+ Lon = node["y"],
+ Ele = node["z"],
+ EleSpecified = node.ContainsKey("z") && node["z"] != 0,
+ Sat = Convert.ToString((int)node["sat_qty"]),
+ Time = Date.DateTimeFromUnixTimestampSeconds(node["t"]),
+ TimeSpecified = node.ContainsKey("t")
+ };
+
+ segment.TrkptList.Add(wpt);
+ TrackMinMax(wpt.Lat, wpt.Lon);
+ }
+
+ Trk track = new Trk(String.Format("Track {0}", trackNum))
+ {
+ Number = trackNum.ToString()
+ };
+ track.TrksegList.Add(segment);
+
+ gpx.TrkList.Add(track);
}
}
}
diff --git a/packages.config b/packages.config
new file mode 100644
index 0000000..ee3219c
--- /dev/null
+++ b/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/starlineonline2gpx.csproj b/starlineonline2gpx.csproj
index 94e8a9b..d568a6f 100644
--- a/starlineonline2gpx.csproj
+++ b/starlineonline2gpx.csproj
@@ -33,8 +33,16 @@
4
+
+ packages\MKCoolsoft.GPXLib.1.0.2\lib\MKCoolsoft.GPXLib.dll
+ True
+
+
+ packages\System.Json.4.4.0\lib\netstandard1.0\System.Json.dll
+ True
+
@@ -48,6 +56,7 @@
+