public Lap(Session session, Track track, double startTime, int lapNumber) { this.session = session; this.track = track; this.startTime = startTime; this.lapNumber = lapNumber; this.points = new List<Point>(); this.duration = 0; this.distance = 0; this.valid = false; this.splits = new double[track.NumSplits()]; this.outLap = lapNumber == 0; if (outLap) { nextGate = track.start; } }
private Track(JToken json) { var jsonGates = (JArray)json["gates"]; var gateList = new List<Gate>(); for (int i = 0; i < jsonGates.Count; i++) { var jsonGate = (JObject)jsonGates[i]; var gate = new Gate((Gate.Type)Enum.Parse(typeof(Gate.Type), (string)jsonGate["gate_type"], true), (int)jsonGate["split_number"], (double)jsonGate["latitude"], (double)jsonGate["longitude"], (double)jsonGate["bearing"]); if (gate.type == Gate.Type.START_FINISH || gate.type == Gate.Type.START) { start = gate; } gateList.Add(gate); } id = (int)json["id"]; name = (string)json["name"]; gates = gateList.ToArray(); }
public void TestCrossing() { var gate = new Gate(Gate.Type.START_FINISH, 1, 37.452602,-122.207069, 32); var a = new Point(37.452414, -122.207193, 14.210000038146973, 32.09501647949219, 0, 0, 1); var b = new Point(37.452523, -122.207107, 14.239999771118164, 32.09501647949219, 0, 0, 2); b.lapDistance = 100.0; b.lapTime = 0.1; var c = new Point(37.45263, -122.207023, 14.15999984741211, 32.09501647949219, 0, 0, 3); var cross = gate.Cross(b, c); Assert.Null(gate.Cross(a, b)); Assert.Null(gate.Cross(c, b)); Assert.True(cross.generated); Assert.AreEqual(37.452593, cross.LatitudeDegrees()); Assert.AreEqual(-122.207052, cross.LongitudeDegrees()); Assert.AreEqual(14.18, cross.speed, 0.01); Assert.AreEqual(31.93, cross.bearing, 0.01); Assert.AreEqual(2.64915, cross.timestamp, 0.00001); Assert.AreEqual(b.lapDistance + b.Distance (cross), cross.lapDistance, 0.01); Assert.AreEqual(0.74915, cross.lapTime, 0.00001); Assert.AreEqual(0.64915, cross.splitTime, 0.00001); }
public void GPS(double latitude, double longitude, double speed, double bearing, double horizontalAccuracy, double verticalAccuracy, double timestamp) { Point point = new Point(latitude, longitude, speed, bearing, horizontalAccuracy, verticalAccuracy, timestamp); if (lastPoint != null) { Point cross = nextGate.Cross(lastPoint, point); if (cross != null) { currentLap.Add(cross); currentLap.splits[currentSplit] = cross.splitTime; switch (nextGate.type) { case Gate.Type.START_FINISH: case Gate.Type.FINISH: if (currentLap.points [0].generated) { currentLap.valid = true; if (bestLap == null || currentLap.duration < bestLap.duration) { bestLap = currentLap; } } goto case Gate.Type.START; case Gate.Type.START: lapNumber++; currentLap = new Lap(session, track, cross.timestamp, lapNumber); lastPoint = cross; lastPoint = new Point(cross.LatitudeDegrees(), cross.LongitudeDegrees(), cross.speed, cross.bearing, cross.hAccuracy, cross.vAccuracy, cross.timestamp); lastPoint.lapDistance = 0; lastPoint.lapTime = 0; lastPoint.generated = true; currentLap.Add(lastPoint); session.laps.Add(currentLap); gap = 0; for (int i = 0; i < splitGaps.Length; i++) { splitGaps[i] = 0.0; } bestIndex = 0; currentSplit = 0; break; case Gate.Type.SPLIT: if (bestLap != null) { splitGaps [currentSplit] = currentLap.splits [currentSplit] - bestLap.splits [currentSplit]; } currentSplit++; break; } if (bestLap != null && bestIndex < bestLap.points.Count - 1) { while (bestIndex < bestLap.points.Count - 1) { Point refPoint = bestLap.points[bestIndex + 1]; if (refPoint.lapDistance > currentLap.distance) { break; } bestIndex++; } Point lastRefPoint = bestLap.points[bestIndex]; double distanceToLastRefPoint = currentLap.distance - lastRefPoint.lapDistance; if (distanceToLastRefPoint > 0) { double sinceLastRefPoint = distanceToLastRefPoint / point.speed; gap = point.lapTime - sinceLastRefPoint - lastRefPoint.lapTime; splitGaps[currentSplit] = point.splitTime - sinceLastRefPoint - lastRefPoint.splitTime; } } splitStartTime = cross.timestamp; nextGate = track.gates[currentSplit]; } point.lapDistance = lastPoint.lapDistance + lastPoint.Distance(point); point.SetLapTime(currentLap.startTime, splitStartTime); } currentLap.Add(point); lastPoint = point; }
public void GPS(double latitude, double longitude, double speed, double bearing, double horizontalAccuracy, double verticalAccuracy, double timestamp) { Point point = new Point(latitude, longitude, speed, bearing, horizontalAccuracy, verticalAccuracy, timestamp); if (lastPoint != null) { Point cross = nextGate.Cross(lastPoint, point); if (cross != null) { currentLap.Add(cross); currentLap.splits[currentSplit] = cross.splitTime; switch(nextGate.type) { case Gate.Type.START_FINISH: case Gate.Type.FINISH: if (currentLap.points [0].generated) { currentLap.valid = true; if (bestLap == null || currentLap.duration < bestLap.duration) { bestLap = currentLap; } } goto case Gate.Type.START; case Gate.Type.START: lapNumber++; currentLap = new Lap(session, track, cross.timestamp, lapNumber); lastPoint = cross; lastPoint = new Point(cross.LatitudeDegrees(), cross.LongitudeDegrees(), cross.speed, cross.bearing, cross.hAccuracy, cross.vAccuracy, cross.timestamp); lastPoint.lapDistance = 0; lastPoint.lapTime = 0; lastPoint.generated = true; currentLap.Add(lastPoint); session.laps.Add(currentLap); gap = 0; for ( int i = 0; i < splitGaps.Length;i++ ) { splitGaps[i] = 0.0; } bestIndex = 0; currentSplit = 0; break; case Gate.Type.SPLIT: if (bestLap != null) { splitGaps [currentSplit] = currentLap.splits [currentSplit] - bestLap.splits [currentSplit]; } currentSplit++; break; } splitStartTime = cross.timestamp; nextGate = track.gates[currentSplit]; } if (bestLap != null && bestIndex < bestLap.points.Count) { while(bestIndex < bestLap.points.Count) { var refPoint = bestLap.points[bestIndex]; if (refPoint.lapDistance > currentLap.distance) { var lastRefPoint = bestLap.points[bestIndex - 1]; var distanceToLastRefPoint = currentLap.distance - lastRefPoint.lapDistance; if (distanceToLastRefPoint > 0) { var sinceLastRefPoint = distanceToLastRefPoint / point.speed; gap = point.lapTime - sinceLastRefPoint - lastRefPoint.lapTime; splitGaps[currentSplit] = point.splitTime - sinceLastRefPoint - lastRefPoint.splitTime; } break; } bestIndex++; } } point.lapDistance = lastPoint.lapDistance + lastPoint.Distance(point); point.SetLapTime(currentLap.startTime, splitStartTime); } currentLap.Add(point); lastPoint = point; }
public void Start(Track track) { if (session == null) { this.track = track; TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1); int secondsSinceEpoch = (int)t.TotalSeconds; session = new Session(track, secondsSinceEpoch); currentLap = new Lap(session, track, session.startTime, 0); session.laps.Add(currentLap); nextGate = track.start; lastPoint = null; lapNumber = 0; splitStartTime = session.startTime; if (bestLap != null) { bestIndex = 0; } splitGaps = new double[track.NumSplits()]; } }