예제 #1
0
 public override Point PointOnBearing(Point from, double distDEG, double bearingDEG, SpatialContext ctx, Point reuse)
 {
     if (distDEG == 0)
     {
         if (reuse == null)
             return from;
         reuse.Reset(from.GetX(), from.GetY());
         return reuse;
     }
     double bearingRAD = DistanceUtils.ToRadians(bearingDEG);
     double x = from.GetX() + Math.Sin(bearingRAD)*distDEG;
     double y = from.GetY() + Math.Cos(bearingRAD)*distDEG;
     if (reuse == null)
     {
         return ctx.MakePoint(x, y);
     }
     else
     {
         reuse.Reset(x, y);
         return reuse;
     }
 }
예제 #2
0
        /**
         * Given a start point (startLat, startLon) and a bearing on a sphere of radius <i>sphereRadius</i>, return the destination point.
         *
         *
         * @param startLat The starting point latitude, in radians
         * @param startLon The starting point longitude, in radians
         * @param distanceRAD The distance to travel along the bearing in radians.
         * @param bearingRAD The bearing, in radians.  North is a 0, moving clockwise till radians(360).
         * @param result A preallocated array to hold the results.  If null, a new one is constructed.
         * @return The destination point, in radians.  First entry is latitude, second is longitude
         */
        public static Point PointOnBearingRAD(double startLat, double startLon, double distanceRAD, double bearingRAD, SpatialContext ctx, Point reuse)
        {
            /*
               lat2 = asin(sin(lat1)*cos(d/R) + cos(lat1)*sin(d/R)*cos(θ))
             lon2 = lon1 + atan2(sin(θ)*sin(d/R)*cos(lat1), cos(d/R)−sin(lat1)*sin(lat2))
              */
            double cosAngDist = Math.Cos(distanceRAD);
            double cosStartLat = Math.Cos(startLat);
            double sinAngDist = Math.Sin(distanceRAD);
            double sinStartLat = Math.Sin(startLat);
            double lat2 = Math.Asin(sinStartLat*cosAngDist +
                                    cosStartLat*sinAngDist*Math.Cos(bearingRAD));
            double lon2 = startLon + Math.Atan2(Math.Sin(bearingRAD)*sinAngDist*cosStartLat,
                                                cosAngDist - sinStartLat*Math.Sin(lat2));

            // normalize lon first
            if (lon2 > DEG_180_AS_RADS)
            {
                lon2 = -1.0*(DEG_180_AS_RADS - (lon2 - DEG_180_AS_RADS));
            }
            else if (lon2 < -DEG_180_AS_RADS)
            {
                lon2 = (lon2 + DEG_180_AS_RADS) + DEG_180_AS_RADS;
            }

            // normalize lat - could flip poles
            if (lat2 > DEG_90_AS_RADS)
            {
                lat2 = DEG_90_AS_RADS - (lat2 - DEG_90_AS_RADS);
                if (lon2 < 0)
                {
                    lon2 = lon2 + DEG_180_AS_RADS;
                }
                else
                {
                    lon2 = lon2 - DEG_180_AS_RADS;
                }
            }
            else if (lat2 < -DEG_90_AS_RADS)
            {
                lat2 = -DEG_90_AS_RADS - (lat2 + DEG_90_AS_RADS);
                if (lon2 < 0)
                {
                    lon2 = lon2 + DEG_180_AS_RADS;
                }
                else
                {
                    lon2 = lon2 - DEG_180_AS_RADS;
                }
            }

            if (reuse == null)
            {
                return ctx.MakePoint(lon2, lat2);
            }
            else
            {
                reuse.Reset(lon2, lat2); //x y
                return reuse;
            }
        }
예제 #3
0
 public override Point PointOnBearing(Point @from, double distDEG, double bearingDEG, SpatialContext ctx, Point reuse)
 {
     if (distDEG == 0)
     {
         if (reuse == null)
             return from;
         reuse.Reset(from.GetX(), from.GetY());
         return reuse;
     }
     Point result = DistanceUtils.PointOnBearingRAD(
         DistanceUtils.ToRadians(from.GetY()), DistanceUtils.ToRadians(from.GetX()),
         DistanceUtils.ToRadians(distDEG),
         DistanceUtils.ToRadians(bearingDEG), ctx, reuse);//output result is in radians
     result.Reset(DistanceUtils.ToDegrees(result.GetX()), DistanceUtils.ToDegrees(result.GetY()));
     return result;
 }