Exemple #1
0
        public void AddPin(double latitude, double longitude)
        {
            trail.Locations.Add(new TrailLocationDto {
                Order     = count++,
                Latitude  = latitude,
                Longitude = longitude
            });

            ILatLng thisLatLng = new LatLng(latitude, longitude);

            if (lastLatLng != null)
            {
                CreatePolyline(new MapPolyline {
                    Positions = new List <ILatLng>()
                    {
                        lastLatLng, thisLatLng
                    },
                    StrokeColor = Color.Red,
                    StrokeWidth = 10,
                });
            }
            else
            {
                DisplayText = "Now tap to set the next point";
            }

            lastLatLng = thisLatLng;
        }
Exemple #2
0
        public static double GetDistanceM(this ILatLng latLng, ILatLng other)
        {
            var d1   = latLng.Latitude * (Math.PI / 180.0);
            var num1 = latLng.Longitude * (Math.PI / 180.0);
            var d2   = other.Latitude * (Math.PI / 180.0);
            var num2 = other.Longitude * (Math.PI / 180.0) - num1;
            var d3   = Math.Pow(Math.Sin((d2 - d1) / 2.0), 2.0) + Math.Cos(d1) * Math.Cos(d2) * Math.Pow(Math.Sin(num2 / 2.0), 2.0);

            return(6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3))));
        }
Exemple #3
0
        private bool IsClosestPoint(RideLocationDto nextLocation, ILatLng trailLocation, double lastDistance)
        {
            if (nextLocation == null)
            {
                return(true);
            }

            double nextDistance = nextLocation.GetDistanceM(trailLocation);

            return(lastDistance < nextDistance);
        }
Exemple #4
0
        private bool IsWithinThresholdAndClosest(ILatLng trailLocation, RideLocationDto location, int threshold)
        {
            double distance = trailLocation.GetDistanceM(location);

            bool isWithinThreshold = distance <= threshold;

            if (!isWithinThreshold)
            {
                return(false);
            }

            int locationIdx  = ride.Locations.IndexOf(location);
            var nextLocation = ride.Locations
                               .Where(i => i.Timestamp > location.Timestamp)
                               .FirstOrDefault();

            return(IsClosestPoint(nextLocation, trailLocation, distance));
        }
Exemple #5
0
        public void AddPin(double latitude, double longitude)
        {
            segment.Locations.Add(new SegmentLocationDto {
                Order     = count++,
                Latitude  = latitude,
                Longitude = longitude
            });

            ILatLng thisLatLng = new LatLng(latitude, longitude);

            if (lastLatLng != null)
            {
                MapViewModel.AddPolyLine(new[] { lastLatLng, thisLatLng }, Color.Red);
            }
            else
            {
                DisplayText = "Now tap to set the next point";
            }

            lastLatLng = thisLatLng;
        }
Exemple #6
0
 public static bool HasPointOnLine(this IList <ILatLng> path, ILatLng point, int toleranceInMetres = 25)
 {
     return(path.Any(i => i.GetDistanceM(point) <= toleranceInMetres));
 }
Exemple #7
0
        protected void GoToLocation(ILatLng midpoint, Distance distance)
        {
            var position = new Position(midpoint.Latitude, midpoint.Longitude);

            map.MoveToRegion(MapSpan.FromCenterAndRadius(position, distance));
        }
