public void Round_Coordinates_By_Meters() { // ARRANGE GeoCoordinateExtended source = geoFile.Routes[0].Points[0]; GeoCoordinateExtended compareTo = source.Clone(); Double roundingMeters = 2D; // ACT compareTo.Round(roundingMeters); // Round second coordinate to 2 meter grid point Double distance = compareTo.GetDistanceTo(source); // Calculate the distance in meters Double hypotenuse = Math.Sqrt(Math.Pow(roundingMeters, 2) + Math.Pow(roundingMeters, 2)); // ASSERT hypotenuse.Should().BeGreaterThan(distance); // Should be smaller than the hypotenuse }
/// <summary> /// Remove not moving points and time from the list of coordinates /// </summary> /// <param name="points">The list of points to be cleaned of not moving time</param> /// <returns>The list of points with the not moving time removed</returns> public static List <GeoCoordinateExtended> RemoveNotMoving(this List <GeoCoordinateExtended> points) { List <GeoCoordinateExtended> reference = points.Clone().CalculateSpeeds(); // Make a copy of the points first to break the reference and re-calculate the speeds List <KeyValuePair <TimeSpan, GeoCoordinateExtended> > timeDiffArray = new List <KeyValuePair <TimeSpan, GeoCoordinateExtended> >(); // New list of points with the timedifference between them as the key List <GeoCoordinateExtended> cleaned = new List <GeoCoordinateExtended>() { reference[0] }; // Create the new clean array, the first point always has no speed so always add this to the cleaned array as a starting point // Loop all points in the track and only count those that had speed (movement) between the two points var coordId = 1; // Start from the second point as the first will always have no speed (from another point) while (coordId <= reference.Count - 1) { if (reference[coordId].Speed != 0) { TimeSpan timeDiff = reference[coordId].Time - reference[coordId - 1].Time; // Calculate the time to the previous coordinate timeDiffArray.Add(new KeyValuePair <TimeSpan, GeoCoordinateExtended>(timeDiff, reference[coordId])); // Add the coordinate that shows movement with the time difference to the last coordinate } coordId++; } // Loop the array with the none moving time stripped out and re-calculate the coordinate times based on the time differences DateTime pointInTime = cleaned[0].Time; // Take the start time of the origional track to be the new start time for (var refId = 0; refId < timeDiffArray.Count; refId++) { GeoCoordinateExtended manipulated = timeDiffArray[refId].Value; // Create a reference to the point on the track to have the time manipluated pointInTime += timeDiffArray[refId].Key; // Add the time difference to the rolling point in time manipulated.Time = pointInTime; // Set the new time to the point so the new point is still the same difference in time between the GPS pings to the last point that moved cleaned.Add(manipulated); // Add the time manipulated point to the cleaned array } // Re-calculate the speeds on the new points cleaned.CalculateSpeeds(); // Return the cleaned list of points return(cleaned); }
public static Double LatitudeDistance = EarthRadius / 360.0D; // What is 1 degree of latitude public static List <GeoCoordinateExtended> InfillPositions(this List <GeoCoordinateExtended> points) { GeoCoordinateExtended lastValidPosition = null; points.ForEach(pt => { // Not a bad coordinate? if (!pt.BadCoordinate) { lastValidPosition = pt; // Assign this as the last known good position } else if (pt.BadCoordinate && lastValidPosition != null) { // Infill the position from the last known good pt.Latitude = lastValidPosition.Latitude; pt.Longitude = lastValidPosition.Longitude; pt.Altitude = lastValidPosition.Altitude; pt.BadCoordinate = false; lastValidPosition = pt; // Reassign this as the last known good } }); return(points); }
=> JsonConvert.DeserializeObject <List <GeoCoordinateExtended> >(JsonConvert.SerializeObject(points)); // Serialise and then deserialise the object to break the references to new objects public static GeoCoordinateExtended Clone(this GeoCoordinateExtended coord) => JsonConvert.DeserializeObject <GeoCoordinateExtended>(JsonConvert.SerializeObject(coord));