Skip to content

Commit

Permalink
v1.1
Browse files Browse the repository at this point in the history
New places ids and smart places grouping
  • Loading branch information
bionicl authored Jul 6, 2018
2 parents 6152387 + b119ca4 commit f3f10a1
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 91 deletions.
2 changes: 2 additions & 0 deletions Arc-app-export-converter/Arc-app-export-converter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
<Compile Include="BurnedCalCalculator.cs" />
<Compile Include="XmlReader.cs" />
<Compile Include="JsonParser.cs" />
<Compile Include="PlacesManager.cs" />
<Compile Include="HelpMethods.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down
95 changes: 95 additions & 0 deletions Arc-app-export-converter/HelpMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;

public static class HelpMethods {

// Distance measure
public static float DistanceTo(XmlTimeline.Coordinates wp1, XmlTimeline.Coordinates wp2, char unit = 'K') {
// Copied from
// https://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates


double rlat1 = Math.PI * wp1.lat / 180;

double rlat2 = Math.PI * wp2.lat / 180;
double theta = wp1.lon - wp2.lon;
double rtheta = Math.PI * theta / 180;
double dist =
Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
Math.Cos(rlat2) * Math.Cos(rtheta);
dist = Math.Acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;

float distF = (float)dist;

switch (unit) {
case 'K': //Kilometers -> default
return distF * 1.609344f;
case 'N': //Nautical Miles
return distF * 0.8684f;
case 'M': //Miles
return distF;
}

return distF;
}
public static float DistanceTo(JsonMoves.Day.Segment.Place.Location jwp1, JsonMoves.Day.Segment.Place.Location jwp2, char unit = 'K') {
XmlTimeline.Coordinates wp1 = new XmlTimeline.Coordinates(jwp1.lat, jwp1.lon);
XmlTimeline.Coordinates wp2 = new XmlTimeline.Coordinates(jwp2.lat, jwp2.lon);
return DistanceTo(wp1, wp2, unit);
}

// Time conversations
public static DateTime ParseIso8601(string iso8601Time) {
return DateTime.Parse(iso8601Time, null, System.Globalization.DateTimeStyles.RoundtripKind);
}
public static string ConvertToIso1601(DateTime time) {
string output = time.ToString(Iso1601Format);
return output.Replace(":", "");
}
public static string Iso1601Format = "yyyyMMddTHHmmsszzz";

// GPX conversion
public static XmlTimeline.Coordinates GetLatLon(string line) {
string lat = "";
string lon = "";
bool captureMode = false;
string capture = "";
foreach (char item in line) {
if (item == '"') {
captureMode = !captureMode;
if (captureMode == false) {
if (lat == "")
lat = capture;
else
lon = capture;
capture = "";
}
} else if (captureMode) {
capture += item;
}
}
return new XmlTimeline.Coordinates(lat, lon);
}
public static string LeaveCenterFromString(string text, string removeLeft, string removeRight) {
string temp = text;
temp = temp.Replace(removeLeft, "");
temp = temp.Replace(removeRight, "");
return temp;
}

// To Json conversion
public static JsonMoves.ActivityGroup ReturnGroup(ActivityType type) {
switch (type) {
case ActivityType.walking:
return JsonMoves.ActivityGroup.walking;
case ActivityType.running:
return JsonMoves.ActivityGroup.running;
case ActivityType.cycling:
return JsonMoves.ActivityGroup.cycling;
default:
return JsonMoves.ActivityGroup.transport;
}
}
}

12 changes: 8 additions & 4 deletions Arc-app-export-converter/JsonParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ public Location(double lat, double lon) {
this.lon = lon;
}
}
public long id = 1234567;
public int id;
public string name;
public string type = "user";
public Location location;

