示例#1
0
        /// <summary>
        /// Insert an item into the tree this is the root of.
        /// </summary>
        /// <param name="itemInterval"></param>
        /// <param name="item"></param>
        public virtual void Insert(Interval itemInterval, object item)
        {
            int index = GetSubnodeIndex(itemInterval, ORIGIN);
            // if index is -1, itemEnv must contain the origin.
            if (index == -1)
            {
                Add(item);
                return;
            }
            /*
            * the item must be contained in one interval, so insert it into the
            * tree for that interval (which may not yet exist)
            */
            Node node = Nodes[index];
            /*
            *  If the subnode doesn't exist or this item is not contained in it,
            *  have to expand the tree upward to contain the item.
            */

            if (node == null || !node.Interval.Contains(itemInterval))
            {
                Node largerNode = Node.CreateExpanded(node, itemInterval);
                Nodes[index] = largerNode;
            }
            /*
            * At this point we have a subnode which exists and must contain
            * contains the env for the item.  Insert the item into the tree.
            */
            InsertContained(Nodes[index], itemInterval, item);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="itemInterval"></param>
        /// <returns></returns>
        public static Node CreateNode(Interval itemInterval)
        {
            Key key = new Key(itemInterval);

            Node node = new Node(key.Interval, key.Level);
            return node;
        }
示例#3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="node"></param>
 /// <param name="addInterval"></param>
 /// <returns></returns>
 public static Node CreateExpanded(Node node, Interval addInterval)
 {
     Interval expandInt = new Interval(addInterval);
     if (node != null) expandInt.ExpandToInclude(node._interval);
     Node largerNode = CreateNode(expandInt);
     if (node != null) largerNode.Insert(node);
     return largerNode;
 }
示例#4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="resultItems"></param>
 /// <returns></returns>
 public virtual IList AddAllItemsFromOverlapping(Interval interval, IList resultItems)
 {
     if (!IsSearchMatch(interval))
         return _items;
     // resultItems.addAll(items);
     foreach (object o in _items)
         resultItems.Add(o);
     for (int i = 0; i < 2; i++)
         if (_subnode[i] != null)
             _subnode[i].AddAllItemsFromOverlapping(interval, resultItems);
     return _items;
 }
示例#5
0
 /// <summary>
 /// Insert an item which is known to be contained in the tree rooted at
 /// the given Node.  Lower levels of the tree will be created
 /// if necessary to hold the item.
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="itemInterval"></param>
 /// <param name="item"></param>
 private static void InsertContained(Node tree, Interval itemInterval, object item)
 {
     Assert.IsTrue(tree.Interval.Contains(itemInterval));
     /*
     * Do NOT create a new node for zero-area intervals - this would lead
     * to infinite recursion. Instead, use a heuristic of simply returning
     * the smallest existing node containing the query
     */
     bool isZeroArea = IntervalSize.IsZeroWidth(itemInterval.Min, itemInterval.Max);
     NodeBase node;
     if (isZeroArea)
         node = tree.Find(itemInterval);
     else node = tree.GetNode(itemInterval);
     node.Add(item);
 }
示例#6
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="level"></param>
 public Node(Interval interval, int level)
 {
     _interval = interval;
     _level = level;
     _centre = (interval.Min + interval.Max) / 2;
 }
示例#7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private Node CreateSubnode(int index)
        {
            // create a new subnode in the appropriate interval
            double min = 0.0;
            double max = 0.0;

            switch (index)
            {
                case 0:
                    min = _interval.Min;
                    max = _centre;
                    break;
                case 1:
                    min = _centre;
                    max = _interval.Max;
                    break;
                default:
                    break;
            }
            Interval subInt = new Interval(min, max);
            Node node = new Node(subInt, _level - 1);
            return node;
        }
示例#8
0
 /// <summary>
 /// Returns the index of the subnode that wholely contains the given interval.
 /// If none does, returns -1.
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="centre"></param>
 public static int GetSubnodeIndex(Interval interval, double centre)
 {
     int subnodeIndex = -1;
     if (interval.Min >= centre)
         subnodeIndex = 1;
     if (interval.Max <= centre)
         subnodeIndex = 0;
     return subnodeIndex;
 }
示例#9
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 /// <param name="foundItems"></param>
 public virtual void Query(Interval interval, IList foundItems)
 {
     _root.AddAllItemsFromOverlapping(interval, foundItems);
 }
示例#10
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="itemInterval"></param>
 /// <param name="item"></param>
 public virtual void Insert(Interval itemInterval, object item)
 {
     CollectStats(itemInterval);
     Interval insertInterval = EnsureExtent(itemInterval, _minExtent);
     _root.Insert(insertInterval, item);
 }
示例#11
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 public Key(Interval interval)
 {
     ComputeKey(interval);
 }
示例#12
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="level"></param>
 /// <param name="itemInterval"></param>
 private void ComputeInterval(int level, Interval itemInterval)
 {
     double size = DoubleBits.PowerOf2(level);
     _pt = Math.Floor(itemInterval.Min / size) * size;
     _interval.Init(_pt, _pt + size);
 }
示例#13
0
 /// <summary>
 /// Return a square envelope containing the argument envelope,
 /// whose extent is a power of two and which is based at a power of 2.
 /// </summary>
 /// <param name="itemInterval"></param>
 public void ComputeKey(Interval itemInterval)
 {
     _level = ComputeLevel(itemInterval);
     _interval = new Interval();
     ComputeInterval(_level, itemInterval);
     // MD - would be nice to have a non-iterative form of this algorithm
     while (!_interval.Contains(itemInterval))
     {
         _level += 1;
         ComputeInterval(_level, itemInterval);
     }
 }
示例#14
0
 /// <summary>
 /// The root node matches all searches.
 /// </summary>
 /// <param name="interval"></param>
 protected override bool IsSearchMatch(Interval interval)
 {
     return true;
 }
示例#15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="itemInterval"></param>
 /// <returns></returns>
 protected override bool IsSearchMatch(Interval itemInterval)
 {
     return itemInterval.Overlaps(_interval);
 }
示例#16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 /// <returns></returns>
 public static int ComputeLevel(Interval interval)
 {
     double dx = interval.Width;
     int level = DoubleBits.GetExponent(dx) + 1;
     return level;
 }
示例#17
0
 /// <summary>
 /// Ensure that the Interval for the inserted item has non-zero extents.
 /// Use the current minExtent to pad it, if necessary.
 /// </summary>
 public static Interval EnsureExtent(Interval itemInterval, double minExtent)
 {
     double min = itemInterval.Min;
     double max = itemInterval.Max;
     // has a non-zero extent
     if (min != max)
         return itemInterval;
     // pad extent
     if (min == max)
     {
         min = min - minExtent / 2.0;
         max = min + minExtent / 2.0;
     }
     return new Interval(min, max);
 }
示例#18
0
 /// <summary>
 /// Returns the subnode containing the envelope.
 /// Creates the node if
 /// it does not already exist.
 /// </summary>
 /// <param name="searchInterval"></param>
 public virtual Node GetNode(Interval searchInterval)
 {
     int subnodeIndex = GetSubnodeIndex(searchInterval, _centre);
     // if index is -1 searchEnv is not contained in a subnode
     if (subnodeIndex != -1)
     {
         // create the node if it does not exist
         Node node = GetSubnode(subnodeIndex);
         // recursively search the found/created node
         return node.GetNode(searchInterval);
     }
     return this;
 }
示例#19
0
 /// <summary>
 /// min and max may be the same value.
 /// </summary>
 /// <param name="interval"></param>
 public virtual IList Query(Interval interval)
 {
     /*
      * the items that are matched are all items in intervals
      * which overlap the query interval
      */
     IList foundItems = new ArrayList();
     Query(interval, foundItems);
     return foundItems;
 }
示例#20
0
 /// <summary>
 /// Returns the smallest existing
 /// node containing the envelope.
 /// </summary>
 /// <param name="searchInterval"></param>
 public virtual NodeBase Find(Interval searchInterval)
 {
     int subnodeIndex = GetSubnodeIndex(searchInterval, _centre);
     if (subnodeIndex == -1)
         return this;
     if (Nodes[subnodeIndex] != null)
     {
         // query lies in subnode, so search it
         Node node = Nodes[subnodeIndex];
         return node.Find(searchInterval);
     }
     // no existing subnode, so return this one anyway
     return this;
 }
示例#21
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 private void CollectStats(Interval interval)
 {
     double del = interval.Width;
     if (del < _minExtent && del > 0.0)
         _minExtent = del;
 }
示例#22
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="interval"></param>
 /// <returns></returns>
 protected abstract bool IsSearchMatch(Interval interval);