Exemplo n.º 1
0
        public bool TryGetDistanceBetweenTwoPointsOnPath(GeoPoint p1, GeoPoint p2, out Double distance)
        {
            bool success = false;

            distance = 0;

            /** get the line each point lies on */
            GeoLine l1, l2;
            Double  d1, d2;

            if (TryGetLineForPoint(p1, .1, out l1) && TryGetLineForPoint(p2, .1, out l2))
            {
                if (l1.Equals(l2))
                {
                    distance = EarthGeo.GetDistance(p1, p2);
                    success  = true;
                }
                else if (TryGetDistanceFromEnd(p1, out d1) && TryGetDistanceFromEnd(p2, out d2))
                {
                    if (d1 > d2)
                    {
                        distance = GetDistanceForTwoOrderedPoints(l1, p1, l2, p2);
                    }
                    else
                    {
                        distance = GetDistanceForTwoOrderedPoints(l2, p2, l1, p1);
                    }
                    success = true;
                }
            }
            return(success);
        }
Exemplo n.º 2
0
        public bool TryGetPointAtDistanceFromEnd(Double distance, out GeoPoint point)
        {
            point = null;

            Double      totalLength = 0;
            GeoLineList list        = new GeoLineList(this);

            list.Reverse();

            for (int index = 0; point == null && index < list.Count; index++)
            {
                GeoLine line      = list[index];
                Double  newLength = totalLength + line.Length;
                if (newLength > distance)
                {
                    Double segLength = distance - totalLength;
                    point = EarthGeo.GetPoint(line.P2 as GeoPoint, Angle.Reverse(line.Bearing), segLength);
                }
                else
                {
                    totalLength = newLength;
                }
            }
            return(point != null);
        }
Exemplo n.º 3
0
        public void Move(Double bearing, Double distance)
        {
            GeoPoint np = EarthGeo.GetPoint(this, bearing, distance);

            Latitude  = np.Latitude;
            Longitude = np.Longitude;
        }
Exemplo n.º 4
0
        Double GetDistanceForTwoOrderedPoints(GeoLine l1, GeoPoint p1, GeoLine l2, GeoPoint p2)
        {
            Double distance = 0;

            if (l1.Equals(l2))
            {
                distance = EarthGeo.GetDistance(p1, p2);
            }
            else
            {
                int index;

                for (index = 0; index < Count && this[index].Equals(l1) == false; index++)
                {
                    ;
                }
                if (index < Count)
                {
                    distance += EarthGeo.GetDistance(p1 as GeoPoint, l1.P2 as GeoPoint);

                    for (; this[index].Equals(l2) == false; index++)
                    {
                        distance += this[index].Length;
                    }
                    if (index < Count)
                    {
                        distance += EarthGeo.GetDistance(p2 as GeoPoint, l2.P1 as GeoPoint);
                    }
                }
            }

            return(distance);
        }
Exemplo n.º 5
0
        public Double ClosestDistanceFrom(GeoPoint from)
        {
            GeoPoint point    = new GeoPoint(ClosestPointTo(from));
            Double   distance = EarthGeo.GetDistance(point, from);

            return(distance);
        }
Exemplo n.º 6
0
        static GeoLine LineFromCenterAndBearing(GeoPoint centerPoint, Double bearing, Double distance)
        {
            GeoPoint p1 = EarthGeo.GetPoint(centerPoint, Angle.Reverse(bearing), distance / 2);
            GeoPoint p2 = EarthGeo.GetPoint(centerPoint, bearing, distance / 2);

            return(new GeoLine(p1, p2));
        }
Exemplo n.º 7
0
        public bool TryGetDistanceFromEnd(GeoPoint point, out Double distance)
        {
            bool success = false;

            distance = 0;
            GeoLineList list = new GeoLineList(this);

            list.Reverse();

            for (int index = 0; index < list.Count; index++)
            {
                GeoLine  line = list[index];
                GeoPoint closest;

                Double thisDistance;
                closest = line.ClosestPointTo(point, out thisDistance);

                /** less than this distance, he is on the line */
                if (thisDistance > .1)
                {
                    distance += line.Length;
                }
                else
                {
                    distance += EarthGeo.GetDistance(line.P2 as GeoPoint, closest);
                    success   = true;
                    break;
                }
            }
            return(success);
        }