public Place(string name, Location location) {
public Place(string name, Location location, DateTime startTime, DateTime endTime) {
this.name = name;
this.location = location;
this.id = PlacesManager.ReturnPlaceId(this, startTime, endTime);
}

}
Expand Down Expand Up @@ -179,7 +180,10 @@ static void ParseSegments(int i, JsonMoves json, List<XmlReader> xml) {
}
static JsonMoves.Day.Segment SegmentPlace(XmlTimeline.Place item) {
JsonMoves.Day.Segment output = new JsonMoves.Day.Segment(JsonMoves.SegmentType.place, item.startTime.Value, item.endTime.Value);
output.place = new JsonMoves.Day.Segment.Place(item.name, new JsonMoves.Day.Segment.Place.Location(item.position.lat, item.position.lon));
output.place = new JsonMoves.Day.Segment.Place(item.name,
new JsonMoves.Day.Segment.Place.Location(item.position.lat, item.position.lon),
item.startTime.Value,
item.endTime.Value);
return output;
}
static JsonMoves.Day.Segment SegmentMove(XmlTimeline.Activity item) {
Expand Down Expand Up @@ -217,7 +221,7 @@ static void WriteToFile(string json) {
sw.Write(json);
sw.Close();
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write("Json file created!");
Console.WriteLine("Json file created!");
}
}

103 changes: 103 additions & 0 deletions Arc-app-export-converter/PlacesManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

