/// <summary> /// Inserts an object into index. /// </summary> /// <param name="obj">An object to insert</param> public void Insert <T>(T obj) where T : IIndexable { if (!IndexedSpace.ContainsRectangle(obj.BoundingRectangle)) { throw new ArgumentException("Bounding rectangle of the object is outside of the indexed space. Need to rebuild index.", "obj"); } _root.Insert(obj, 1); }
internal int Insert(T ins, MultidimensionalComparator <T> comparator, int level) { Load(); CompareResult diff = comparator.Compare(ins, obj, level % comparator.NumberOfDimensions); if (diff == CompareResult.EQ && deleted) { Storage.Deallocate(obj); Modify(); obj = ins; deleted = false; return(level); } else if (diff != CompareResult.GT) { if (left == null) { Modify(); left = new KDTreeNode(Storage, ins); return(level + 1); } else { return(left.Insert(ins, comparator, level + 1)); } } else { if (right == null) { Modify(); right = new KDTreeNode(Storage, ins); return(level + 1); } else { return(right.Insert(ins, comparator, level + 1)); } } }
/// <summary> /// Adds an object to this node /// or one of its childs. /// </summary> internal void Insert(IIndexable obj, int branchDepth) { // возможно глубина текущей ветки // уже больше глубины индекса if (branchDepth > _parent.Depth) { _parent._depth++; } // возможно мы достигли: // 1. максимально допустимой глубины индекса // 2. порогового значения площади ячейки узла // при этом создавать дочерние узлы уже нельзя if (_parent.Depth >= _parent.MaxDepth || _parent._boxSquareThreshold > _boundingBox.Width * _boundingBox.Height) { _objects.Add(obj); return; } BoundingRectangle box0, box1; bool hasChilds = _child0 != null && _child1 != null; // усли у узла еще нет дочерних узлов, вычисляем их ограничивающие прямоугольники, // иначе берем их из дочерних узлов if (!hasChilds) { splitMaxAxis(_boundingBox, out box0, out box1); } else { box0 = _child0._boundingBox; box1 = _child1._boundingBox; } bool f0 = box0.Intersects(obj.BoundingRectangle); bool f1 = box1.Intersects(obj.BoundingRectangle); if (f0 && f1) { // дочерние узлы уже были созданы, // вариантов разбиения больше нет if (hasChilds) { _objects.Add(obj); return; } // возможно при разбиении вдоль другой оси ситуация не столь плачевна splitMinAxis(_boundingBox, out box0, out box1); f0 = box0.Intersects(obj.BoundingRectangle); f1 = box1.Intersects(obj.BoundingRectangle); if (f0 && f1) { // добавляемый объект пересекает оба ограничивающих прямоугольника в обоих // вариантах разбиения, значит мы не можем добавить его в дочерние узлы, // добавляем в текущий узел _objects.Add(obj); return; } } // если дочерние узлы еще не были созданы, создаем их if (_child0 == null && _child1 == null) { _child0 = new KDTreeNode(box0, _parent); _child1 = new KDTreeNode(box1, _parent); } if (f0) { _child0.Insert(obj, branchDepth + 1); return; } if (f1) { _child1.Insert(obj, branchDepth + 1); return; } #if DEBUG Debug.Assert(false, "This statement should never be executed"); #endif }