MakePoint() 공개 메소드

Construct a point.
public MakePoint ( double x, double y ) : System.Point
x double
y double
리턴 System.Point
예제 #1
0
        public void testMakeRect(SpatialContext ctx)
        {
            this.ctx = ctx;

            //test rectangle constructor
            Assert.Equal(new RectangleImpl(1, 3, 2, 4),
                new RectangleImpl(new PointImpl(1, 2), new PointImpl(3, 4)));

            //test ctx.makeRect
            Assert.Equal(ctx.MakeRect(1, 3, 2, 4),
                ctx.MakeRect(ctx.MakePoint(1, 2), ctx.MakePoint(3, 4)));
        }
예제 #2
0
 /// <summary>
 /// Computes the distance given a shape and the {@code distErrPct}.  The
 /// algorithm is the fraction of the distance from the center of the query
 /// shape to its furthest bounding box corner.
 /// </summary>
 /// <param name="shape">Mandatory.</param>
 /// <param name="distErrPct">0 to 0.5</param>
 /// <param name="ctx">Mandatory</param>
 /// <returns>A distance (in degrees).</returns>
 public static double CalcDistanceFromErrPct(Shape shape, double distErrPct, SpatialContext ctx)
 {
     if (distErrPct < 0 || distErrPct > 0.5)
     {
         throw new ArgumentException("distErrPct " + distErrPct + " must be between [0 to 0.5]", "distErrPct");
     }
     if (distErrPct == 0 || shape is Point)
     {
         return 0;
     }
     Rectangle bbox = shape.GetBoundingBox();
     //The diagonal distance should be the same computed from any opposite corner,
     // and this is the longest distance that might be occurring within the shape.
     double diagonalDist = ctx.GetDistCalc().Distance(
         ctx.MakePoint(bbox.GetMinX(), bbox.GetMinY()), bbox.GetMaxX(), bbox.GetMaxY());
     return diagonalDist*0.5*distErrPct;
 }
예제 #3
0
        private readonly GeoCircle inverseCircle; //when distance reaches > 1/2 way around the world, cache the inverse.

        #endregion Fields

        #region Constructors

        public GeoCircle(Point p, double dist, SpatialContext ctx)
            : base(p, dist, ctx)
        {
            Debug.Assert(ctx.IsGeo());

            //In the direction of latitude (N,S), distance is the same number of degrees.
            distDEG = ctx.GetDistCalc().DistanceToDegrees(distRadius);

            if (distDEG > 90)
            {
                //--spans more than half the globe
                Debug.Assert(enclosingBox.GetWidth() == 360);
                double backDistDEG = 180 - distDEG;
                if (backDistDEG > 0)
                {
                    double backDistance = ctx.GetDistCalc().DegreesToDistance(backDistDEG);
                    //shrink inverseCircle as small as possible to avoid accidental overlap
                    backDistance -= Ulp(backDistance);
                    Point backPoint = ctx.MakePoint(GetCenter().GetX() + 180, GetCenter().GetY() + 180);
                    inverseCircle = new GeoCircle(backPoint, backDistance, ctx);
                }
                else
                    inverseCircle = null;//whole globe
                horizAxisY = GetCenter().GetY();//although probably not used
            }
            else
            {
                inverseCircle = null;
                double _horizAxisY = ctx.GetDistCalc().CalcBoxByDistFromPt_yHorizAxisDEG(GetCenter(), dist, ctx);
                //some rare numeric conditioning cases can cause this to be barely beyond the box
                if (_horizAxisY > enclosingBox.GetMaxY())
                {
                    horizAxisY = enclosingBox.GetMaxY();
                }
                else if (_horizAxisY < enclosingBox.GetMinY())
                {
                    horizAxisY = enclosingBox.GetMinY();
                }
                else
                {
                    horizAxisY = _horizAxisY;
                }
                //Debug.Assert(enclosingBox.Relate_yRange(horizAxis, horizAxis, ctx).Intersects());
            }
        }
예제 #4
0
 public override Point PointOnBearing(Point @from, double dist, double bearingDEG, SpatialContext ctx)
 {
     if (dist == 0)
         return from;
     double bearingRAD = DistanceUtils.ToRadians(bearingDEG);
     double x = Math.Sin(bearingRAD) * dist;
     double y = Math.Cos(bearingRAD) * dist;
     return ctx.MakePoint(from.GetX() + x, from.GetY() + y);
 }