public class Place {
public class PlaceVisit {
public DateTime startTime;
public DateTime endTime;

public PlaceVisit(DateTime startTime, DateTime endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
}
public int id;
public string name;
public JsonMoves.Day.Segment.Place.Location location;
public List<PlaceVisit> visits = new List<PlaceVisit>();

public Place(int id, string name, JsonMoves.Day.Segment.Place.Location location) {
this.id = id;
this.name = name;
this.location = location;
}

public void AddVisit(DateTime startTime, DateTime endTime) {
PlaceVisit tempVisit = new PlaceVisit(startTime, endTime);
foreach (var item in visits) {
if (item.startTime == startTime)
return;
}
visits.Add(tempVisit);
}
}

public class PlacesSave {
public List<Place> places = new List<Place>();
public int currentId;

public PlacesSave(List<Place> places, int currentId) {
this.places = places;
this.currentId = currentId;
}
}

public class PlacesManager {
static bool loaded;
static string placesFileName = "places.json";
static float distanceTolerance = 0.07f;

static List<Place> places = new List<Place>();
static int currentId;

public static bool Loaded {
get {
if (!loaded) {
LoadPlaces();
loaded = true;
}
return true;
}
}

public static int ReturnPlaceId(JsonMoves.Day.Segment.Place place, DateTime startTime, DateTime endTime) {
foreach (var item in places) {
if (CheckIfSamePlace(item, place)) {
item.AddVisit(startTime, endTime);
return item.id;
}
}
Place newPlace = new Place(currentId++, place.name, place.location);
places.Add(newPlace);
newPlace.AddVisit(startTime, endTime);
return newPlace.id;
}
static bool CheckIfSamePlace(Place place, JsonMoves.Day.Segment.Place jsonPlace) {
if (place.name == jsonPlace.name) {
if (HelpMethods.DistanceTo(place.location, jsonPlace.location) <= distanceTolerance)
return true;
}
return false;
}

// Loading files
static void LoadPlaces() {
if (File.Exists(placesFileName)) {
StreamReader sr = new StreamReader(placesFileName);
string line = sr.ReadLine();
sr.Close();
PlacesSave save = JsonConvert.DeserializeObject<PlacesSave>(line);
places = save.places;
currentId = save.currentId;
}
}
public static void SavePlaces() {
StreamWriter sw = new StreamWriter(placesFileName);
sw.Write(JsonConvert.SerializeObject(new PlacesSave(places, currentId)));
sw.Close();
Console.WriteLine("Places database saved to file " + placesFileName);
}

}
5 changes: 5 additions & 0 deletions Arc-app-export-converter/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ class MainClass {

[STAThread]
public static void Main() {
if (PlacesManager.Loaded)
Console.WriteLine("Places initialised");
Console.Write("Input your weight (in kg): ");
weight = Convert.ToInt32(Console.ReadLine());
XmlReader xr = new XmlReader();
xr.LoadFile();
xr.ParseToJson();

// On finish
PlacesManager.SavePlaces();
}
}
93 changes: 7 additions & 86 deletions Arc-app-export-converter/XmlReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public Coordinates(string lat, string lon) {
this.lat = Convert.ToDouble(lat);
this.lon = Convert.ToDouble(lon);
}
public Coordinates(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
public override string ToString() {
return string.Format("Lat: {0} Lon: {1} Ele: {2}", lat, lon, ele);
}
Expand Down Expand Up @@ -141,7 +145,7 @@ public Activity(ActivityType activity, Coordinates[] waypoints) {
}

public void MargeWithNew(Coordinates[] waypoints) {
List<Coordinates> tempMerge = waypoints.ToList();
List<Coordinates> tempMerge = this.waypoints.ToList();
foreach (var item in waypoints) {
tempMerge.Add(item);
}
Expand Down Expand Up @@ -217,7 +221,7 @@ public void LoadFile(string path = "file.gpx") {
SetStartEnd();
SetSummary();

//Display();
Display();
}
void GetPlace(string line, StreamReader sr) {
XmlTimeline.Coordinates location = HelpMethods.GetLatLon(line);
Expand Down Expand Up @@ -335,87 +339,4 @@ public void ParseToJson() {
};
JsonParser.Parse(tempList);
}
}

public static class HelpMethods {

// Copied from
// https://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates

public static float DistanceTo(XmlTimeline.Coordinates wp1, XmlTimeline.Coordinates wp2, char unit = 'K') {
double rlat1 = Math.PI * wp1.lat / 180;
double rlat2 = Math.PI * wp2.lat / 180;
double theta = wp1.lon - wp2.lon;
double rtheta = Math.PI * theta / 180;
double dist =
Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
Math.Cos(rlat2) * Math.Cos(rtheta);
dist = Math.Acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;

float distF = (float)dist;

switch (unit) {
case 'K': //Kilometers -> default
return distF * 1.609344f;
case 'N': //Nautical Miles
return distF * 0.8684f;
case 'M': //Miles
return distF;
}

return distF;
}

public static DateTime ParseIso8601 (string iso8601Time) {
return DateTime.Parse(iso8601Time, null, System.Globalization.DateTimeStyles.RoundtripKind);
}

public static XmlTimeline.Coordinates GetLatLon(string line) {
string lat = "";
string lon = "";
bool captureMode = false;
string capture = "";
foreach (char item in line) {
if (item == '"') {
captureMode = !captureMode;
if (captureMode == false) {
if (lat == "")
lat = capture;
else
lon = capture;
capture = "";
}
} else if (captureMode) {
capture += item;
}
}
return new XmlTimeline.Coordinates(lat, lon);
}
public static string LeaveCenterFromString(string text, string removeLeft, string removeRight) {
string temp = text;
temp = temp.Replace(removeLeft, "");
temp = temp.Replace(removeRight, "");
return temp;
}

public static string ConvertToIso1601(DateTime time) {
string output = time.ToString(Iso1601Format);
return output.Replace(":", "");
}
public static string Iso1601Format = "yyyyMMddTHHmmsszzz";

public static JsonMoves.ActivityGroup ReturnGroup(ActivityType type) {
switch (type) {
case ActivityType.walking:
return JsonMoves.ActivityGroup.walking;
case ActivityType.running:
return JsonMoves.ActivityGroup.running;
case ActivityType.cycling:
return JsonMoves.ActivityGroup.cycling;
default:
return JsonMoves.ActivityGroup.transport;
}
}
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Convert GPX exported from [Arc App][1] to storyline Json format used by abandome
Converter generates all information used by Moves developers:
- Calculates burned calories based on movement speed and body weight
- Creates summary of all movement types
- Sometimes GPX file can contain two different places with the same name - if those are too far from each other, converter will split it into two different places

### Usage:
1. Download [newest release][2]
Expand All @@ -20,7 +21,6 @@ Converter generates all information used by Moves developers:

### TODO:
- Export many files/month file into a single json
- Create place id’s with smart place grouping based on name and coordinates

[1]: https://itunes.apple.com/app/arc-app-location-activity-tracker/id1063151918?mt=8
[2]: https://github.com/bionicl/Arc-app-export-converter/releases/
Expand Down

0 comments on commit f3f10a1

Please sign in to comment.