Exemple #8
0
        public GeodeticLine CalculateOrthodromicLine(ILatLng point1, ILatLng point2)
        {
            if (Math.Abs(point1.Latitude - point2.Latitude) < double.Epsilon && Math.Abs(point1.Longitude - point2.Longitude) < double.Epsilon)
                return null;

            var lon1 = point1.Longitude.ToRadians();
            var lat1 = point1.Latitude.ToRadians();
            var lon2 = point2.Longitude.ToRadians();
            var lat2 = point2.Latitude.ToRadians();
            /*
             * Solution of the geodetic inverse problem after T.Vincenty.
             * Modified Rainsford's method with Helmert's elliptical terms.
             * Effective in any azimuth and at any distance short of antipodal.
             *
             * Latitudes and longitudes in radians positive North and East.
             * Forward azimuths at both points returned in radians from North.
             *
             * Programmed for CDC-6600 by LCDR L.Pfeifer NGS ROCKVILLE MD 18FEB75
             * Modified for IBM SYSTEM 360 by John G.Gergen NGS ROCKVILLE MD 7507
             * Ported from Fortran to Java by Martin Desruisseaux.
             *
             * Source: ftp://ftp.ngs.noaa.gov/pub/pcsoft/for_inv.3d/source/inverse.for
             *         subroutine INVER1
             */
            const int maxIterations = 100;
            const double eps = 0.5E-13;
            double R = 1 - Flattening;

            double tu1 = R * Math.Sin(lat1) / Math.Cos(lat1);
            double tu2 = R * Math.Sin(lat2) / Math.Cos(lat2);
            double cu1 = 1 / Math.Sqrt(tu1 * tu1 + 1);
            double cu2 = 1 / Math.Sqrt(tu2 * tu2 + 1);
            double su1 = cu1 * tu1;
            double s = cu1 * cu2;
            double baz = s * tu2;
            double faz = baz * tu1;
            double x = lon2 - lon1;
            for (int i = 0; i < maxIterations; i++)
            {
                double sx = Math.Sin(x);
                double cx = Math.Cos(x);
                tu1 = cu2 * sx;
                tu2 = baz - su1 * cu2 * cx;
                double sy = Math.Sqrt(Math.Pow(tu1, 2) + Math.Pow(tu2, 2));
                double cy = s * cx + faz;
                double y = Math.Atan2(sy, cy);
                double SA = s * sx / sy;
                double c2a = 1 - SA * SA;
                double cz = faz + faz;
                if (c2a > 0)
                {
                    cz = -cz / c2a + cy;
                }
                double e = cz * cz * 2 - 1;
                double c = ((-3 * c2a + 4) * Flattening + 4) * c2a * Flattening / 16;
                double d = x;
                x = ((e * cy * c + cz) * sy * c + y) * SA;
                x = (1 - c) * x * Flattening + lon2 - lon1;

                if (Math.Abs(d - x) <= eps)
                {
                    x = Math.Sqrt((1 / (R * R) - 1) * c2a + 1) + 1;
                    x = (x - 2) / x;
                    c = 1 - x;
                    c = (x * x / 4 + 1) / c;
                    d = (0.375 * x * x - 1) * x;
                    x = e * cy;
                    s = 1 - 2 * e;
                    s = ((((sy * sy * 4 - 3) * s * cz * d / 6 - x) * d / 4 + cz) * sy * d + y) * c * R * EquatorialAxis;
                    // 'faz' and 'baz' are forward azimuths at both points.
                    faz = Math.Atan2(tu1, tu2);
                    baz = Math.Atan2(cu1 * sx, baz * cx - su1 * cu2) + Math.PI;
                    return new GeodeticLine(new Coordinate(point1.Latitude, point1.Longitude), new Coordinate(point2.Latitude, point2.Longitude), s, faz.ToDegrees(), baz.ToDegrees());
                }
            }
            // No convergence. It may be because coordinate points
            // are equals or because they are at antipodes.
            const double leps = 1E-10;
            if (Math.Abs(lon1 - lon2) <= leps && Math.Abs(lat1 - lat2) <= leps)
            {
                // Coordinate points are equals
                return null;
            }
            if (Math.Abs(lat1) <= leps && Math.Abs(lat2) <= leps)
            {
                // Points are on the equator.
                return new GeodeticLine(new Coordinate(point1.Latitude, point1.Longitude), new Coordinate(point2.Latitude, point2.Longitude), Math.Abs(lon1 - lon2) * EquatorialAxis, faz.ToDegrees(), baz.ToDegrees());
            }
            // Other cases: no solution for this algorithm.
            throw new ArithmeticException();
        }