예제 #5
0
        public void TestSimplePoint(SpatialContext ctx)
        {
            base.ctx = ctx;

            Point pt = ctx.MakePoint(0, 0);
            String msg = pt.ToString();

            //test equals & hashcode
            Point pt2 = ctx.MakePoint(0, 0);
            Assert.Equal(/*msg,*/ pt, pt2);
            Assert.Equal(/*msg,*/ pt.GetHashCode(), pt2.GetHashCode());

            Assert.False(pt.HasArea(), msg);
            Assert.Equal(/*msg,*/ pt.GetCenter(), pt);
            Rectangle bbox = pt.GetBoundingBox();
            Assert.False(bbox.HasArea(), msg);

            var center = bbox.GetCenter();
            Assert.True(pt.Equals(center));
            //Assert.Equal(/*msg,*/ pt, center);

            AssertRelation(msg, SpatialRelation.CONTAINS, pt, pt2);
            AssertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(0, 1));
            AssertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(1, 0));
            AssertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(1, 1));
        }
예제 #6
0
        public void TestGeoCircle(SpatialContext ctx)
        {
            base.ctx = ctx;

            Assert.Equal("Circle(Pt(x=10.0,y=20.0), d=30.0° 3335.85km)", ctx.MakeCircle(10, 20, 30).ToString());

            double v = 200 * (random.NextDouble() > 0.5 ? -1 : 1);
            Assert.Throws<InvalidShapeException>(() => ctx.MakeCircle(v,0,5));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeCircle(0, v, 5));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeCircle(random.Next(-180, 180), random.Next(-90, 90), v));

            //--Start with some static tests that once failed:

            //Bug: numeric edge at pole, fails to init
            ctx.MakeCircle(110, -12, 90 + 12);

            //Bug: horizXAxis not in enclosing rectangle, assertion
            ctx.MakeCircle(-44, 16, 106);
            ctx.MakeCircle(-36, -76, 14);
            ctx.MakeCircle(107, 82, 172);

            // TODO need to update this test to be valid
            //{
            //    //Bug in which distance was being confused as being in the same coordinate system as x,y.
            //    double distDeltaToPole = 0.001;//1m
            //    double distDeltaToPoleDEG = ctx.getDistCalc().distanceToDegrees(distDeltaToPole);
            //    double dist = 1;//1km
            //    double distDEG = ctx.getDistCalc().distanceToDegrees(dist);
            //    Circle c = ctx.makeCircle(0, 90 - distDeltaToPoleDEG - distDEG, dist);
            //    Rectangle cBBox = c.getBoundingBox();
            //    Rectangle r = ctx.makeRect(cBBox.getMaxX() * 0.99, cBBox.getMaxX() + 1, c.getCenter().getY(), c.getCenter().getY());
            //    assertEquals(INTERSECTS, c.getBoundingBox().relate(r, ctx));
            //    assertEquals("dist != xy space", INTERSECTS, c.relate(r, ctx));//once failed here
            //}

            assertEquals("edge rounding issue 2", SpatialRelation.INTERSECTS, ctx.MakeCircle(84, -40, 136).Relate(ctx.MakeRectangle(-150, -80, 34, 84)));

            assertEquals("edge rounding issue", SpatialRelation.CONTAINS, ctx.MakeCircle(0, 66, 156).Relate(ctx.MakePoint(0, -90)));

            assertEquals("nudge back circle", SpatialRelation.CONTAINS, ctx.MakeCircle(-150, -90, 122).Relate(ctx.MakeRectangle(0, -132, 32, 32)));

            assertEquals("wrong estimate", SpatialRelation.DISJOINT, ctx.MakeCircle(-166, 59, kmToDeg(5226.2)).Relate(ctx.MakeRectangle(36, 66, 23, 23)));

            assertEquals("bad CONTAINS (dateline)", SpatialRelation.INTERSECTS, ctx.MakeCircle(56, -50, kmToDeg(12231.5)).Relate(ctx.MakeRectangle(108, 26, 39, 48)));

            assertEquals("bad CONTAINS (backwrap2)", SpatialRelation.INTERSECTS,
                ctx.MakeCircle(112, -3, 91).Relate(ctx.MakeRectangle(-163, 29, -38, 10)));

            assertEquals("bad CONTAINS (r x-wrap)", SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-139, 47, 80).Relate(ctx.MakeRectangle(-180, 180, -3, 12)));

            assertEquals("bad CONTAINS (pwrap)", SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-139, 47, 80).Relate(ctx.MakeRectangle(-180, 179, -3, 12)));

            assertEquals("no-dist 1", SpatialRelation.WITHIN,
                ctx.MakeCircle(135, 21, 0).Relate(ctx.MakeRectangle(-103, -154, -47, 52)));

            assertEquals("bbox <= >= -90 bug", SpatialRelation.CONTAINS,
                ctx.MakeCircle(-64, -84, 124).Relate(ctx.MakeRectangle(-96, 96, -10, -10)));

            //The horizontal axis line of a geo circle doesn't necessarily pass through c's ctr.
            assertEquals("c's horiz axis doesn't pass through ctr", SpatialRelation.INTERSECTS,
                ctx.MakeCircle(71, -44, 40).Relate(ctx.MakeRectangle(15, 27, -62, -34)));

            assertEquals("pole boundary", SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-100, -12, 102).Relate(ctx.MakeRectangle(143, 175, 4, 32)));

            assertEquals("full circle assert", SpatialRelation.CONTAINS,
                ctx.MakeCircle(-64, 32, 180).Relate(ctx.MakeRectangle(47, 47, -14, 90)));

            //--Now proceed with systematic testing:
            assertEquals(ctx.GetWorldBounds(), ctx.MakeCircle(0, 0, 180).GetBoundingBox());
            //assertEquals(ctx.makeCircle(0,0,distToOpposeSide/2 - 500).getBoundingBox());

            double[] theXs = new double[] { -180, -45, 90 };
            foreach (double x in theXs)
            {
                double[] theYs = new double[] { -90, -45, 0, 45, 90 };
                foreach (double y in theYs)
                {
                    TestCircle(x, y, 0);
                    TestCircle(x, y, kmToDeg(500));
                    TestCircle(x, y, 90);
                    TestCircle(x, y, 180);
                }
            }

            TestCircleIntersect();
        }
