public virtual void TestLineStringDateline() { //works because we use NTS (NtsGeometry); BufferedLineString doesn't yet do DL wrap. IShape s = ctx.ReadShapeFromWkt("LINESTRING(160 10, -170 15)"); CustomAssert.EqualWithDelta(30, s.BoundingBox.Width, 0.0); }
public void TestNtsContextFactory() { NtsSpatialContext ctx = (NtsSpatialContext)Call( "spatialContextFactory", typeof(NtsSpatialContextFactory).AssemblyQualifiedName, "geo", "true", "normWrapLongitude", "true", "precisionScale", "2.0", "wktShapeParserClass", typeof(CustomWktShapeParser).AssemblyQualifiedName, "datelineRule", "ccwRect", "validationRule", "repairConvexHull", "autoIndex", "true"); Assert.True(ctx.IsNormWrapLongitude); CustomAssert.EqualWithDelta(2.0, ctx.GeometryFactory.PrecisionModel.Scale, 0.0); Assert.True(CustomWktShapeParser.once);//cheap way to test it was created Assert.Equal(DatelineRule.CcwRect, ((NtsWktShapeParser)ctx.WktShapeParser).DatelineRule); Assert.Equal(ValidationRule.RepairConvexHull, ((NtsWktShapeParser)ctx.WktShapeParser).ValidationRule); //ensure geo=false with worldbounds works -- fixes #72 ctx = (NtsSpatialContext)Call( "spatialContextFactory", typeof(NtsSpatialContextFactory).AssemblyQualifiedName, "geo", "false",//set to false "worldBounds", "ENVELOPE(-500,500,300,-300)", "normWrapLongitude", "true", "precisionScale", "2.0", "wktShapeParserClass", typeof(CustomWktShapeParser).AssemblyQualifiedName, "datelineRule", "ccwRect", "validationRule", "repairConvexHull", "autoIndex", "true"); CustomAssert.EqualWithDelta(300, ctx.WorldBounds.MaxY, 0.0); }
public void TestNormLon() { var lons = new double[][] { new double[] { 1.23, 1.23 }, //1.23 might become 1.2299999 after some math and we want to ensure that doesn't happen new double[] { -180, -180 }, new double[] { 180, +180 }, new double[] { 0, 0 }, new double[] { -190, 170 }, new double[] { 181, -179 }, new double[] { -180 - 360, -180 }, new double[] { -180 - 720, -180 }, new double[] { 180 + 360, +180 }, new double[] { 180 + 720, +180 } }; foreach (var pair in lons) { CustomAssert.EqualWithDelta( /*"input "+pair[0],*/ pair[1], DistanceUtils.NormLonDEG(pair[0]), Double.Epsilon); } var random = new Random(RandomSeed.Seed()); for (int i = -1000; i < 1000; i += random.Next(9) * 10) { double d = DistanceUtils.NormLonDEG(i); Assert.True(d >= -180 && d <= 180, i + " " + d); } }
public void TestNormLat() { var lats = new double[][] { new double[] { 1.23, 1.23 }, //1.23 might become 1.2299999 after some math and we want to ensure that doesn't happen new double[] { -90, -90 }, new double[] { 90, 90 }, new double[] { 0, 0 }, new double[] { -100, -80 }, new double[] { -90 - 180, 90 }, new double[] { -90 - 360, -90 }, new double[] { 90 + 180, -90 }, new double[] { 90 + 360, 90 }, new double[] { -12 + 180, 12 } }; foreach (var pair in lats) { CustomAssert.EqualWithDelta( /* "input "+pair[0],*/ pair[1], DistanceUtils.NormLatDEG(pair[0]), Double.Epsilon); } var random = new Random(RandomSeed.Seed()); for (int i = -1000; i < 1000; i += random.Next(9) * 10) { double d = DistanceUtils.NormLatDEG(i); Assert.True(/*i + " " + d,*/ d >= -90 && d <= 90); } }
protected virtual void AssertEqualsRatio(string msg, double expected, double actual) { double delta = Math.Abs(actual - expected); double @base = Math.Min(actual, expected); double deltaRatio = @base == 0 ? delta : Math.Min(delta, delta / @base); CustomAssert.EqualWithDelta(/*msg,*/ 0, deltaRatio, EPS); }
private static void AssertEqualsRatio(double expected, double actual, double EPS) { double delta = Math.Abs(actual - expected); double baseValue = Math.Min(actual, expected); double deltaRatio = baseValue == 0 ? delta : Math.Min(delta, delta / baseValue); CustomAssert.EqualWithDelta(0, deltaRatio, EPS); }
private void AssertEqualsRatio(String msg, double expected, double actual) { double delta = Math.Abs(actual - expected); double baseValue = Math.Min(actual, expected); double deltaRatio = (baseValue == 0) ? delta : Math.Min(delta, delta / baseValue); CustomAssert.EqualWithDelta(/*msg,*/ 0, deltaRatio, EPS); }
public virtual void TestDecodePreciseLongitudeLatitude() { string hash = GeohashUtils.EncodeLatLon(52.3738007, 4.8909347); IPoint point = GeohashUtils.Decode(hash, ctx); CustomAssert.EqualWithDelta(52.3738007, point.Y, 0.00001D); CustomAssert.EqualWithDelta(4.8909347, point.X, 0.00001D); }
public void TestDecodeImpreciseLongitudeLatitude() { String hash = GeohashUtils.EncodeLatLon(84.6, 10.5); Point point = GeohashUtils.Decode(hash, ctx); CustomAssert.EqualWithDelta(84.6, point.GetY(), 0.00001D); CustomAssert.EqualWithDelta(10.5, point.GetX(), 0.00001D); }
public virtual void TestDecodeImpreciseLongitudeLatitude() { string hash = GeohashUtils.EncodeLatLon(84.6, 10.5); IPoint point = GeohashUtils.Decode(hash, ctx); CustomAssert.EqualWithDelta(84.6, point.Y, 0.00001D); CustomAssert.EqualWithDelta(10.5, point.X, 0.00001D); }
public virtual void TestHashLenToWidth() { //test odd & even len double[] boxOdd = GeohashUtils.LookupDegreesSizeForHashLen(3); CustomAssert.EqualWithDelta(1.40625, boxOdd[0], 0.0001); CustomAssert.EqualWithDelta(1.40625, boxOdd[1], 0.0001); double[] boxEven = GeohashUtils.LookupDegreesSizeForHashLen(4); CustomAssert.EqualWithDelta(0.1757, boxEven[0], 0.0001); CustomAssert.EqualWithDelta(0.3515, boxEven[1], 0.0001); }
public virtual void TestWidthGreaterThan180() { //does NOT cross the dateline but is a wide shape >180 NtsGeometry ntsGeo = (NtsGeometry)ctx.ReadShapeFromWkt("POLYGON((-161 49, 0 49, 20 49, 20 89.1, 0 89.1, -161 89.2, -161 49))"); CustomAssert.EqualWithDelta(161 + 20, ntsGeo.BoundingBox.Width, 0.001); //shift it to cross the dateline and check that it's still good ntsGeo = ShiftPoly(ntsGeo, 180); CustomAssert.EqualWithDelta(161 + 20, ntsGeo.BoundingBox.Width, 0.001); }
public void testSomeDistances() { //See to verify: from http://www.movable-type.co.uk/scripts/latlong.html Point ctr = pLL(0, 100); CustomAssert.EqualWithDelta(11100, dc().Distance(ctr, pLL(10, 0)) * DistanceUtils.DEG_TO_KM, 3); double deg = dc().Distance(ctr, pLL(10, -160)); CustomAssert.EqualWithDelta(11100, deg * DistanceUtils.DEG_TO_KM, 3); CustomAssert.EqualWithDelta(314.40338, dc().Distance(pLL(1, 2), pLL(3, 4)) * DistanceUtils.DEG_TO_KM, EPS); }
protected virtual void TestRectangle(double minX, double width, double minY, double height) { double maxX = minX + width; double maxY = minY + height; minX = NormX(minX); maxX = NormX(maxX); IRectangle r = ctx.MakeRectangle(minX, maxX, minY, maxY); //test equals & hashcode of duplicate IRectangle r2 = ctx.MakeRectangle(minX, maxX, minY, maxY); Assert.Equal(r, r2); Assert.Equal(r.GetHashCode(), r2.GetHashCode()); string msg = r.ToString(); Assert.Equal(/*msg,*/ width != 0 && height != 0, r.HasArea); Assert.Equal(/*msg,*/ width != 0 && height != 0, r.GetArea(ctx) > 0); if (ctx.IsGeo && r.Width == 360 && r.Height == 180) { //whole globe double earthRadius = DistanceUtils.ToDegrees(1); CustomAssert.EqualWithDelta(4 * Math.PI * earthRadius * earthRadius, r.GetArea(ctx), 1.0);//1km err } AssertEqualsRatio(msg, height, r.Height); AssertEqualsRatio(msg, width, r.Width); IPoint center = r.Center; msg += " ctr:" + center; //System.out.println(msg); AssertRelation(msg, SpatialRelation.CONTAINS, r, center); IDistanceCalculator dc = ctx.DistCalc; double dUR = dc.Distance(center, r.MaxX, r.MaxY); double dLR = dc.Distance(center, r.MaxX, r.MinY); double dUL = dc.Distance(center, r.MinX, r.MaxY); double dLL = dc.Distance(center, r.MinX, r.MinY); Assert.Equal(/*msg,*/ width != 0 || height != 0, dUR != 0); if (dUR != 0) { Assert.True(dUR > 0 && dLL > 0); } AssertEqualsRatio(msg, dUR, dUL); AssertEqualsRatio(msg, dLR, dLL); if (!ctx.IsGeo || center.Y == 0) { AssertEqualsRatio(msg, dUR, dLL); } }
private void checkBBox(Point ctr, double distKm) { String msg = "ctr: " + ctr + " distKm: " + distKm; double dist = distKm * DistanceUtils.KM_TO_DEG; Rectangle r = dc().CalcBoxByDistFromPt(ctr, dist, ctx, null); double horizAxisLat = dc().CalcBoxByDistFromPt_yHorizAxisDEG(ctr, dist, ctx); if (!Double.IsNaN(horizAxisLat)) { Assert.True(r.RelateYRange(horizAxisLat, horizAxisLat).Intersects()); } //horizontal if (r.GetWidth() >= 180) { double deg = dc().Distance(ctr, r.GetMinX(), r.GetMaxY() == 90 ? 90 : -90); double calcDistKm = deg * DistanceUtils.DEG_TO_KM; Assert.True(/*msg,*/ calcDistKm <= distKm + EPS); //horizAxisLat is meaningless in this context } else { Point tPt = FindClosestPointOnVertToPoint(r.GetMinX(), r.GetMinY(), r.GetMaxY(), ctr); double calcDistKm = dc().Distance(ctr, tPt) * DistanceUtils.DEG_TO_KM; CustomAssert.EqualWithDelta(/*msg,*/ distKm, calcDistKm, EPS); CustomAssert.EqualWithDelta(/*msg,*/ tPt.GetY(), horizAxisLat, EPS); } //vertical double topDistKm = dc().Distance(ctr, ctr.GetX(), r.GetMaxY()) * DistanceUtils.DEG_TO_KM; if (r.GetMaxY() == 90) { Assert.True(/*msg,*/ topDistKm <= distKm + EPS); } else { CustomAssert.EqualWithDelta(msg, distKm, topDistKm, EPS); } double botDistKm = dc().Distance(ctr, ctr.GetX(), r.GetMinY()) * DistanceUtils.DEG_TO_KM; if (r.GetMinY() == -90) { Assert.True(/*msg,*/ botDistKm <= distKm + EPS); } else { CustomAssert.EqualWithDelta(/*msg,*/ distKm, botDistKm, EPS); } }
public void testArea() { //simple bbox Rectangle r = RandomRectangle(20); var ctxJts = (NtsSpatialContext)ctx; var rPoly = new NtsGeometry(ctxJts.GetGeometryFrom(r), ctxJts, false); CustomAssert.EqualWithDelta(r.GetArea(null), rPoly.GetArea(null), 0.0); CustomAssert.EqualWithDelta(r.GetArea(ctx), rPoly.GetArea(ctx), 0.000001); //same since fills 100% CustomAssert.EqualWithDelta(1300, POLY_SHAPE.GetArea(null), 0.0); //fills 27% CustomAssert.EqualWithDelta(0.27, POLY_SHAPE.GetArea(ctx) / POLY_SHAPE.GetBoundingBox().GetArea(ctx), 0.009); Assert.True(POLY_SHAPE.GetBoundingBox().GetArea(ctx) > POLY_SHAPE.GetArea(ctx)); }
public virtual void TestArea() { //simple bbox IRectangle r = RandomRectangle(20); NtsSpatialContext ctxNts = (NtsSpatialContext)ctx; NtsGeometry rPoly = ctxNts.MakeShape(ctxNts.GetGeometryFrom(r), false, false); CustomAssert.EqualWithDelta(r.GetArea(null), rPoly.GetArea(null), 0.0); CustomAssert.EqualWithDelta(r.GetArea(ctx), rPoly.GetArea(ctx), 0.000001);//same since fills 100% CustomAssert.EqualWithDelta(1300, POLY_SHAPE.GetArea(null), 0.0); //fills 27% CustomAssert.EqualWithDelta(0.27, POLY_SHAPE.GetArea(ctx) / POLY_SHAPE.BoundingBox.GetArea(ctx), 0.009); Assert.True(POLY_SHAPE.BoundingBox.GetArea(ctx) > POLY_SHAPE.GetArea(ctx)); }
public void testArea() { double radius = DistanceUtils.EARTH_MEAN_RADIUS_KM * DistanceUtils.KM_TO_DEG; //surface of a sphere is 4 * pi * r^2 double earthArea = 4 * Math.PI * radius * radius; Circle c = ctx.MakeCircle(random.Next(-180, 180), random.Next(-90, 90), 180); //180 means whole earth CustomAssert.EqualWithDelta(earthArea, c.GetArea(ctx), 1.0); CustomAssert.EqualWithDelta(earthArea, ctx.GetWorldBounds().GetArea(ctx), 1.0); //now check half earth Circle cHalf = ctx.MakeCircle(c.GetCenter(), 90); CustomAssert.EqualWithDelta(earthArea / 2, cHalf.GetArea(ctx), 1.0); //circle with same radius at +20 lat with one at -20 lat should have same area as well as bbox with same area Circle c2 = ctx.MakeCircle(c.GetCenter(), 30); Circle c3 = ctx.MakeCircle(c.GetCenter().GetX(), 20, 30); CustomAssert.EqualWithDelta(c2.GetArea(ctx), c3.GetArea(ctx), 0.01); Circle c3Opposite = ctx.MakeCircle(c.GetCenter().GetX(), -20, 30); CustomAssert.EqualWithDelta(c3.GetArea(ctx), c3Opposite.GetArea(ctx), 0.01); CustomAssert.EqualWithDelta(c3.GetBoundingBox().GetArea(ctx), c3Opposite.GetBoundingBox().GetArea(ctx), 0.01); //small shapes near the equator should have similar areas to euclidean rectangle Rectangle smallRect = ctx.MakeRectangle(0, 1, 0, 1); CustomAssert.EqualWithDelta(1.0, smallRect.GetArea(null), 0.0); double smallDelta = smallRect.GetArea(null) - smallRect.GetArea(ctx); Assert.True(smallDelta > 0 && smallDelta < 0.0001); Circle smallCircle = ctx.MakeCircle(0, 0, 1); smallDelta = smallCircle.GetArea(null) - smallCircle.GetArea(ctx); Assert.True(smallDelta > 0 && smallDelta < 0.0001); //bigger, but still fairly similar //c2 = ctx.makeCircle(c.getCenter(), 30); double areaRatio = c2.GetArea(null) / c2.GetArea(ctx); Assert.True(areaRatio > 1 && areaRatio < 1.1); }
private void assertDistanceConversion(double dist) { double radius = DistanceUtils.EARTH_MEAN_RADIUS_KM; //test back & forth conversion for both double distRAD = DistanceUtils.Dist2Radians(dist, radius); CustomAssert.EqualWithDelta(dist, DistanceUtils.Radians2Dist(distRAD, radius), EPS); double distDEG = DistanceUtils.Dist2Degrees(dist, radius); CustomAssert.EqualWithDelta(dist, DistanceUtils.Degrees2Dist(distDEG, radius), EPS); //test across rad & deg CustomAssert.EqualWithDelta(distDEG, DistanceUtils.ToDegrees(distRAD), EPS); //test point on bearing CustomAssert.EqualWithDelta( DistanceUtils.PointOnBearingRAD(0, 0, DistanceUtils.Dist2Radians(dist, radius), DistanceUtils.DEG_90_AS_RADS, ctx, new PointImpl(0, 0, ctx)).GetX(), distRAD, 10e-5); }
public void TestDecodeEncode() { String geoHash = "u173zq37x014"; Assert.Equal(geoHash, GeohashUtils.EncodeLatLon(52.3738007, 4.8909347)); Point point = GeohashUtils.Decode(geoHash, ctx); CustomAssert.EqualWithDelta(52.37380061d, point.GetY(), 0.000001d); CustomAssert.EqualWithDelta(4.8909343d, point.GetX(), 0.000001d); Assert.Equal(geoHash, GeohashUtils.EncodeLatLon(point.GetY(), point.GetX())); geoHash = "u173"; point = GeohashUtils.Decode("u173", ctx); geoHash = GeohashUtils.EncodeLatLon(point.GetY(), point.GetX()); Point point2 = GeohashUtils.Decode(geoHash, ctx); CustomAssert.EqualWithDelta(point.GetY(), point2.GetY(), 0.000001d); CustomAssert.EqualWithDelta(point.GetX(), point2.GetX(), 0.000001d); }
public virtual void TestDecodeEncode() { string geoHash = "u173zq37x014"; Assert.Equal(geoHash, GeohashUtils.EncodeLatLon(52.3738007, 4.8909347)); IPoint point = GeohashUtils.Decode(geoHash, ctx); CustomAssert.EqualWithDelta(52.37380061d, point.Y, 0.000001d); CustomAssert.EqualWithDelta(4.8909343d, point.X, 0.000001d); Assert.Equal(geoHash, GeohashUtils.EncodeLatLon(point.Y, point.X)); geoHash = "u173"; point = GeohashUtils.Decode("u173", ctx); geoHash = GeohashUtils.EncodeLatLon(point.Y, point.X); IPoint point2 = GeohashUtils.Decode(geoHash, ctx); CustomAssert.EqualWithDelta(point.Y, point2.Y, 0.000001d); CustomAssert.EqualWithDelta(point.X, point2.X, 0.000001d); }
public virtual void TestCalcBoxByDistFromPt() { //first test regression { double d = 6894.1 * DistanceUtils.KM_TO_DEG; IPoint pCtr = PLL(-20, 84); IPoint pTgt = PLL(-42, 15); Assert.True(Dc().Distance(pCtr, pTgt) < d); //since the pairwise distance is less than d, a bounding box from ctr with d should contain pTgt. IRectangle r = Dc().CalcBoxByDistFromPt(pCtr, d, ctx, null); Assert.Equal(SpatialRelation.CONTAINS, r.Relate(pTgt)); CheckBBox(pCtr, d); } CustomAssert.EqualWithDelta(/*"0 dist, horiz line",*/ -45, Dc().CalcBoxByDistFromPt_yHorizAxisDEG(ctx.MakePoint(-180, -45), 0, ctx), 0); double MAXDIST = (double)180 * DistanceUtils.DEG_TO_KM; CheckBBox(ctx.MakePoint(0, 0), MAXDIST); CheckBBox(ctx.MakePoint(0, 0), MAXDIST * 0.999999); CheckBBox(ctx.MakePoint(0, 0), 0); CheckBBox(ctx.MakePoint(0, 0), 0.000001); CheckBBox(ctx.MakePoint(0, 90), 0.000001); CheckBBox(ctx.MakePoint(-32.7, -5.42), 9829); CheckBBox(ctx.MakePoint(0, 90 - 20), (double)20 * DistanceUtils.DEG_TO_KM); { double d = 0.010;//10m CheckBBox(ctx.MakePoint(0, 90 - (d + 0.001) * DistanceUtils.KM_TO_DEG), d); } for (int T = 0; T < 100; T++) { double lat = -90 + random.NextDouble() * 180; double lon = -180 + random.NextDouble() * 360; IPoint ctr = ctx.MakePoint(lon, lat); double dist = MAXDIST * random.NextDouble(); CheckBBox(ctr, dist); } }
public virtual 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.WorldBounds.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(); //Test buffer AssertEquals(ctx.MakeRectangle(-10, 10, -10, 10), ctx.MakeRectangle(0, 0, 0, 0).GetBuffered(10, ctx)); for (int i = 0; i < AtLeast(100); i++) { IRectangle r = RandomRectangle(1); int buf = random.Next(0, 90 + 1); IRectangle br = (IRectangle)r.GetBuffered(buf, ctx); AssertRelation(null, SpatialRelation.CONTAINS, br, r); if (r.Width + 2 * buf >= 360) { CustomAssert.EqualWithDelta(360, br.Width, 0.0); } else { Assert.True(br.Width - r.Width >= 2 * buf); } //TODO test more thoroughly; we don't check that we over-buf } Assert.True(ctx.MakeRectangle(0, 10, 0, 89).GetBuffered(0.5, ctx).BoundingBox.Width > 11); }