Ejemplo n.º 1
0
 /// <summary>
 /// Saves a node to a stream recursively
 /// </summary>
 /// <param name="node">Node to save</param>
 /// <param name="sw">Reference to BinaryWriter</param>
 private void SaveNode(QuadTreeOld node, ref System.IO.BinaryWriter sw)
 {
     //Write node boundingbox
     sw.Write(node.Box.MinX);
     sw.Write(node.Box.MinY);
     sw.Write(node.Box.MaxX);
     sw.Write(node.Box.MaxY);
     sw.Write(node.IsLeaf);
     if (node.IsLeaf)
     {
         sw.Write(node._objList.Count);                 //Write number of features at node
         for (int i = 0; i < node._objList.Count; i++)  //Write each featurebox
         {
             sw.Write(node._objList[i].box.MinX);
             sw.Write(node._objList[i].box.MinY);
             sw.Write(node._objList[i].box.MaxX);
             sw.Write(node._objList[i].box.MaxY);
             sw.Write(node._objList[i].ID);
         }
     }
     else if (!node.IsLeaf)             //Save next node
     {
         SaveNode(node.Child0, ref sw);
         SaveNode(node.Child1, ref sw);
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Disposes the node
 /// </summary>
 public void Dispose()
 {
     //this._box = null;
     this._child0  = null;
     this._child1  = null;
     this._objList = null;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Reads a node from a stream recursively
        /// </summary>
        /// <param name="depth">Current depth</param>
        /// <param name="br">Binary reader reference</param>
        /// <returns></returns>
        private static QuadTreeOld ReadNode(uint depth, ref System.IO.BinaryReader br)
        {
            QuadTreeOld node = new QuadTreeOld();

            node._Depth = depth;
            node.Box    = GeometryFactory.CreateEnvelope(br.ReadDouble(), br.ReadDouble(), br.ReadDouble(), br.ReadDouble());
            bool IsLeaf = br.ReadBoolean();

            if (IsLeaf)
            {
                int FeatureCount = br.ReadInt32();
                node._objList = new List <BoxObjects>();
                for (int i = 0; i < FeatureCount; i++)
                {
                    BoxObjects box = new BoxObjects();
                    box.box = GeometryFactory.CreateEnvelope(br.ReadDouble(), br.ReadDouble(), br.ReadDouble(), br.ReadDouble());
                    box.ID  = (uint)br.ReadInt32();
                    node._objList.Add(box);
                }
            }
            else
            {
                node.Child0 = ReadNode(node._Depth + 1, ref br);
                node.Child1 = ReadNode(node._Depth + 1, ref br);
            }
            return(node);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Loads a quadtree from a file
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static QuadTreeOld FromFile(string filename)
        {
            System.IO.FileStream   fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
            if (br.ReadDouble() != INDEXFILEVERSION)             //Check fileindex version
            {
                fs.Close();
                fs.Dispose();
                throw new ObsoleteFileFormatException("Invalid index file version. Please rebuild the spatial index by either deleting the index");
            }
            QuadTreeOld node = ReadNode(0, ref br);

            br.Close();
            fs.Close();
            return(node);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Recursive function that traverses the tree and looks for intersections with a boundingbox
 /// </summary>
 /// <param name="box">Boundingbox to intersect with</param>
 /// <param name="node">Node to search from</param>
 /// <param name="list">List of found intersections</param>
 private void IntersectTreeRecursive(IEnvelope box, QuadTreeOld node, ref Collection <int> list)
 {
     if (node.IsLeaf)             //Leaf has been reached
     {
         for (int i = 0; i < node._objList.Count; i++)
         {
             list.Add((int)node._objList[i].ID);
         }
     }
     else
     {
         if (node.Box.Intersects(box))
         {
             IntersectTreeRecursive(box, node.Child0, ref list);
             IntersectTreeRecursive(box, node.Child1, ref list);
         }
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates a node and either splits the objects recursively into sub-nodes, or stores them at the node depending on the heuristics.
        /// Tree is built top->down
        /// </summary>
        /// <param name="objList">Geometries to index</param>
        /// <param name="depth">Current depth of tree</param>
        /// <param name="heurdata">Heuristics data</param>
        public QuadTreeOld(List <BoxObjects> objList, uint depth, Heuristic heurdata)
        {
            _Depth = depth;
            _box   = new Envelope(objList[0].box);
            for (int i = 0; i < objList.Count; i++)
            {
                _box.ExpandToInclude(objList[i].box);
            }

            // test our build heuristic - if passes, make children
            if (depth < heurdata.maxdepth && objList.Count > heurdata.mintricnt &&
                (objList.Count > heurdata.tartricnt || ErrorMetric(_box) > heurdata.minerror))
            {
                List <BoxObjects>[] objBuckets = new List <BoxObjects> [2];              // buckets of geometries
                objBuckets[0] = new List <BoxObjects>();
                objBuckets[1] = new List <BoxObjects>();

                string longaxis = LongestAxis(_box); // longest axis
                double geoavg   = 0;                 // geometric average - midpoint of ALL the objects

                // go through all bbox and calculate the average of the midpoints
                double frac = 1.0f / objList.Count;
                for (int i = 0; i < objList.Count; i++)
                {
                    if (longaxis == "X")
                    {
                        geoavg += objList[i].box.Centre.X * frac;
                    }
                    else
                    {
                        geoavg += objList[i].box.Centre.Y * frac;
                    }
                }

//				// bucket bbox based on their midpoint's side of the geo average in the longest axis
                for (int i = 0; i < objList.Count; i++)
                {
                    if (longaxis == "X")
                    {
                        objBuckets[geoavg > objList[i].box.Centre.X ? 1 : 0].Add(objList[i]);
                    }
                    else
                    {
                        objBuckets[geoavg > objList[i].box.Centre.Y ? 1 : 0].Add(objList[i]);
                    }
                }

                //If objects couldn't be splitted, just store them at the leaf
                //TODO: Try splitting on another axis
                if (objBuckets[0].Count == 0 || objBuckets[1].Count == 0)
                {
                    _child0 = null;
                    _child1 = null;
                    // copy object list
                    _objList = objList;
                }
                else
                {
                    // create new children using the buckets
                    _child0 = new QuadTreeOld(objBuckets[0], depth + 1, heurdata);
                    _child1 = new QuadTreeOld(objBuckets[1], depth + 1, heurdata);
                }
            }
            else
            {
                // otherwise the build heuristic failed, this is
                // set the first child to null (identifies a leaf)
                _child0 = null;
                _child1 = null;
                // copy object list
                _objList = objList;
            }
        }
Ejemplo n.º 7
0
		/// <summary>
		/// Creates a node and either splits the objects recursively into sub-nodes, or stores them at the node depending on the heuristics.
		/// Tree is built top->down
		/// </summary>
		/// <param name="objList">Geometries to index</param>
		/// <param name="depth">Current depth of tree</param>
		/// <param name="heurdata">Heuristics data</param>
		public QuadTreeOld(List<BoxObjects> objList, uint depth, Heuristic heurdata)
		{
			_Depth = depth;
			_box = new Envelope(objList[0].box);
			for (int i = 0; i < objList.Count;i++ )
				_box.ExpandToInclude(objList[i].box);
			
			// test our build heuristic - if passes, make children
			if (depth < heurdata.maxdepth && objList.Count > heurdata.mintricnt &&
				(objList.Count > heurdata.tartricnt || ErrorMetric(_box) > heurdata.minerror))
			{
				List<BoxObjects>[] objBuckets = new List<BoxObjects>[2]; // buckets of geometries
				objBuckets[0] = new List<BoxObjects>();
				objBuckets[1] = new List<BoxObjects>();

				string longaxis = LongestAxis(_box); // longest axis
				double geoavg = 0; // geometric average - midpoint of ALL the objects

				// go through all bbox and calculate the average of the midpoints
				double frac = 1.0f / objList.Count;
				for (int i = 0; i < objList.Count;i++ )
				{
					if (longaxis=="X")
						geoavg += objList[i].box.Centre.X * frac;
					else
						geoavg += objList[i].box.Centre.Y * frac;
				}

//				// bucket bbox based on their midpoint's side of the geo average in the longest axis
				for (int i = 0; i < objList.Count;i++ )
				{
					if(longaxis=="X")
						objBuckets[geoavg > objList[i].box.Centre.X ? 1 : 0].Add(objList[i]);
					else
						objBuckets[geoavg > objList[i].box.Centre.Y ? 1 : 0].Add(objList[i]);						
				}

				//If objects couldn't be splitted, just store them at the leaf
				//TODO: Try splitting on another axis
				if (objBuckets[0].Count == 0 || objBuckets[1].Count == 0)
				{
					_child0 = null;
					_child1 = null;
					// copy object list
					_objList = objList;
				}
				else
				{
					// create new children using the buckets
					_child0 = new QuadTreeOld(objBuckets[0], depth + 1, heurdata);
					_child1 = new QuadTreeOld(objBuckets[1], depth + 1, heurdata);
				}
			}
			else
			{
				// otherwise the build heuristic failed, this is 
				// set the first child to null (identifies a leaf)
				_child0 = null;
				_child1 = null;
				// copy object list
				_objList = objList;
			}
		}
Ejemplo n.º 8
0
		/// <summary>
		/// Recursive function that traverses the tree and looks for intersections with a boundingbox
		/// </summary>
		/// <param name="box">Boundingbox to intersect with</param>
		/// <param name="node">Node to search from</param>
		/// <param name="list">List of found intersections</param>
		private void IntersectTreeRecursive(IEnvelope box, QuadTreeOld node, ref Collection<int> list)
		{
			if (node.IsLeaf) //Leaf has been reached
			{
                for (int i = 0; i < node._objList.Count; i++)
                {
                    list.Add((int) node._objList[i].ID);
                }
			}
			else
			{
				if(node.Box.Intersects(box))
				{
					IntersectTreeRecursive(box, node.Child0, ref list);
					IntersectTreeRecursive(box, node.Child1, ref list);
				}
			}
		}
Ejemplo n.º 9
0
		/// <summary>
		/// Disposes the node
		/// </summary>
		public void Dispose()
		{
			//this._box = null;
			this._child0 = null;
			this._child1 = null;
			this._objList = null;
		}
Ejemplo n.º 10
0
		/// <summary>
		/// Saves a node to a stream recursively
		/// </summary>
		/// <param name="node">Node to save</param>
		/// <param name="sw">Reference to BinaryWriter</param>
		private void SaveNode(QuadTreeOld node, ref System.IO.BinaryWriter sw)
		{
			//Write node boundingbox
			sw.Write(node.Box.MinX);
			sw.Write(node.Box.MinY);
			sw.Write(node.Box.MaxX);
			sw.Write(node.Box.MaxY);
			sw.Write(node.IsLeaf);
			if (node.IsLeaf)
			{
				sw.Write(node._objList.Count); //Write number of features at node
				for (int i = 0; i < node._objList.Count;i++ ) //Write each featurebox
				{
					sw.Write(node._objList[i].box.MinX);
					sw.Write(node._objList[i].box.MinY);
					sw.Write(node._objList[i].box.MaxX);
					sw.Write(node._objList[i].box.MaxY);
					sw.Write(node._objList[i].ID);
				}
			}
			else if (!node.IsLeaf) //Save next node
			{
				SaveNode(node.Child0, ref sw);
				SaveNode(node.Child1, ref sw);
			}
		}
Ejemplo n.º 11
0
		/// <summary>
		/// Reads a node from a stream recursively
		/// </summary>
		/// <param name="depth">Current depth</param>
		/// <param name="br">Binary reader reference</param>
		/// <returns></returns>
		private static QuadTreeOld ReadNode(uint depth, ref System.IO.BinaryReader br)
		{
			QuadTreeOld node = new QuadTreeOld();
			node._Depth = depth;
			node.Box = GeometryFactory.CreateEnvelope(br.ReadDouble(),br.ReadDouble(),br.ReadDouble(),br.ReadDouble());
			bool IsLeaf = br.ReadBoolean();
			if (IsLeaf)
			{
				int FeatureCount = br.ReadInt32();
				node._objList = new List<BoxObjects>();
				for (int i = 0; i < FeatureCount; i++)
				{
					BoxObjects box = new BoxObjects();
					box.box = GeometryFactory.CreateEnvelope(br.ReadDouble(), br.ReadDouble(), br.ReadDouble(), br.ReadDouble());
					box.ID = (uint)br.ReadInt32();
					node._objList.Add(box);
				}
			}
			else
			{
				node.Child0 = ReadNode(node._Depth + 1, ref br);
				node.Child1 = ReadNode(node._Depth + 1, ref br);
			}
			return node;
		}