Exemplo n.º 8
0
        bool TryMoveBackwardOnPath(GeoLine originLine, GeoPoint origin, Double distance, out GeoPoint final)
        {
            final = null;
            Double distanceMoved = EarthGeo.GetDistance(origin as GeoPoint, originLine.P1 as GeoPoint);

            if (distanceMoved <= distance)
            {
                for (int index = IndexOf(originLine) - 1; index >= 0; index--)
                {
                    if (distanceMoved + this[index].Length >= distance)
                    {
                        final = EarthGeo.GetPoint(this[index].P2 as GeoPoint, Angle.Reverse(this[index].Bearing), distance - distanceMoved);
                        break;
                    }
                    else
                    {
                        distanceMoved += this[index].Length;
                    }
                }
            }
            else
            {
                /** the destination is on the first segment */
                final = EarthGeo.GetPoint(origin, Angle.Reverse(originLine.Bearing), distance);
            }
            return(final != null);
        }
Exemplo n.º 9
0
        public GeoPoint ClosestEndPointTo(GeoPoint point, out Double distance)
        {
            Double d1 = EarthGeo.GetDistance(_P1, point);
            Double d2 = EarthGeo.GetDistance(_P2, point);

            distance = Math.Min(d1, d2);
            return(d1 < d2 ? _P1 : _P2);
        }
Exemplo n.º 10
0
        void RecalculateAxes()
        {
            MajorAxis = new GeoLine(
                EarthGeo.GetPoint(_center, Angle.Reverse(m_MajorAxisBearing), m_MajorAxisLength / 2),
                EarthGeo.GetPoint(_center, m_MajorAxisBearing, m_MajorAxisLength / 2));

            Double minorAxisBearing = Angle.Add(m_MajorAxisBearing, 90);

            MinorAxis = new GeoLine(
                EarthGeo.GetPoint(_center, Angle.Reverse(minorAxisBearing), m_MinorAxisLength / 2),
                EarthGeo.GetPoint(_center, minorAxisBearing, m_MinorAxisLength / 2));
        }
Exemplo n.º 11
0
        public static GeoCircle CreateFromRegionPolygon(GeoPolygon polygon)
        {
            GeoPoint      centroid  = polygon.Centroid;
            List <Double> distances = new List <Double>();

            foreach (GeoPoint point in polygon.Points)
            {
                distances.Add(EarthGeo.GetDistance(centroid, point));
            }

            return(new GeoCircle(centroid, distances.Average()));
        }
Exemplo n.º 12
0
        public PointD GetPixelPoint(GeoPoint geoPoint)
        {
            // get a bearing to the point from our known point
            double geoBearing  = EarthGeo.GetBearing(this.GeoPoint, geoPoint);
            double geoDistance = EarthGeo.GetDistance(this.GeoPoint, geoPoint);

            double pixBearing  = FlatGeo.Radians(((geoBearing + 360) - this.BearingDelta) % 360);
            double pixDistance = geoDistance * this.PixelsPerMeter;

            PointD ret = new PointD(this.PixPoint.X + (Math.Sin(pixBearing) * pixDistance), this.PixPoint.Y - (Math.Cos(pixBearing) * pixDistance));

            return(ret);
        }
Exemplo n.º 13
0
        public GeoPolygon ToGeoPolygon(int sides = 16)
        {
            GeoPointList points    = new GeoPointList();
            Double       angleSize = (360 / (Double)sides);

            for (Double degrees = 0; degrees < 360; degrees += angleSize)
            {
                points.Add(EarthGeo.GetPoint(_center, Radius, degrees));
            }

            GeoPolygon polygon = new GeoPolygon(points);

            return(polygon);
        }
Exemplo n.º 14
0
        public void ExtendTo(GeoPoint point)
        {
            Double d1 = EarthGeo.GetDistance(_P1, point);
            Double d2 = EarthGeo.GetDistance(_P2, point);

            if (d1 < d2)
            {
                _P1 = point;
            }
            else
            {
                _P2 = point;
            }
        }