예제 #7
0
        public void TestGeoRectangle(SpatialContext ctx)
        {
            base.ctx = ctx;

            double v = 200 * (random.NextDouble() > 0.5 ? -1 : 1);
            Assert.Throws<InvalidShapeException>(() => ctx.MakeRectangle(v,0,0,0));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeRectangle(0,v,0,0));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeRectangle(0,0,v,0));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeRectangle(0,0,0,v));
            Assert.Throws<InvalidShapeException>(() => ctx.MakeRectangle(0, 0, 10, -10));

            //test some relateXRange
            //    opposite +/- 180
            Assert.Equal(SpatialRelation.INTERSECTS, ctx.MakeRectangle(170, 180, 0, 0).RelateXRange(-180, -170));
            Assert.Equal(SpatialRelation.INTERSECTS, ctx.MakeRectangle(-90, -45, 0, 0).RelateXRange(-45, -135));
            Assert.Equal(SpatialRelation.CONTAINS, ctx.GetWorldBounds().RelateXRange(-90, -135));
            //point on edge at dateline using opposite +/- 180
            Assert.Equal(SpatialRelation.CONTAINS, ctx.MakeRectangle(170, 180, 0, 0).Relate(ctx.MakePoint(-180, 0)));

            //test 180 becomes -180 for non-zero width rectangle
            Assert.Equal(ctx.MakeRectangle(-180, -170, 0, 0), ctx.MakeRectangle(180, -170, 0, 0));
            Assert.Equal(ctx.MakeRectangle(170, 180, 0, 0), ctx.MakeRectangle(170, -180, 0, 0));

            double[] lons = new double[] { 0, 45, 160, 180, -45, -175, -180 }; //minX
            foreach (double lon in lons)
            {
                double[] lonWs = new double[] { 0, 20, 180, 200, 355, 360 }; //width
                foreach (double lonW in lonWs)
                {
                    if (lonW == 360 && lon != -180)
                        continue;
                    TestRectangle(lon, lonW, 0, 0);
                    TestRectangle(lon, lonW, -10, 10);
                    TestRectangle(lon, lonW, 80, 10); //polar cap
                    TestRectangle(lon, lonW, -90, 180); //full lat range
                }
            }

            TestShapes2D.testCircleReset(ctx);

            //Test geo rectangle intersections
            testRectIntersect();
        }