Exemple #9
0
        public GeodeticLine CalculateOrthodromicLine(ILatLng point, double heading, double distance)
        {
            var lat1 = point.Latitude.ToRadians();
            var lon1 = point.Longitude.ToRadians();
            var faz = heading.ToRadians();

            // glat1 initial geodetic latitude in radians N positive
            // glon1 initial geodetic longitude in radians E positive
            // faz forward azimuth in radians
            // s distance in units of a (=nm)

            var EPS = 0.00000000005;
            //var r, tu, sf, cf, b, cu, su, sa, c2a, x, c, d, y, sy, cy, cz, e
            //            var glat2, glon2, baz, f

            if ((Math.Abs(Math.Cos(lat1)) < EPS) && !(Math.Abs(Math.Sin(faz)) < EPS))
            {
                //alert("Only N-S courses are meaningful, starting at a pole!")
            }

            var r = 1 - this.Flattening;
            var tu = r*Math.Tan(lat1);
            var sf = Math.Sin(faz);
            var cf = Math.Cos(faz);
            double b;
            if (cf == 0)
            {
                b = 0d;
            }
            else
            {
                b = 2*Math.Atan2(tu, cf);
            }
            var cu = 1/Math.Sqrt(1 + tu*tu);
            var su = tu*cu;
            var sa = cu*sf;
            var c2a = 1 - sa*sa;
            var x = 1 + Math.Sqrt(1 + c2a*(1/(r*r) - 1));
            x = (x - 2)/x;
            var c = 1 - x;
            c = (x*x/4 + 1)/c;
            var d = (0.375*x*x - 1)*x;
            tu = distance / (r * EquatorialAxis * c);
            var y = tu;
            c = y + 1;

            double sy = 0, cy =0, cz = 0, e = 0;

            while (Math.Abs(y - c) > EPS)
            {
                sy = Math.Sin(y);
                cy = Math.Cos(y);
                cz = Math.Cos(b + y);
                e = 2*cz*cz - 1;
                c = y;
                x = e*cy;
                y = e + e - 1;
                y = (((sy*sy*4 - 3)*y*cz*d/6 + x)*
                     d/4 - cz)*sy*d + tu;
            }

            b = cu*cy*cf - su*sy;
            c = r*Math.Sqrt(sa*sa + b*b);
            d = su*cy + cu*sy*cf;
            var glat2 = modlat(Math.Atan2(d, c));
            c = cu*cy - su*sy*cf;
            x = Math.Atan2(sy*sf, c);
            c = ((-3 * c2a + 4) * Flattening + 4) * c2a * Flattening / 16;
            d = ((e*cy*c + cz)*sy*c + y)*sa;
            var glon2 = modlon(lon1 + x - (1 - c)*d*Flattening); // fix date line problems
            var baz = modcrs(Math.Atan2(sa, b) + Math.PI);

            return new GeodeticLine(new Coordinate(point.Latitude, point.Longitude), new Coordinate(glat2.ToDegrees(), glon2.ToDegrees()),
                                    distance, heading, baz);
        }
Exemple #10
0
        public GeodeticLine CalculateLoxodromicLine(ILatLng point1, ILatLng point2)
        {
            var lat1 = point1.Latitude;
            var lon1 = point1.Longitude;
            var lat2 = point2.Latitude;
            var lon2 = point2.Longitude;

            if (Math.Abs(lat1 - lat2) < double.Epsilon && Math.Abs(lon1 - lon2) < double.Epsilon)
                return null;

            double distance;
            var latDeltaRad = (lat2 - lat1).ToRadians();
            var meridionalDistance = CalculateMeridionalDistance(lat2) - CalculateMeridionalDistance(lat1);
            var course = LoxodromicLineCourse(lat1, lon1, lat2, lon2);

            if (Math.Abs(latDeltaRad) < 0.0008)
            {
                // near parallel sailing

                var lonDelta = lon2 - lon1;
                if (lonDelta > 180)
                    lonDelta = lonDelta - 360;
                if (lonDelta < -180)
                    lonDelta = lonDelta + 360;
                var lonDeltaRad = lonDelta.ToRadians();

                var midLatRad = (0.5 * (lat1 + lat2)).ToRadians();
                // expand merid_dist/dmp about lat_mid_rad to order e2*dlat_rad^2
                var e2 = Math.Pow(Eccentricity, 2);
                var ratio = Math.Cos(midLatRad) /
                        Math.Sqrt(1 - e2 * Math.Pow(Math.Sin(midLatRad), 2)) *
                    (1.0 + (e2 * Math.Cos(2 * midLatRad) / 8 -
                        (1 + 2 * Math.Pow(Math.Tan(midLatRad), 2)) / 24 -
                        e2 / 12) * latDeltaRad * latDeltaRad);

                distance = Math.Sqrt(Math.Pow(meridionalDistance, 2) + Math.Pow(EquatorialAxis * ratio * lonDeltaRad, 2));
            }
            else
            {
                distance = Math.Abs(meridionalDistance / Math.Cos(course.ToRadians()));
            }
            return new GeodeticLine(new Coordinate(lat1, lon1), new Coordinate(lat2, lon2), distance, course, course > 180 ? course - 180 : course + 180);
        }