public void BoxF2DOverlapsTest() { var rect1 = new BoxF2D(0, 0, 2, 2); var rect2 = new BoxF2D(3, 2, 5, 4); Assert.IsFalse(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 2, 2); rect2 = new BoxF2D(2, 0, 4, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 2, 2); rect2 = new BoxF2D(1, 1, 3, 3); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(1, 0, 2, 3); rect2 = new BoxF2D(0, 1, 3, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); rect1 = new BoxF2D(0, 0, 3, 3); rect2 = new BoxF2D(1, 1, 2, 2); Assert.IsTrue(rect1.Overlaps(rect2)); Assert.AreEqual(rect1.Overlaps(rect2), rect2.Overlaps(rect1)); }
/// <summary> /// Adds all the data in the given node and inside the given bounding box to the given data list. /// </summary> /// <param name="data"></param> /// <param name="node"></param> /// <param name="box"></param> public void AddInsideAtNode(IList <TDataType> data, QuadTreeNode node, BoxF2D box) { if (box.Overlaps(_bounds)) { // ok there is an overlap. if (_depth > 0) { if (_minMin != null) { _minMin.AddInsideAtNode(data, node, box); } if (_minMax != null) { _minMax.AddInsideAtNode(data, node, box); } if (_maxMin != null) { _maxMin.AddInsideAtNode(data, node, box); } if (_maxMax != null) { _maxMax.AddInsideAtNode(data, node, box); } } else { foreach (KeyValuePair <TPointType, TDataType> data_pair in _data) { if (box.IsInside(data_pair.Key)) { data.Add(data_pair.Value); } } } } }
/// <summary> /// Removes the given item but does not re-balance the tree. /// </summary> /// <param name="node">The node to begin the search for the item.</param> /// <param name="box">The box of the item.</param> /// <param name="item">The item to remove.</param> private static bool RemoveSimple(Node node, BoxF2D box, T item) { if (node.Children is List <Node> ) { var children = (node.Children as List <Node>); for (int idx = 0; idx < children.Count; idx++) { if (box.Overlaps(node.Boxes[idx])) { if (RTreeMemoryIndex <T> .RemoveSimple(node.Children[idx] as Node, box, item)) { // if sucessfull stop the search. return(true); } } } } else { var children = (node.Children as List <T>); if (children != null) { // the children are of the data type. return(children.Remove(item)); } } return(false); }
/// <summary> /// Returns true if the given rectangle overlaps with this view. /// </summary> /// <returns><c>true</c>, if with rectangle overlaps, <c>false</c> otherwise.</returns> /// <param name="left">Left.</param> /// <param name="top">Top.</param> /// <param name="right">Right.</param> /// <param name="bottom">Bottom.</param> public bool OverlapsWithBox(double left, double top, double right, double bottom) { BoxF2D box = new BoxF2D(left, top, right, bottom); if (box.Overlaps(_rectangle.BoundingBox)) { return(_rectangle.Overlaps(box)); } return(false); }
private static bool RemoveSimple(RTreeMemoryIndex <T> .Node node, BoxF2D box, T item) { if (node.Children is List <RTreeMemoryIndex <T> .Node> ) { List <RTreeMemoryIndex <T> .Node> children = node.Children as List <RTreeMemoryIndex <T> .Node>; for (int index = 0; index < children.Count; ++index) { if (box.Overlaps(node.Boxes[index]) && RTreeMemoryIndex <T> .RemoveSimple(node.Children[index] as RTreeMemoryIndex <T> .Node, box, item)) { return(true); } } } else { List <T> children = node.Children as List <T>; if (children != null) { return(children.Remove(item)); } } return(false); }
/// <summary> /// Fills the collection with data. /// </summary> /// <param name="node"></param> /// <param name="box"></param> /// <param name="result"></param> private static void Get(Node node, BoxF2D box, HashSet <T> result) { if (node.Children is List <Node> ) { var children = (node.Children as List <Node>); for (int idx = 0; idx < children.Count; idx++) { if (box.Overlaps(node.Boxes[idx])) { if (box.Contains(node.Boxes[idx])) { // add all the data from the child. RTreeMemoryIndex <T> .GetAll(children[idx], result); } else { // add the data from the child. RTreeMemoryIndex <T> .Get(children[idx], box, result); } } } } else { var children = (node.Children as List <T>); if (children != null) { // the children are of the data type. for (int idx = 0; idx < node.Children.Count; idx++) { if (node.Boxes[idx].Overlaps(box)) { result.Add(children[idx]); } } } } }
public void AddInsideAtNode(IList <TDataType> data, QuadTree <TPointType, TDataType> .QuadTreeNode node, BoxF2D box) { if (!box.Overlaps(this._bounds)) { return; } if (this._depth > 0) { if (this._minMin != null) { this._minMin.AddInsideAtNode(data, node, box); } if (this._minMax != null) { this._minMax.AddInsideAtNode(data, node, box); } if (this._maxMin != null) { this._maxMin.AddInsideAtNode(data, node, box); } if (this._maxMax == null) { return; } this._maxMax.AddInsideAtNode(data, node, box); } else { foreach (KeyValuePair <TPointType, TDataType> keyValuePair in this._data) { if (box.Contains((PointF2D)keyValuePair.Key)) { data.Add(keyValuePair.Value); } } } }
private static void Get(RTreeMemoryIndex <T> .Node node, BoxF2D box, HashSet <T> result) { if (node.Children is List <RTreeMemoryIndex <T> .Node> ) { List <RTreeMemoryIndex <T> .Node> children = node.Children as List <RTreeMemoryIndex <T> .Node>; for (int index = 0; index < children.Count; ++index) { if (box.Overlaps(node.Boxes[index])) { if (box.Contains(node.Boxes[index])) { RTreeMemoryIndex <T> .GetAll(children[index], result); } else { RTreeMemoryIndex <T> .Get(children[index], box, result); } } } } else { List <T> children = node.Children as List <T>; if (children == null) { return; } for (int index = 0; index < node.Children.Count; ++index) { if (node.Boxes[index].Overlaps(box)) { result.Add(children[index]); } } } }
/// <summary> /// Returns true if the given rectangle overlaps with this view. /// </summary> /// <returns><c>true</c>, if with rectangle overlaps, <c>false</c> otherwise.</returns> /// <param name="left">Left.</param> /// <param name="top">Top.</param> /// <param name="right">Right.</param> /// <param name="bottom">Bottom.</param> public bool OverlapsWithBox(double left, double top, double right, double bottom) { BoxF2D box = new BoxF2D (left, top, right, bottom); if (box.Overlaps (_rectangle.BoundingBox)) { return _rectangle.Overlaps (box); } return false; }
/// <summary> /// Deserializes the data that is relevant for the given box. /// </summary> /// <param name="stream"></param> /// <param name="box"></param> /// <param name="result"></param> /// <returns></returns> public void Search(SpatialIndexSerializerStream stream, BoxF2D box, HashSet <T> result) { _searchCancelled = false; // check if the current leaf/index exists. long position = stream.Position; KeyValuePair <ChildrenIndex, long> index; KeyValuePair <List <BoxF2D>, List <T> > leaf; if (_cachedIndexes.TryGet(position + 1 + 4, out index)) { // at this position is an index. stream.Seek(index.Value, SeekOrigin.Begin); } else if (_cachedLeaves.TryGet(position + 1, out leaf)) { // at this position there is a leaf. for (int idx = 0; idx < leaf.Value.Count; idx++) { // check each overlapping box. if (leaf.Key[idx].Overlaps(box)) { // adds the object to the result set. result.Add(leaf.Value[idx]); if (_searchCancelled) { // make sure to exit on cancelled search. break; } } } return; } if (index.Key == null) { // nothing was found. var leafFlag = new byte[1]; stream.Read(leafFlag, 0, 1); if (leafFlag[0] == 1) { // cannot deserialize a leaf without a given size. // try to read the entire stream as a leaf. leaf = this.SearchInLeaf(stream, 1, stream.Length - 1); for (int dataidx = 0; dataidx < leaf.Key.Count; dataidx++) { // check each overlapping box. if (leaf.Key[dataidx].Overlaps(box)) { // adds the object to the result set. result.Add(leaf.Value[dataidx]); } if (_searchCancelled) { // make sure to exit on cancelled search. break; } } return; } // build the run time type model. RuntimeTypeModel typeModel = this.GetRuntimeTypeModel(); // get the lenght of the meta info. var metaLengthBytes = new byte[4]; stream.Read(metaLengthBytes, 0, metaLengthBytes.Length); int metaLength = BitConverter.ToInt32(metaLengthBytes, 0); var metaBytes = new byte[metaLength]; position = stream.Position; stream.Read(metaBytes, 0, metaBytes.Length); index = new KeyValuePair <ChildrenIndex, long>( typeModel.Deserialize(new MemoryStream(metaBytes), null, typeof(ChildrenIndex)) as ChildrenIndex, stream.Position); } if (index.Key != null) { // the index was deserialized. _cachedIndexes.Add(position, index); // add to cache. position = stream.Position; int leafs = 0; if (index.Key.IsLeaf != null) { for (int idx = 0; idx < index.Key.IsLeaf.Length; idx++) { var localBox = new BoxF2D(index.Key.MinX [idx], index.Key.MinY [idx], index.Key.MaxX [idx], index.Key.MaxY [idx]); if (localBox.Overlaps(box)) // there will be data in one of the children. { if (index.Key.IsLeaf [idx]) // deserialize and search the leaf-data. // calculate size. { int size; if (idx == index.Key.IsLeaf.Length - 1) // the last index. { size = index.Key.End - index.Key.Starts [idx] - 1; } else // not the last index. { size = index.Key.Starts [idx + 1] - index.Key.Starts [idx] - 1; } long offset = position + index.Key.Starts [idx] + 1; if (!_cachedLeaves.TryGet(offset, out leaf)) // the leaf was not cached! { leaf = this.SearchInLeaf(stream, offset, size); } for (int dataidx = 0; dataidx < leaf.Key.Count; dataidx++) // check each overlapping box. { if (leaf.Key [dataidx].Overlaps(box)) // adds the object to the result set. { result.Add(leaf.Value [dataidx]); } } leafs++; } else // deserialize the node and the children. { stream.Seek(position + index.Key.Starts [idx], SeekOrigin.Begin); this.Search(stream, box, result); } } if (_searchCancelled) { // make sure to exit on cancelled search. break; } } } return; } throw new Exception("Cannot deserialize node!"); }