예제 #8
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;
            }
        }
예제 #9
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;
     }
 }
예제 #10
0
 public override Point PointOnBearing(Point @from, double dist, double bearingDEG, SpatialContext ctx)
 {
     //TODO avoid unnecessary double[] intermediate object
     if (dist == 0)
         return from;
     double[] latLon = DistanceUtils.PointOnBearingRAD(
         DistanceUtils.ToRadians(from.GetY()), DistanceUtils.ToRadians(from.GetX()),
         DistanceUtils.Dist2Radians(dist, ctx.GetUnits().EarthRadius()),
         DistanceUtils.ToRadians(bearingDEG), null);
     return ctx.MakePoint(DistanceUtils.ToDegrees(latLon[1]), DistanceUtils.ToDegrees(latLon[0]));
 }
예제 #11
0
        public void TestGeoRectangle(SpatialContext ctx)
        {
            base.ctx = ctx;

            //First test some relateXRange
            //    opposite +/- 180
            Assert.Equal(SpatialRelation.INTERSECTS, ctx.MakeRect(170, 180, 0, 0).RelateXRange(-180, -170, ctx));
            Assert.Equal(SpatialRelation.INTERSECTS, ctx.MakeRect(-90, -45, 0, 0).RelateXRange(-45, -135, ctx));
            Assert.Equal(SpatialRelation.CONTAINS, ctx.GetWorldBounds().RelateXRange(-90, -135, ctx));
            //point on edge at dateline using opposite +/- 180
            Assert.Equal(SpatialRelation.CONTAINS, ctx.MakeRect(170, 180, 0, 0).Relate(ctx.MakePoint(-180, 0), ctx));

            //test 180 becomes -180 for non-zero width rectangle
            Assert.Equal(ctx.MakeRect(-180, -170, 0, 0), ctx.MakeRect(180, -170, 0, 0));
            Assert.Equal(ctx.MakeRect(170, 180, 0, 0), ctx.MakeRect(170, -180, 0, 0));

            double[] lons = new double[] { 0, 45, 160, 180, -45, -175, -180 }; //minX
            foreach (double lon in lons)
            {
                double[] lonWs = new double[] { 0, 20, 180, 200, 355, 360 }; //width
                foreach (double lonW in lonWs)
                {
                    TestRectangle(lon, lonW, 0, 0);
                    TestRectangle(lon, lonW, -10, 10);
                    TestRectangle(lon, lonW, 80, 10); //polar cap
                    TestRectangle(lon, lonW, -90, 180); //full lat range
                }
            }

            //Test geo rectangle intersections
            TestRectIntersect();
        }
예제 #12
0
 /**
  * Decodes the given geohash into a latitude and longitude
  *
  * @param geohash Geohash to deocde
  * @return Array with the latitude at index 0, and longitude at index 1
  */
 public static Point Decode(String geohash, SpatialContext ctx)
 {
     Rectangle rect = DecodeBoundary(geohash, ctx);
     double latitude = (rect.GetMinY() + rect.GetMaxY()) / 2D;
     double longitude = (rect.GetMinX() + rect.GetMaxX()) / 2D;
     return ctx.MakePoint(longitude, latitude);
 }
예제 #13
0
 public SpatialRelation Relate(Point pt, SpatialContext ctx)
 {
     //TODO if not jtsPoint, test against bbox to avoid JTS if disjoint
     var jtsPoint = (NtsPoint)(pt is NtsPoint ? pt : ctx.MakePoint(pt.GetX(), pt.GetY()));
     return geom.Disjoint(jtsPoint.GetGeom()) ? SpatialRelation.DISJOINT : SpatialRelation.CONTAINS;
 }