GetDistCalc() 공개 메소드

public GetDistCalc ( ) : DistanceCalculator
리턴 DistanceCalculator
예제 #1
0
 //we don't have a line shape so we use a rectangle for these axis
 public CircleImpl(Point p, double dist, SpatialContext ctx)
 {
     //We assume any normalization / validation of params already occurred (including bounding dist)
     this.point = p;
     this.distRadius = dist;
     this.ctx = ctx;
     this.enclosingBox = ctx.GetDistCalc().CalcBoxByDistFromPt(point, distRadius, ctx);
 }
예제 #2
0
 //we don't have a line shape so we use a rectangle for these axis
 public CircleImpl(Point p, double radiusDEG, SpatialContext ctx)
 {
     //We assume any validation of params already occurred (including bounding dist)
     this.ctx = ctx;
     this.point = p;
     this.radiusDEG = radiusDEG;
     this.enclosingBox = ctx.GetDistCalc().CalcBoxByDistFromPt(point, this.radiusDEG, ctx, null);
 }
예제 #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
 /// <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;
 }
예제 #5
0
 public double GetArea(SpatialContext ctx)
 {
     if (ctx == null)
     {
         return GetWidth()*GetHeight();
     }
     else
     {
         return ctx.GetDistCalc().Area(this);
     }
 }
예제 #6
0
 public DistanceSimilarity(SpatialContext ctx, Point queryPoint)
 {
     this.queryPoint = queryPoint;
     this.distCalc = ctx.GetDistCalc();
     this.nullValue = (ctx.IsGeo() ? 180 : double.MaxValue);
 }
예제 #7
0
        public SpatialRelation Relate(Circle circle, SpatialContext ctx)
        {
            double crossDist = ctx.GetDistCalc().Distance(point, circle.GetCenter());
            double aDist = distRadius, bDist = circle.GetRadius();
            if (crossDist > aDist + bDist)
                return SpatialRelation.DISJOINT;
            if (crossDist < aDist && crossDist + bDist <= aDist)
                return SpatialRelation.CONTAINS;
            if (crossDist < bDist && crossDist + aDist <= bDist)
                return SpatialRelation.WITHIN;

            return SpatialRelation.INTERSECTS;
        }
예제 #8
0
 public double GetArea(SpatialContext ctx)
 {
     if (ctx == null)
     {
         return Math.PI*distRadius*distRadius;
     }
     else
     {
         return ctx.GetDistCalc().Area(this);
     }
 }
예제 #9
0
        public void TestGeoCircle(SpatialContext ctx)
        {
            base.ctx = ctx;

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

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

            //Bug: horizXAxis not in enclosing rectangle, assertion
            ctx.MakeCircle(-44, 16, DegToDist(106));
            ctx.MakeCircle(-36, -76, DegToDist(14));
            ctx.MakeCircle(107, 82, DegToDist(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
            //}

            Assert.Equal(/*"nudge back circle", */ SpatialRelation.CONTAINS, ctx.MakeCircle(-150, -90, DegToDist(122)).Relate(ctx.MakeRect(0, -132, 32, 32), ctx));

            Assert.Equal(/* "wrong estimate", */ SpatialRelation.DISJOINT, ctx.MakeCircle(-166, 59, 5226.2).Relate(ctx.MakeRect(36, 66, 23, 23), ctx));

            Assert.Equal(/*"bad CONTAINS (dateline)",*/ SpatialRelation.INTERSECTS,
                ctx.MakeCircle(56, -50, 12231.5).Relate(ctx.MakeRect(108, 26, 39, 48), ctx));

            Assert.Equal(/*"bad CONTAINS (backwrap2)",*/ SpatialRelation.INTERSECTS,
                ctx.MakeCircle(112, -3, DegToDist(91)).Relate(ctx.MakeRect(-163, 29, -38, 10), ctx));

            Assert.Equal(/*"bad CONTAINS (r x-wrap)",*/ SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-139, 47, DegToDist(80)).Relate(ctx.MakeRect(-180, 180, -3, 12), ctx));

            Assert.Equal(/*"bad CONTAINS (pwrap)",*/ SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-139, 47, DegToDist(80)).Relate(ctx.MakeRect(-180, 179, -3, 12), ctx));

            Assert.Equal(/*"no-dist 1",*/ SpatialRelation.WITHIN,
                ctx.MakeCircle(135, 21, 0).Relate(ctx.MakeRect(-103, -154, -47, 52), ctx));

            Assert.Equal(/*"bbox <= >= -90 bug",*/ SpatialRelation.CONTAINS,
                ctx.MakeCircle(-64, -84, DegToDist(124)).Relate(ctx.MakeRect(-96, 96, -10, -10), ctx));

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

            Assert.Equal(/*"pole boundary",*/ SpatialRelation.INTERSECTS,
                ctx.MakeCircle(-100, -12, DegToDist(102)).Relate(ctx.MakeRect(143, 175, 4, 32), ctx));

            Assert.Equal(/*"full circle assert",*/ SpatialRelation.CONTAINS,
                ctx.MakeCircle(-64, 32, DegToDist(180)).Relate(ctx.MakeRect(47, 47, -14, 90), ctx));

            //--Now proceed with systematic testing:

            double distToOpposeSide = ctx.GetUnits().EarthRadius() * Math.PI;
            Assert.Equal(ctx.GetWorldBounds(), ctx.MakeCircle(0, 0, distToOpposeSide).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, 500);
                    TestCircle(x, y, DegToDist(90));
                    TestCircle(x, y, ctx.GetUnits().EarthRadius() * 6);
                }
            }

            TestCircleIntersect();
        }