Exemplo n.º 15
0
        public virtual GeoRectangle GetMinimumBoundingRectangle()
        {
            /** offset minor axis to half the major axis distance in either direction */
            Double   offset = MajorAxis.Length / 2;
            GeoPoint p1     = EarthGeo.GetPoint(MinorAxis.P1 as GeoPoint, MajorAxis.Bearing, offset);
            GeoPoint p2     = EarthGeo.GetPoint(MinorAxis.P2 as GeoPoint, MajorAxis.Bearing, offset);
            GeoPoint p3     = EarthGeo.GetPoint(MinorAxis.P2 as GeoPoint, Angle.Reverse(MajorAxis.Bearing), offset);
            GeoPoint p4     = EarthGeo.GetPoint(MinorAxis.P1 as GeoPoint, Angle.Reverse(MajorAxis.Bearing), offset);

            return(new GeoRectangle(new GeoPointList()
            {
                p1, p2, p3, p4
            }));
        }
Exemplo n.º 16
0
        void RecalculateFociAndArea()
        {
            //      __________
            //    \/ r1² * r2²
            Double fociDistance = Math.Sqrt(MajorRadius * MajorRadius - MinorRadius * MinorRadius);

            Foci = new GeoPoint[]
            {
                EarthGeo.GetPoint(Center as GeoPoint, Angle.Reverse(MajorAxis.Bearing), fociDistance),
                EarthGeo.GetPoint(Center as GeoPoint, MajorAxis.Bearing, fociDistance)
            };

            Eccentricity = new Line(Foci[0], Center).Length / new Line(Foci[0], MinorAxis.P1).Length;

            Area = Math.PI * MajorRadius * MinorRadius;
        }
Exemplo n.º 17
0
        void Initialize(PointDList pixPointList, GeoPointList geoPointList)
        {
            // Get and store the difference in pixel orientation to north (Rotation from north)
            double geoBearing = EarthGeo.GetBearing(geoPointList[0], geoPointList[1]);
            double pixBearing = GetPixelBearing(pixPointList[0], pixPointList[1]);

            this.BearingDelta = geoBearing - pixBearing;


            // Get and store the pixel to meter ratio (Scale to meters)
            double geoDistance = EarthGeo.GetDistance(geoPointList[0], geoPointList[1]);
            double pixDistance = new Line(pixPointList[0], pixPointList[1]).Length;

            _pixelsPerMeter = pixDistance / geoDistance;

            // Store a pixel cross reference point, from which all other conversions can happen
            this.PixPoint = new PointD(pixPointList[0].X, pixPointList[0].Y);
            this.GeoPoint = new GeoPoint(geoPointList[0].Y, geoPointList[0].X);
        }
Exemplo n.º 18
0
        public GeoPoint ClosestPointTo(GeoPoint pt, out Double distance)
        {
            /** SPSPTODO: This needs to use spherical trig */

            PointD closest;
            Double dx = P2.X - P1.X;
            Double dy = P2.Y - P1.Y;

            // Calculate the t that minimizes the distance.
            Double t = ((pt.X - P1.X) * dx + (pt.Y - P1.Y) * dy) / (dx * dx + dy * dy);

            // See if this represents one of the segment's
            // end points or a point in the middle.
            if (t < 0)
            {
                closest = new PointD(P1.X, P1.Y);
                dx      = pt.X - P1.X;
                dy      = pt.Y - P1.Y;
            }
            else if (t > 1)
            {
                closest = new PointD(P2.X, P2.Y);
                dx      = pt.X - P2.X;
                dy      = pt.Y - P2.Y;
            }
            else
            {
                closest = new PointD(P1.X + t * dx, P1.Y + t * dy);
                dx      = pt.X - closest.X;
                dy      = pt.Y - closest.Y;
            }

            GeoPoint ret = new GeoPoint(closest);

            distance = EarthGeo.GetDistance(pt, ret);
            return(ret);
        }
