Exemple #1
0
        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));