protected void InitMaxLevels() { String mlStr; if (args.TryGetValue(MAX_LEVELS, out mlStr) && mlStr != null) { maxLevels = int.Parse(mlStr); return; } double degrees; if (!args.TryGetValue(MAX_DIST_ERR, out mlStr) || mlStr == null) { if (!ctx.IsGeo()) { return; //let default to max } degrees = DistanceUtils.Dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM); } else { degrees = Double.Parse(mlStr); } maxLevels = GetLevelForDistance(degrees); }
protected internal virtual void InitMaxLevels() { string mlStr = args[MaxLevels]; if (mlStr != null) { maxLevels = int.Parse(mlStr); return; } double degrees; string maxDetailDistStr = args[MaxDistErr]; if (maxDetailDistStr == null) { if (!ctx.IsGeo()) { return; } //let default to max degrees = DistanceUtils.Dist2Degrees(DefaultGeoMaxDetailKm, DistanceUtils.EARTH_MEAN_RADIUS_KM); } else { degrees = double.Parse(maxDetailDistStr); } maxLevels = GetLevelForDistance(degrees); }
/// <summary> /// The factory is looked up via "prefixTree" in args, expecting "geohash" or "quad". /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen. /// </summary> /// <param name="args"></param> /// <param name="ctx"></param> /// <returns></returns> public static SpatialPrefixTree MakeSPT(Dictionary <String, String> args, SpatialContext ctx) { SpatialPrefixTreeFactory instance; String cname; if (!args.TryGetValue(PREFIX_TREE, out cname) || cname == null) { cname = ctx.IsGeo() ? "geohash" : "quad"; } if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase)) { instance = new GeohashPrefixTree.Factory(); } else if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase)) { instance = new QuadPrefixTree.Factory(); } else { Type t = Type.GetType(cname); instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(t); } instance.Init(args, ctx); return(instance.NewSPT()); }
//1m /// <summary>The factory is looked up via "prefixTree" in args, expecting "geohash" or "quad". /// </summary> /// <remarks> /// The factory is looked up via "prefixTree" in args, expecting "geohash" or "quad". /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen. /// </remarks> public static SpatialPrefixTree MakeSPT(IDictionary <string, string> args, SpatialContext ctx) { SpatialPrefixTreeFactory instance; string cname = args[PrefixTree]; if (cname == null) { cname = ctx.IsGeo() ? "geohash" : "quad"; } if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase)) { instance = new GeohashPrefixTree.Factory(); } else { if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase)) { instance = new QuadPrefixTree.Factory(); } else { try { Type c = Type.GetType(cname); instance = (SpatialPrefixTreeFactory)System.Activator.CreateInstance(c); } catch (Exception e) { throw new Exception(string.Empty, e); } } } instance.Init(args, ctx); return(instance.NewSPT()); }
public void testMultiShape(SpatialContext ctx) { this.ctx = ctx; if (ctx.IsGeo()) { return; //TODO not yet supported! } //come up with some random shapes int NUM_SHAPES = random.Next(1, 5); var shapes = new List <Rectangle>(NUM_SHAPES); while (shapes.Count < NUM_SHAPES) { shapes.Add(RandomRectangle(20)); } var multiShape = new MultiShape(shapes.Cast <Shape>(), ctx); //test multiShape.getBoundingBox(); Rectangle msBbox = multiShape.GetBoundingBox(); if (shapes.Count == 1) { Assert.Equal(shapes[0], msBbox.GetBoundingBox()); } else { foreach (Rectangle shape in shapes) { assertRelation("bbox contains shape", SpatialRelation.CONTAINS, msBbox, shape); } } //TODO test multiShape.relate() }
public void TestDefault() { SpatialContext s = SpatialContext.GEO; SpatialContext t = Call();//default Assert.Equal(s.GetType(), t.GetType()); Assert.Equal(s.IsGeo(), t.IsGeo()); Assert.Equal(s.GetDistCalc(), t.GetDistCalc()); Assert.Equal(s.GetWorldBounds(), t.GetWorldBounds()); }
public void TestCustom() { SpatialContext sc = Call("geo", "false"); Assert.True(!sc.IsGeo()); Assert.Equal(new CartesianDistCalc(), sc.GetDistCalc()); sc = Call("geo", "false", "distCalculator", "cartesian^2", "worldBounds", "-100 0 75 200");//West South East North Assert.Equal(new CartesianDistCalc(true), sc.GetDistCalc()); Assert.Equal(new RectangleImpl(-100, 75, 0, 200, sc), sc.GetWorldBounds()); sc = Call("geo", "true", "distCalculator", "lawOfCosines"); Assert.True(sc.IsGeo()); var test = new GeodesicSphereDistCalc.LawOfCosines(); Assert.Equal(test, sc.GetDistCalc()); }
public SpatialRelation Relate(Point point) { if (point.GetY() > GetMaxY() || point.GetY() < GetMinY()) { return(SpatialRelation.DISJOINT); } // all the below logic is rather unfortunate but some dateline cases demand it double minX = this.minX; double maxX = this.maxX; double pX = point.GetX(); if (ctx.IsGeo()) { //unwrap dateline and normalize +180 to become -180 double rawWidth = maxX - minX; if (rawWidth < 0) { maxX = minX + (rawWidth + 360); } //shift to potentially overlap if (pX < minX) { pX += 360; } else if (pX > maxX) { pX -= 360; } else { return(SpatialRelation.CONTAINS); //short-circuit } } if (pX < minX || pX > maxX) { return(SpatialRelation.DISJOINT); } return(SpatialRelation.CONTAINS); }
public DistanceSimilarity(SpatialContext ctx, Point queryPoint) { this.queryPoint = queryPoint; this.distCalc = ctx.GetDistCalc(); this.nullValue = (ctx.IsGeo() ? 180 : double.MaxValue); }
/// <summary>Returns a new shape that is larger than shape by at distErr.</summary> /// <remarks>Returns a new shape that is larger than shape by at distErr.</remarks> protected internal virtual Shape BufferShape(Shape shape, double distErr) { //TODO move this generic code elsewhere? Spatial4j? if (distErr <= 0) { throw new ArgumentException("distErr must be > 0"); } SpatialContext ctx = grid.SpatialContext; if (shape is Point) { return(ctx.MakeCircle((Point)shape, distErr)); } else { if (shape is Circle) { var circle = (Circle)shape; double newDist = circle.GetRadius() + distErr; if (ctx.IsGeo() && newDist > 180) { newDist = 180; } return(ctx.MakeCircle(circle.GetCenter(), newDist)); } else { Rectangle bbox = shape.GetBoundingBox(); double newMinX = bbox.GetMinX() - distErr; double newMaxX = bbox.GetMaxX() + distErr; double newMinY = bbox.GetMinY() - distErr; double newMaxY = bbox.GetMaxY() + distErr; if (ctx.IsGeo()) { if (newMinY < -90) { newMinY = -90; } if (newMaxY > 90) { newMaxY = 90; } if (newMinY == -90 || newMaxY == 90 || bbox.GetWidth() + 2 * distErr > 360) { newMinX = -180; newMaxX = 180; } else { newMinX = DistanceUtils.NormLonDEG(newMinX); newMaxX = DistanceUtils.NormLonDEG(newMaxX); } } else { //restrict to world bounds newMinX = Math.Max(newMinX, ctx.GetWorldBounds().GetMinX()); newMaxX = Math.Min(newMaxX, ctx.GetWorldBounds().GetMaxX()); newMinY = Math.Max(newMinY, ctx.GetWorldBounds().GetMinY()); newMaxY = Math.Min(newMaxY, ctx.GetWorldBounds().GetMaxY()); } return(ctx.MakeRectangle(newMinX, newMaxX, newMinY, newMaxY)); } } }
private double horizAxisY; //see getYAxis public GeoCircle(Point p, double radiusDEG, SpatialContext ctx) : base(p, radiusDEG, ctx) { Debug.Assert(ctx.IsGeo()); Init(); }
//These few norm methods normalize the arguments for creating a shape to // account for the dateline. Some tests loop past the dateline or have offsets // that go past it and it's easier to have them coded that way and correct for // it here. These norm methods should be used when needed, not frivolously. protected double normX(double x) { return(ctx.IsGeo() ? DistanceUtils.NormLonDEG(x) : x); }