Exemplo n.º 19
0
        public override bool Intersects(GeoLine line, out GeoPoint intersection1, out GeoPoint intersection2, out int intersections)
        {
            intersection1 = new GeoPoint(float.NaN, float.NaN);
            intersection2 = new GeoPoint(float.NaN, float.NaN);

            const Double increment = .1;

            bool     intersects = false;
            GeoPoint p          = line.P1.Clone() as GeoPoint;

            do
            {
                if (this.Contains(p))
                {
                    intersects = true;
                    break;
                }

                p = EarthGeo.GetPoint(p, line.Bearing, increment);
            } while(EarthGeo.GetDistance(line.P1 as GeoPoint, p) < line.Length);

            intersections = 0;
            if (intersects)
            {
                Double degy   = EarthGeo.DegreesPerMeterAtLatitude(_center.Latitude);
                Double degx   = EarthGeo.DegreesPerMeterAtLongitude(_center.Longitude);
                Double radius = Radius * Math.Max(degx, degy);

                Double dx, dy, A, B, C, det, t;

                dx = line.P2.X - line.P1.X;
                dy = line.P2.Y - line.P1.Y;

                A = dx * dx + dy * dy;
                B = 2 * (dx * (line.P1.X - Center.X) + dy * (line.P1.Y - Center.Y));
                C = (line.P1.X - Center.X) * (line.P1.X - Center.X) + (line.P1.Y - Center.Y) * (line.P1.Y - Center.Y) - radius * radius;

                det = B * B - 4 * A * C;

                if ((A <= 0.00000001) || (det < 0))
                {
                    // No real solutions.
                    intersection1 = new GeoPoint(float.NaN, float.NaN);
                    intersection2 = new GeoPoint(float.NaN, float.NaN);
                }
                else if (det == 0)
                {
                    // One solution.
                    t             = -B / (2 * A);
                    intersection1 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    intersection2 = new GeoPoint(float.NaN, float.NaN);
                    intersections = 1;
                }
                else
                {
                    // Two solutions.
                    t             = (float)((-B + Math.Sqrt(det)) / (2 * A));
                    intersection1 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    t             = (float)((-B - Math.Sqrt(det)) / (2 * A));
                    intersection2 = new GeoPoint(line.P1.X + t * dx, line.P1.Y + t * dy);
                    intersections = 2;
                }
            }
            return(intersects);
        }
Exemplo n.º 20
0
        public override bool Contains(GeoPoint point)
        {
            Double distance = EarthGeo.GetDistance(_center, point);

            return(distance <= Radius);
        }
Exemplo n.º 21
0
        public override void Move(Double bearing, Double distance)
        {
            GeoPoint newCenter = EarthGeo.GetPoint(GeoCenter, bearing, distance);

            Move(newCenter);
        }
Exemplo n.º 22
0
 public bool Intersects(GeoLine other, int precision, out GeoPoint intersection)
 {
     return(EarthGeo.GetIntersection(this, other, precision, out intersection));
 }
Exemplo n.º 23
0
 public GeoPoint GetPointAt(Double bearing, Double distance)
 {
     return(EarthGeo.GetPoint(this, bearing, distance));
 }
Exemplo n.º 24
0
        public bool Contains(GeoPoint point, Double rayLength = DEFAULT_RAY_LENGTH)
        {
            /** Use Ray-Casting Algorithm to determine if point lies within polygon */

            Double rayBearing = EarthGeo.North;
            float  insides    = 0;
            float  outsides   = 0;

            int minimumRays = 4;

            bool majority = false;

            /**
             * We will cast at least two rays and keep casting till we get a majority of
             * one or the other, or we go in a circle.
             */
            do
            {
                /**
                 * Step One:
                 *   Create a ray from our point extending outwards
                 */
                GeoPoint endPoint = EarthGeo.GetPoint(point, rayBearing, rayLength);
                GeoLine  ray      = new GeoLine(point, endPoint);

                /**
                 * Step 2
                 *   Draw line from our point in any direction (we will use North)
                 *   and count the intersections
                 */
                Double intersections = 0;
                foreach (GeoLine line in Lines)
                {
                    if (ray.Intersects(line))
                    {
                        intersections++;
                    }
                }

                /** if the intersections are even, the point is outside... if odd, it's inside */
                bool inside = (intersections % 2) != 0;

                if (inside)
                {
                    insides++;
                }
                else
                {
                    outsides++;
                }

                rayBearing = Angle.Add(rayBearing, 95);

                if (insides + outsides >= minimumRays)
                {
                    majority = insides > outsides * 2 || outsides > insides * 2;
                }
            }while(majority == false && !(insides + outsides >= 360 / 5));

            return(insides > outsides);
        }