Пример #1
0
        public override IRectangle CalcBoxByDistFromPt(IPoint from, double distDEG, SpatialContext ctx, IRectangle reuse)
        {
            double minX = from.X - distDEG;
            double maxX = from.X + distDEG;
            double minY = from.Y - distDEG;
            double maxY = from.Y + distDEG;

            if (reuse == null)
            {
                return(ctx.MakeRectangle(minX, maxX, minY, maxY));
            }
            else
            {
                reuse.Reset(minX, maxX, minY, maxY);
                return(reuse);
            }
        }
Пример #2
0
        public virtual void TestSimpleRectangle(SpatialContext ctx)
        {
            base.ctx = ctx;

            double v = 2001 * (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));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(10, -10, 0, 0));

            double[] minXs = new double[] { -1000, -360, -180, -20, 0, 20, 180, 1000 };
            foreach (double minX in minXs)
            {
                double[] widths = new double[] { 0, 10, 180, 360, 400 };
                foreach (double width in widths)
                {
                    TestRectangle(minX, width, 0, 0);
                    TestRectangle(minX, width, -10, 10);
                    TestRectangle(minX, width, 5, 10);
                }
            }

            IRectangle r = ctx.MakeRectangle(0, 0, 0, 0);

            r.Reset(1, 2, 3, 4);
            Assert.Equal(ctx.MakeRectangle(1, 2, 3, 4), r);

            TestRectIntersect();

            if (!ctx.IsGeo)
            {
                AssertEquals(ctx.MakeRectangle(0.9, 2.1, 2.9, 4.1), ctx.MakeRectangle(1, 2, 3, 4).GetBuffered(0.1, ctx));
            }

            TestEmptiness(ctx.MakeRectangle(double.NaN, double.NaN, double.NaN, double.NaN));
        }
Пример #3
0
        /// <summary>
        /// Calculates the bounding box of a circle, as specified by its center point
        /// and distance. <paramref name="reuse"/> is an optional argument to store the
        /// results to avoid object creation.
        /// </summary>
        public static IRectangle CalcBoxByDistFromPtDEG(double lat, double lon, double distDEG, SpatialContext ctx, IRectangle reuse)
        {
            //See http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates Section 3.1, 3.2 and 3.3
            double minX;
            double maxX;
            double minY;
            double maxY;

            if (distDEG == 0)
            {
                minX = lon;
                maxX = lon;
                minY = lat;
                maxY = lat;
            }
            else if (distDEG >= 180)
            {
                //distance is >= opposite side of the globe
                minX = -180;
                maxX = 180;
                minY = -90;
                maxY = 90;
            }
            else
            {
                //--calc latitude bounds
                maxY = lat + distDEG;
                minY = lat - distDEG;

                if (maxY >= 90 || minY <= -90)
                {
                    //touches either pole
                    //we have special logic for longitude
                    minX = -180;
                    maxX = 180; //world wrap: 360 deg
                    if (maxY <= 90 && minY >= -90)
                    {
                        //doesn't pass either pole: 180 deg
                        minX = NormLonDEG(lon - 90);
                        maxX = NormLonDEG(lon + 90);
                    }
                    if (maxY > 90)
                    {
                        maxY = 90;
                    }
                    if (minY < -90)
                    {
                        minY = -90;
                    }
                }
                else
                {
                    //--calc longitude bounds
                    double lon_delta_deg = CalcBoxByDistFromPt_deltaLonDEG(lat, lon, distDEG);

                    minX = NormLonDEG(lon - lon_delta_deg);
                    maxX = NormLonDEG(lon + lon_delta_deg);
                }
            }
            if (reuse == null)
            {
                return(ctx.MakeRectangle(minX, maxX, minY, maxY));
            }
            else
            {
                reuse.Reset(minX, maxX, minY, maxY);
                return(reuse);
            }
        }