예제 #1
0
		/// <summary>
		/// Insert an item into the tree this is the root of.
		/// </summary>
		/// <param name="itemInterval"></param>
		/// <param name="item"></param>
		public 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 = _subnode[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 );
				_subnode[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( _subnode[index], itemInterval, item );
		}
예제 #2
0
		/// <summary>
		/// Return a square envelope containing the argement 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 = Key.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 );
			}
		}
예제 #3
0
		public ArrayList AddAllItemsFromOverlapping( Interval interval, ArrayList resultItems )
		{
			if ( !IsSearchMatch( interval ) )
			{
				return _items;
			}
			resultItems.AddRange( _items );

			for (int i = 0; i < 2; i++) 
			{
				if ( _subnode[i] != null ) 
				{
					_subnode[i].AddAllItemsFromOverlapping( interval, resultItems );
				}
			}
			return _items;
		}
예제 #4
0
		/// <summary>
		/// Returns the subnode containing the envelope.  Creates the node if it does not already exist.
		/// </summary>
		/// <param name="searchInterval"></param>
		/// <returns></returns>
		public 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 );
			}
			else 
			{
				return this;
			}
		}
예제 #5
0
		/// <summary>
		/// Returns the smallest existing node containing the envelope.
		/// </summary>
		/// <param name="searchInterval"></param>
		/// <returns></returns>
		public NodeBase Find( Interval searchInterval )
		{
			int subnodeIndex = GetSubnodeIndex( searchInterval, _centre );
			if ( subnodeIndex == -1 )
			{
				return this;
			}

			if ( _subnode[subnodeIndex] != null ) 
			{
				// query lies in subnode, so search it
				Node node = _subnode[subnodeIndex];
				return node.Find( searchInterval );
			}
			// no existing subnode, so return this one anyway
			return this;
		}
예제 #6
0
		/// <summary>
		/// Initializes a new instance of the Key class.
		/// </summary>
		public Key( Interval interval )
		{
			ComputeKey( interval );
		}
예제 #7
0
		public Interval(Interval interval)
		{
			Initialize( interval.Min, interval.Max );
		}
예제 #8
0
		public bool Overlaps( Interval interval )
		{
			return Overlaps( interval.Min, interval.Max );
		}
예제 #9
0
		protected override bool IsSearchMatch( Interval itemInterval )
		{
			return itemInterval.Overlaps( _interval );
		}
예제 #10
0
		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;
		}
예제 #11
0
		public void Query(Interval interval, ArrayList foundItems)
		{
			_root.AddAllItemsFromOverlapping( interval, foundItems );
		}
예제 #12
0
		/// <summary>
		/// Min and max may be the same value.
		/// </summary>
		/// <param name="interval"></param>
		/// <returns></returns>
		public ArrayList Query( Interval interval )
		{
			// the items that are matched are all items in intervals
			// which overlap the query interval
			ArrayList foundItems = new ArrayList();
			Query( interval, foundItems );
			return foundItems;
		}
예제 #13
0
		/// <summary>
		/// Insert an item which is known to be contained in the tree rooted at the given Noed.
		/// Lower levels of the tree will be created it necessary to hold the item.
		/// </summary>
		/// <param name="tree"></param>
		/// <param name="itemInterval"></param>
		/// <param name="item"></param>
		private void InsertContained( Node tree, Interval itemInterval, object item )
		{
			Debug.Assert( 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 );
		}
예제 #14
0
		/// <summary>
		/// The root node matches all searches.
		/// </summary>
		/// <param name="interval"></param>
		/// <returns></returns>
		protected override bool IsSearchMatch( Interval interval )
		{
			return true;
		}
예제 #15
0
		private void ComputeInterval( int level, Interval itemInterval )
		{
			double size = DoubleBits.PowerOf2( level );
			//double size = pow2.power(level);
			_pt = Math.Floor( itemInterval.Min / size) * size;
			_interval.Initialize( _pt, _pt + size );
		}
예제 #16
0
		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;
			}

			Interval subInt = new Interval( min, max );
			Node node = new Node (subInt, _level - 1);
			return node;
		}
예제 #17
0
		public static Node CreateNode( Interval itemInterval )
		{
			Key key = new Key( itemInterval );

			//System.out.println("input: " + env + "  binaryEnv: " + key.getEnvelope());
			Node node = new Node( key.Interval, key.Level );
			return node;
		}
예제 #18
0
		private void CollectStats( Interval interval )
		{
			double del = interval.GetWidth();
			if (del < _minExtent && del > 0.0)
			{
				_minExtent = del;
			}
		}
예제 #19
0
		/// <summary>
		/// Initializes a new instance of the Node class.
		/// </summary>
		public Node( Interval interval, int level )
		{
			_interval = interval;
			_level = level;
			_centre = ( interval.Min + interval.Max ) / 2;
		}
예제 #20
0
		/// <summary>
		/// Ensure that the Interval for the inserted item has non-zero extents.
		/// Use the current minExtent to pad it, if necessary.
		/// </summary>
		/// <param name="itemInterval"></param>
		/// <param name="minExtent"></param>
		/// <returns></returns>
		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);
		}
예제 #21
0
		public void Insert( Interval itemInterval, object item )
		{
			CollectStats( itemInterval );
			Interval insertInterval = EnsureExtent( itemInterval, _minExtent );
			_root.Insert( insertInterval, item );
			/* DEBUG
			int newSize = size();
			System.out.println("BinTree: size = " + newSize + "   node size = " + nodeSize());
			if (newSize <= oldSize) 
			{
				System.out.println("Lost item!");
				root.insert(insertInterval, item);
				System.out.println("reinsertion size = " + size());
			}*/
		}
예제 #22
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>
		/// <returns></returns>
		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;
		}
예제 #23
0
		public bool Contains( Interval interval )
		{
			return Contains( interval.Min, interval.Max );
		}
예제 #24
0
		protected abstract bool IsSearchMatch( Interval interval );
예제 #25
0
		public void ExpandToInclude( Interval interval )
		{
			if ( interval.Max > _max ) _max = interval.Max;
			if ( interval.Min < _min ) _min = interval.Min;
		}
예제 #26
0
		public static int ComputeLevel( Interval interval )
		{
			double dx = interval.GetWidth();
			//int level = BinaryPower.exponent(dx) + 1;
			int level = DoubleBits.Exponent(dx) + 1;
			return level;
		}