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); } }
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)); }
/// <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); } }