/// <summary>
        /// Get similarity
        /// </summary>
        /// <param name="circle"></param>
        /// <param name="treshold"></param>
        /// <returns></returns>
        public Double GetSimilarity(GeoCircle circle, double treshold = 0.02)
        {
            //variables
            Double match = 0;
            Double max = Math.Min(circle.Positions.Count, this.Positions.Count);
            var distance = 0.0;
            var i = 0;
            var p = 0;

            //CHECK: LENGTH
            var length = Math.Abs(circle.Length - this.Length);
            //another distance
            if (length > 0.05)
            {
                return 0;
            }

            //CHECK: START
            var startGeo = new Geo(circle.Positions[0]);
            //all positions
            for (i = 0; i < this.Positions.Count; i++)
            {
                //distance
                distance = startGeo.distanceTo(this.Positions[i]);
                //treshold
                if (distance <= treshold)
                {
                    break;
                }
            }
            //start not found
            if (i == this.Positions.Count)
            {
                return 0;
            }

            //CHECK: PROCESS ALL PATH
            while (p < max)
            {
                //nearest
                int a;
                var nearest = Geo.GetNearest(circle.Positions[p], this.Positions, out a, i);
                i = a;
                //match
                match += nearest < treshold ? 1 : 0;
                //processed
                p++;
            }
            //return
            return (match / max) * 100;
        }
        /// <summary>
        /// Speed btween two points
        /// </summary>
        /// <param name="positions"></param>
        /// <returns>Speed</returns>
        public static double SpeedTo(List<GeoPosition> positions, double accuracy = 20)
        {
            //distance init
            var km = 0.0;
            //time init
            var hours = 0.0;
            //geo
            Geo geo;

            for (var i = 0; i < positions.Count - 2; i++)
            {
                //save
                var first = positions[i];
                var second = positions[i + 1];
                //geo
                geo = new Geo(first);
                //calculate data
                TimeSpan sub = second.Date.Subtract(first.Date);
                hours += sub.TotalHours;
                km += geo.distanceTo(second);
            }

            if (hours == 0)
            {
                return 0;
            }
            //calculate
            Double multiplier = 1 / hours;
            Double kmh = km * multiplier;
            //return
            return kmh;
        }
        /// <summary>
        /// Get circle
        /// </summary>
        /// <param name="positions"></param>
        /// <returns></returns>
        public static GeoCircle GetCircle(List<GeoPosition> positions)
        {
            var startGeo = new Geo(positions[0]);
            var returning = false;
            var distance = 0.0;
            var treshold = 0.02;

            //data
            double x = 0;
            double y = 0;
            double z = 0;
            double latitude = 0.0;
            double longitude = 0.0;

            //circle
            GeoCircle circle = new GeoCircle();
            circle.Positions = new List<GeoPosition>();
            circle.Length = 0;
            circle.Center = null;

            //get circle
            for (var i = 0; i < positions.Count; i++)
            {
                var geo = new Geo(positions[i]);

                //add
                circle.Positions.Add(positions[i]);
                //length
                circle.Length += (i < positions.Count - 1) ? geo.distanceTo(positions[i + 1]) : 0;

                //center
                latitude = positions[i].Latitude * Math.PI / 180;
                longitude = positions[i].Longitude * Math.PI / 180;
                //center - calculates
                x += Math.Cos(latitude) * Math.Cos(longitude);
                y += Math.Cos(latitude) * Math.Sin(longitude);
                z += Math.Sin(latitude);

                //distance
                distance = startGeo.distanceTo(positions[i]);
                //returning
                returning = returning || distance > 0.1;
                //check lap
                if (returning && distance <= treshold)
                {
                    break;
                }
            }

            //center
            if (circle.Positions.Count > 1)
            {
                x = x / circle.Positions.Count;
                y = y / circle.Positions.Count;
                z = z / circle.Positions.Count;

                var centralLongitude = Math.Atan2(y, x);
                var centralSquareRoot = Math.Sqrt(x * x + y * y);
                var centralLatitude = Math.Atan2(z, centralSquareRoot);

                circle.Center = new GeoPosition(centralLatitude * 180 / Math.PI, centralLongitude * 180 / Math.PI, 0);
            }
            else
            {
                circle.Center = circle.Positions[0];
            }

            return circle;
        }
 /// <summary>
 /// Get nearest point
 /// </summary>
 /// <param name="point"></param>
 /// <param name="positions"></param>
 /// <param name="current"></param>
 /// <param name="start"></param>
 /// <returns></returns>
 public static Double GetNearest(GeoPosition point, List<GeoPosition> positions, out int current, int start = 0)
 {
     Double distance = Double.MaxValue;
     int max = positions.Count;
     Geo geo = new Geo(point);
     for (var i = start; i < max; i++)
     {
         var d = geo.distanceTo(positions[i]);
         //next distance is bigger
         if (d > distance)
         {
             current = i - 1;
             return distance;
         }
         //distance is smaller
         if (d < distance)
         {
             distance = d;
         }
         //reset
         if (start > 0 && i == positions.Count - 1)
         {
             start = 0;
             i = 0;
             max = start;
         }
     }
     //not found
     current = 0;
     return distance;
 }