예제 #1
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Tests to see whether <B>h</B> is inside this HyperCube.
         * If <B>h</B> is exactly the same shape as this object, it is considered
         * to be inside.
         *
         * @return True if <B>h</B> is inside, false otherwise.
         */
        public bool Enclosure(HyperCube h)
        {
            if (h == null)
            {
                throw new
                      ArgumentException("HyperCube cannot be null.");
            }

            if (h.GetDimension() != GetDimension())
            {
                throw new
                      ArgumentException
                          ("HyperCube dimension is different from current dimension.");
            }

            bool inside = true;

            for (int i = 0; i < GetDimension(); i++)
            {
                if (_p1.GetFloatCoordinate(i) > h._p1.GetFloatCoordinate(i) ||
                    _p2.GetFloatCoordinate(i) < h._p2.GetFloatCoordinate(i))
                {
                    inside = false;
                    break;
                }
            }

            return(inside);
        }
예제 #2
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Return a new HyperCube representing the mbb of the Union of this
         * HyperCube and <B>h</B>
         *
         * @param  h The HyperCube that we want to Union with this HyperCube.
         * @return  A HyperCube representing the mbb of their Union.
         */
        public HyperCube GetUnionMbb(HyperCube h)
        {
            if (h == null)
            {
                throw new
                      ArgumentException("HyperCube cannot be null.");
            }

            if (h.GetDimension() != GetDimension())
            {
                throw new
                      ArgumentException
                          ("HyperCubes must be of the same dimension.");
            }

            double[] min = new double[GetDimension()];
            double[] max = new double[GetDimension()];

            for (int i = 0; i < GetDimension(); i++)
            {
                min[i] = Math.Min(_p1.GetFloatCoordinate(i),
                                  h._p1.GetFloatCoordinate(i));
                max[i] = Math.Max(_p2.GetFloatCoordinate(i),
                                  h._p2.GetFloatCoordinate(i));
            }

            return(new HyperCube(new Point(min), new Point(max)));
        }
예제 #3
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * chooseLeaf finds the most appropriate leaf where the given HyperCube
         * should be stored.
         *
         * @param h The new HyperCube.
         *
         * @return The leaf where the new HyperCube should be inserted.
         */
        internal override Leaf ChooseLeaf(HyperCube h)
        {
            int i;

            switch (Tree.GetTreeType())
            {
            case RTree.RTREE_LINEAR:
            case RTree.RTREE_QUADRATIC:
            case RTree.RTREE_EXPONENTIAL:
                i = FindLeastEnlargement(h);
                break;

            case RTree.RSTAR:
                if (Level == 1)
                {
                    // if this node points to leaves...
                    i = FindLeastOverlap(h);
                }
                else
                {
                    i = FindLeastEnlargement(h);
                }
                break;

            default:
                throw new Exception("Invalid tree type.");
            }

            return(GetChild(i).ChooseLeaf(h));
        }
예제 #4
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Equals.
         */
        public bool Equals(HyperCube h)
        {
            if (_p1.Equals(h.GetP1()) && _p2.Equals(h.GetP2()))
            {
                return(true);
            }
            return(false);
        }
예제 #5
0
 public ContainEnum(HyperCube hh, RTree tree)
 {
     _cubes = tree.Enclosure(hh, tree._file.ReadNode(0));
     if (_cubes.Count == 0)
     {
         _hasNext = false;
     }
 }
예제 #6
0
 public IntersectionEnum(HyperCube hh, RTree tree)
 {
     _nodes = tree.Intersection(hh, tree._file.ReadNode(0));
     if (_nodes.Count == 0)
     {
         _hasNext = false;
     }
 }
예제 #7
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Return a copy of the HyperCubes present in this node.
         * @return An array of HyperCubes containing copies of the original data.
         */
        public HyperCube[] GetHyperCubes()
        {
            HyperCube[] h = new HyperCube[UsedSpace];

            for (int i = 0; i < UsedSpace; i++)
            {
                h[i] = (HyperCube)Data[i].Clone();
            }

            return(h);
        }
예제 #8
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Returns the mbb of all HyperCubes present in this node.
         *
         * @return A new HyperCube object, representing the mbb of this node.
         */
        public HyperCube GetNodeMbb()
        {
            if (UsedSpace > 0)
            {
                HyperCube[] h = new HyperCube[UsedSpace];
                Array.Copy(Data, 0, h, 0, UsedSpace);
                return(HyperCube.GetUnionMbb(h));
            }
            return(new HyperCube(new Point(new double[] { 0, 0 }),
                                 new Point(new double[] { 0, 0 })));
        }
예제 #9
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Returns the area of the intersecting region between this HyperCube and
         * the argument.
         *
         * Below, all possible situations are depicted.
         *
         *     -------   -------      ---------   ---------      ------         ------
         *    |2      | |2      |    |2        | |1        |    |2     |       |1     |
         *  --|--     | |     --|--  | ------  | | ------  |  --|------|--   --|------|--
         * |1 |  |    | |    |1 |  | ||1     | | ||2     | | |1 |      |  | |2 |      |  |
         *  --|--     | |     --|--  | ------  | | ------  |  --|------|--   --|------|--
         *     -------   -------      ---------   ---------      ------         ------
         *
         * @param h Given HyperCube.
         * @return Area of intersecting region.
         */
        public double IntersectingArea(HyperCube h)
        {
            if (!Intersection(h))
            {
                return(0);
            }
            double ret = 1;

            for (int i = 0; i < GetDimension(); i++)
            {
                double l1 = _p1.GetFloatCoordinate(i);
                double h1 = _p2.GetFloatCoordinate(i);
                double l2 = h._p1.GetFloatCoordinate(i);
                double h2 = h._p2.GetFloatCoordinate(i);

                if (l1 <= l2 && h1 <= h2)
                {
                    // cube1 left of cube2.
                    ret *= (h1 - l1) - (l2 - l1);
                }
                else if (l2 <= l1 && h2 <= h1)
                {
                    // cube1 right of cube2.
                    ret *= (h2 - l2) - (l1 - l2);
                }
                else if (l2 <= l1 && h1 <= h2)
                {
                    // cube1 inside cube2.
                    ret *= h1 - l1;
                }
                else if (l1 <= l2 && h2 <= h1)
                {
                    // cube1 Contains cube2.
                    ret *= h2 - l2;
                }
                else if (l1 <= l2 && h2 <= h1)
                {
                    // cube1 crosses cube2.
                    ret *= h2 - l2;
                }
                else if (l2 <= l1 && h1 <= h2)
                {
                    // cube1 crossed by cube2.
                    ret *= h1 - l1;
                }
            }
            if (ret <= 0)
            {
                throw new
                      ArithmeticException("Intersecting area cannot be negative!");
            }
            return(ret);
        }
예제 #10
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * findLeaf.
         */
        internal override Leaf FindLeaf(HyperCube h)
        {
            for (int i = 0; i < UsedSpace; i++)
            {
                if (Data[i].Enclosure(h))
                {
                    return(this);
                }
            }

            return(null);
        }
예제 #11
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * findLeaf returns the leaf that Contains the given hypercube, null if the
         * hypercube is not contained in any of the leaves of this node.
         * @param h The HyperCube to search for.
         * @return The leaf where the HyperCube is contained, null if such a leaf
         * is not found.
         */
        internal override Leaf FindLeaf(HyperCube h)
        {
            for (int i = 0; i < UsedSpace; i++)
            {
                if (Data[i].Enclosure(h))
                {
                    Leaf l = GetChild(i).FindLeaf(h);
                    if (l != null)
                    {
                        return(l);
                    }
                }
            }

            return(null);
        }
예제 #12
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Static impementation. Takes an array of HyperCubes and calculates the
         * mbb of their Union.
         *
         * @param  a The array of HyperCubes.
         * @return The mbb of their Union.
         */
        public static HyperCube GetUnionMbb(HyperCube[] a)
        {
            if (a == null || a.Length == 0)
            {
                throw new
                      ArgumentException("HyperCube array is empty.");
            }

            HyperCube h = (HyperCube)a[0].Clone();

            for (int i = 1; i < a.Length; i++)
            {
                h = h.GetUnionMbb(a[i]);
            }

            return(h);
        }
예제 #13
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Add the new HyperCube to all mbbs present in this node. Calculate the
         * area difference and choose the entry with the least enlargement. Based
         * on that metric we choose the path that leads to the leaf that will
         * hold the new HyperCube.
         * [A. Guttman 'R-trees a dynamic index structure for spatial searching']
         *
         * @return The index of the branch of the path that leads to the Leaf where
         * the new HyperCube should be inserted.
         */
        private int FindLeastEnlargement(HyperCube h)
        {
            double area = Double.PositiveInfinity;
            int    sel  = -1;

            for (int i = 0; i < UsedSpace; i++)
            {
                double enl = Data[i].GetUnionMbb(h).GetArea() - Data[i].GetArea();
                if (enl < area)
                {
                    area = enl;
                    sel  = i;
                }
                else if (enl == area)
                {
                    sel = (Data[sel].GetArea() <= Data[i].GetArea()) ? sel : i;
                }
            }
            return(sel);
        }
예제 #14
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * Returns a ArrayList with all Hypercubes that completely contain HyperCube
         * <B>h</B>.
         * The HyperCubes are returned in post order traversing, according to the
         * Nodes where they belong.
         *
         * @param h The given HyperCube.
         * @param root The node where the search should begin.
         * @return A ArrayList containing the appropriate HyperCubes in the correct
         * order.
         */
        public ArrayList Enclosure(HyperCube h, AbstractNode root)
        {
            if (h == null || root == null)
            {
                throw new
                      ArgumentException("Arguments cannot be null.");
            }

            if (h.GetDimension() != _file.Dimension)
            {
                throw new
                      ArgumentException("HyperCube dimension " +
                                        "different than RTree dimension.");
            }

            ArrayList v = new ArrayList();

            if (root.GetNodeMbb().Enclosure(h))
            {
                v.Add(root);

                if (!root.IsLeaf())
                {
                    for (int i = 0; i < root.UsedSpace; i++)
                    {
                        if (root.Data[i].Enclosure(h))
                        {
                            ArrayList a = Enclosure(h, ((Index)root).GetChild(i));
                            for (int j = 0; j < a.Count; j++)
                            {
                                v.Add(a[j]);
                            }
                        }
                    }
                }
            }
            return(v);
        }
예제 #15
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * R*-tree criterion for choosing the best branch to follow.
         * [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and
         * Robust Access Method for Points and Rectangles]
         *
         * @return The index of the branch of the path that leads to the Leaf where
         * the new HyperCube should be inserted.
         */
        private int FindLeastOverlap(HyperCube h)
        {
            float overlap = float.PositiveInfinity;
            int   sel     = -1;

            for (int i = 0; i < UsedSpace; i++)
            {
                AbstractNode n = GetChild(i);
                float        o = 0;
                for (int j = 0; j < n.Data.Length; j++)
                {
                    o += (float)h.IntersectingArea(n.Data[j]);
                }
                if (o < overlap)
                {
                    overlap = o;
                    sel     = i;
                }
                else if (o == overlap)
                {
                    double area1 = Data[i].GetUnionMbb(h).GetArea()
                                   - Data[i].GetArea();
                    double area2 = Data[sel].GetUnionMbb(h).GetArea()
                                   - Data[sel].GetArea();

                    if (area1 == area2)
                    {
                        sel = (Data[sel].GetArea() <= Data[i].GetArea()) ? sel : i;
                    }
                    else
                    {
                        sel = (area1 < area2) ? i : sel;
                    }
                }
            }
            return(sel);
        }
예제 #16
0
        ////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS --------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ------------------
        // 21JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////

        /**
         * Returns an Enumeration with all nodes present in the tree that Intersect with the given
         * HyperCube. The nodes are returned in post order traversing
         *
         * @param h The given HyperCube that is tested for overlapping.
         * @return An Enumeration containing the appropriate nodes in the correct order.
         */
        public IEnumeration Intersection(HyperCube h)
        {
            return(new IntersectionEnum(h, this));
        }
예제 #17
0
        ////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS --------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ------------------
        // 21JUN2009  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////

        /**
         * Returns an Enumeration with all Hypercubes present in the tree that contain the given
         * HyperCube. The HyperCubes are returned in post order traversing, according to the Nodes where
         * they belong.
         *
         * @param h The given HyperCube.
         * @param root The node where the search should begin.
         * @return An Enumeration containing the appropriate HyperCubes in the correct order.
         */
        public IEnumeration Enclosure(HyperCube h)
        {
            return(new ContainEnum(h, this));
        }
예제 #18
0
 public IntersectionEnum(HyperCube hh, RTree tree)
 {
     _nodes = tree.Intersection(hh, tree._file.ReadNode(0));
     if (_nodes.Count == 0)
     {
         _hasNext = false;
     }
 }
예제 #19
0
 public ContainEnum(HyperCube hh, RTree tree)
 {
     _cubes = tree.Enclosure(hh, tree._file.ReadNode(0));
     if (_cubes.Count == 0)
     {
         _hasNext = false;
     }
 }
예제 #20
0
 ////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS --------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ------------------
 // 21JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////
 /**
 * Returns an Enumeration with all nodes present in the tree that Intersect with the given
 * HyperCube. The nodes are returned in post order traversing
 *
 * @param h The given HyperCube that is tested for overlapping.
 * @return An Enumeration containing the appropriate nodes in the correct order.
 */
 public IEnumeration Intersection(HyperCube h)
 {
     return new IntersectionEnum(h, this);
 }
예제 #21
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Returns a ArrayList with all nodes that Intersect with the given HyperCube.
         * The nodes are returned in post order traversing
         *
         * @param h The given HyperCube that is tested for overlapping.
         * @param root The node where the search should begin.
         * @return A ArrayList containing the appropriate nodes in the correct order.
         */
        public ArrayList Intersection(HyperCube h, AbstractNode root)
        {
            if (h == null || root == null)
            {
                throw new ArgumentException("Arguments cannot be null.");
            }

            if (h.GetDimension() != _file.Dimension)
            {
                throw new ArgumentException
                        ("HyperCube dimension different than RTree dimension.");
            }

            ArrayList v = new ArrayList();

            if (root.GetNodeMbb().Intersection(h))
            {
                v.Add(root);

                if (!root.IsLeaf())
                {
                    for (int i = 0; i < root.UsedSpace; i++)
                    {
                        if (root.Data[i].Intersection(h))
                        {
                            ArrayList a = Intersection(h, ((Index)root).GetChild(i));
                            for (int j = 0; j < a.Count; j++)
                            {
                                v.Add(a[j]);
                            }
                        }
                    }
                }
            }
            return v;
        }
예제 #22
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         *
         * Tests to see whether <B>h</B> has any common points with this HyperCube.
         * If <B>h</B> is inside this object (or vice versa), it returns true.
         *
         * @return True if <B>h</B> and this HyperCube Intersect, false otherwise.
         */
        public bool Intersection(HyperCube h)
        {
            if (h == null) throw new
                    ArgumentException("HyperCube cannot be null.");

            if (h.GetDimension() != GetDimension()) throw new
                      ArgumentException
                    ("HyperCube dimension is different from current dimension.");

            bool intersect = true;
            for (int i = 0; i < GetDimension(); i++)
            {
                if (_p1.GetFloatCoordinate(i) > h._p2.GetFloatCoordinate(i) ||
                        _p2.GetFloatCoordinate(i) < h._p1.GetFloatCoordinate(i))
                {
                    intersect = false;
                    break;
                }
            }
            return intersect;
        }
예제 #23
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * R*-tree criterion for choosing the best branch to follow.
         * [Beckmann, Kriegel, Schneider, Seeger 'The R*-tree: An efficient and
         * Robust Access Method for Points and Rectangles]
         *
         * @return The index of the branch of the path that leads to the Leaf where
         * the new HyperCube should be inserted.
         */
        private int FindLeastOverlap(HyperCube h)
        {
            float overlap = float.PositiveInfinity;
            int sel = -1;

            for (int i = 0; i < UsedSpace; i++) {
            AbstractNode n = GetChild(i);
            float o = 0;
            for (int j = 0; j < n.Data.Length; j++) {
                o += (float)h.IntersectingArea(n.Data[j]);
            }
            if (o < overlap) {
                overlap = o;
                sel = i;
            } else if (o == overlap) {
                double area1 = Data[i].GetUnionMbb(h).GetArea()
                    - Data[i].GetArea();
                double area2 = Data[sel].GetUnionMbb(h).GetArea()
                    - Data[sel].GetArea();

                if (area1 == area2) {
                    sel = (Data[sel].GetArea() <= Data[i].GetArea()) ? sel : i;
                } else {
                    sel = (area1 < area2) ? i : sel;
                }
            }
            }
            return sel;
        }
예제 #24
0
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 21DEC2008  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Returns the mbb of all HyperCubes present in this node.
  *
  * @return A new HyperCube object, representing the mbb of this node.
  */
 public HyperCube GetNodeMbb()
 {
     if (UsedSpace > 0)
     {
         HyperCube[] h = new HyperCube[UsedSpace];
         Array.Copy(Data, 0, h, 0, UsedSpace);
         return HyperCube.GetUnionMbb(h);
     }
     return new HyperCube(new Point(new double[] { 0, 0 }),
                          new Point(new double[] { 0, 0 }));
 }
예제 #25
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * findLeaf returns the leaf that Contains the given hypercube, null if the
         * hypercube is not contained in any of the leaves of this node.
         * @param h The HyperCube to search for.
         * @return The leaf where the HyperCube is contained, null if such a leaf
         * is not found.
         */
        internal override Leaf FindLeaf(HyperCube h)
        {
            for (int i = 0; i < UsedSpace; i++) {
            if (Data[i].Enclosure(h)) {
                Leaf l = GetChild(i).FindLeaf(h);
                if (l != null) {
                    return l;
                }
            }
            }

            return null;
        }
예제 #26
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * findLeaf returns the leaf that Contains the given hypercube, null if the
         * hypercube is not contained in any of the leaves of this node.
         *
         * @param h The HyperCube to search for.
         *
         * @return The leaf where the HyperCube is contained, null if such a leaf is not found.
         */
        internal abstract Leaf FindLeaf(HyperCube h);
예제 #27
0
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 21DEC2008  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * findLeaf returns the leaf that Contains the given hypercube, null if the
  * hypercube is not contained in any of the leaves of this node.
  *
  * @param h The HyperCube to search for.
  *
  * @return The leaf where the HyperCube is contained, null if such a leaf is not found.
  */
 internal abstract Leaf FindLeaf(HyperCube h);
예제 #28
0
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 21DEC2008  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * chooseLeaf finds the most appropriate leaf where the given HyperCube
  * should be stored.
  *
  * @param h The new HyperCube.
  *
  * @return The leaf where the new HyperCube should be inserted.
  */
 internal abstract Leaf ChooseLeaf(HyperCube h);
예제 #29
0
 ////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS --------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ------------------
 // 21JUN2009  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////
 /**
 * Returns an Enumeration with all Hypercubes present in the tree that contain the given
 * HyperCube. The HyperCubes are returned in post order traversing, according to the Nodes where
 * they belong.
 *
 * @param h The given HyperCube.
 * @param root The node where the search should begin.
 * @return An Enumeration containing the appropriate HyperCubes in the correct order.
 */
 public IEnumeration Enclosure(HyperCube h)
 {
     return new ContainEnum(h, this);
 }
예제 #30
0
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 21DEC2008  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * chooseLeaf.
  */
 internal override Leaf ChooseLeaf(HyperCube h)
 {
     return this;
 }
예제 #31
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * chooseLeaf.
         */
        internal override Leaf ChooseLeaf(HyperCube h)
        {
            return(this);
        }
예제 #32
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * findLeaf.
         */
        internal override Leaf FindLeaf(HyperCube h)
        {
            for (int i = 0; i < UsedSpace; i++)
            {
                if (Data[i].Enclosure(h))
                {
                    return this;
                }
            }

            return null;
        }
예제 #33
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Static impementation. Takes an array of HyperCubes and calculates the
         * mbb of their Union.
         *
         * @param  a The array of HyperCubes.
         * @return The mbb of their Union.
         */
        public static HyperCube GetUnionMbb(HyperCube[] a)
        {
            if (a == null || a.Length == 0) throw new
                    ArgumentException("HyperCube array is empty.");

            HyperCube h = (HyperCube)a[0].Clone();

            for (int i = 1; i < a.Length; i++)
            {
                h = h.GetUnionMbb(a[i]);
            }

            return h;
        }
예제 #34
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                              Initial Creation
        ////////////////////////////////////////////////////////////////////////////

        /**
         * chooseLeaf finds the most appropriate leaf where the given HyperCube
         * should be stored.
         *
         * @param h The new HyperCube.
         *
         * @return The leaf where the new HyperCube should be inserted.
         */
        internal abstract Leaf ChooseLeaf(HyperCube h);
예제 #35
0
 ////////////////////////////////////////////////////////////////////////////
 //--------------------------------- REVISIONS ------------------------------
 // Date       Name                 Tracking #         Description
 // ---------  -------------------  -------------      ----------------------
 // 21DEC2008  James Shen                 	          Initial Creation
 ////////////////////////////////////////////////////////////////////////////
 /**
  * Equals.
  */
 public bool Equals(HyperCube h)
 {
     if (_p1.Equals(h.GetP1()) && _p2.Equals(h.GetP2()))
     {
         return true;
     }
     return false;
 }
예제 #36
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * get all records based on given rectangle.
         * @param rectGeo the boundary..
         * @return a hashtable of all matched record.the key is the mapInfo ID.
         */
        public Hashtable SearchMapObjectsInRect(GeoLatLngBounds rectGeo)
        {
            Point pt1, pt2;
            pt1 = new Point(new[]{
                    (int) (rectGeo.X * DOUBLE_PRECISION+0.5),
                    (int) (rectGeo.Y * DOUBLE_PRECISION+0.5)});
            pt2 = new Point(new int[]{
                    (int) ((rectGeo.X + rectGeo.Width) * DOUBLE_PRECISION+0.5),
                    (int) ((rectGeo.Y + rectGeo.Height) * DOUBLE_PRECISION+0.5)});
            HyperCube h1 = new HyperCube(pt1, pt2);
            Hashtable retArrayList = new Hashtable();
            Point p11, p12;
            for (IEnumeration e1 = _tree.Intersection(h1); e1.HasMoreElements(); )
            {

                AbstractNode node = (AbstractNode)(e1.NextElement());
                if (node.IsLeaf())
                {
                    int index = 0;
                    HyperCube[] data = node.GetHyperCubes();
                    HyperCube cube;
                    for (int cubeIndex = 0; cubeIndex < data.Length; cubeIndex++)
                    {
                        cube = data[cubeIndex];
                        if (cube.Intersection(h1))
                        {
                            p11 = cube.GetP1();
                            p12 = cube.GetP2();
                            int mapinfoId = ((Leaf)node).GetDataPointer(index);
                            int mapInfoId = mapinfoId;
                            GeoLatLngBounds mbr = new GeoLatLngBounds();
                            mbr.X = p11.GetFloatCoordinate(0) / DOUBLE_PRECISION;
                            mbr.Y = p11.GetFloatCoordinate(1) / DOUBLE_PRECISION;
                            mbr.Width = ((p12.GetFloatCoordinate(0) - p11.GetFloatCoordinate(0))) / DOUBLE_PRECISION;
                            mbr.Height = ((p12.GetFloatCoordinate(1) - p11.GetFloatCoordinate(1))) / DOUBLE_PRECISION;
                            if (!retArrayList.Contains(mapInfoId))
                            {
                                retArrayList.Add(mapInfoId, mbr);
                            }

                        }
                        index++;

                    }
                }
            }
            return retArrayList;
        }
예제 #37
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Return a new HyperCube representing the mbb of the Union of this
         * HyperCube and <B>h</B>
         *
         * @param  h The HyperCube that we want to Union with this HyperCube.
         * @return  A HyperCube representing the mbb of their Union.
         */
        public HyperCube GetUnionMbb(HyperCube h)
        {
            if (h == null) throw new
                    ArgumentException("HyperCube cannot be null.");

            if (h.GetDimension() != GetDimension()) throw new
                    ArgumentException
                    ("HyperCubes must be of the same dimension.");

            double[] min = new double[GetDimension()];
            double[] max = new double[GetDimension()];

            for (int i = 0; i < GetDimension(); i++)
            {
                min[i] = Math.Min(_p1.GetFloatCoordinate(i),
                        h._p1.GetFloatCoordinate(i));
                max[i] = Math.Max(_p2.GetFloatCoordinate(i),
                        h._p2.GetFloatCoordinate(i));
            }

            return new HyperCube(new Point(min), new Point(max));
        }
예제 #38
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Add the new HyperCube to all mbbs present in this node. Calculate the
         * area difference and choose the entry with the least enlargement. Based
         * on that metric we choose the path that leads to the leaf that will
         * hold the new HyperCube.
         * [A. Guttman 'R-trees a dynamic index structure for spatial searching']
         *
         * @return The index of the branch of the path that leads to the Leaf where
         * the new HyperCube should be inserted.
         */
        private int FindLeastEnlargement(HyperCube h)
        {
            double area = Double.PositiveInfinity;
            int sel = -1;

            for (int i = 0; i < UsedSpace; i++) {
            double enl = Data[i].GetUnionMbb(h).GetArea() - Data[i].GetArea();
            if (enl < area) {
                area = enl;
                sel = i;
            } else if (enl == area) {
                sel = (Data[sel].GetArea() <= Data[i].GetArea()) ? sel : i;
            }
            }
            return sel;
        }
예제 #39
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Returns the area of the intersecting region between this HyperCube and
         * the argument.
         *
         * Below, all possible situations are depicted.
         *
         *     -------   -------      ---------   ---------      ------         ------
         *    |2      | |2      |    |2        | |1        |    |2     |       |1     |
         *  --|--     | |     --|--  | ------  | | ------  |  --|------|--   --|------|--
         * |1 |  |    | |    |1 |  | ||1     | | ||2     | | |1 |      |  | |2 |      |  |
         *  --|--     | |     --|--  | ------  | | ------  |  --|------|--   --|------|--
         *     -------   -------      ---------   ---------      ------         ------
         *
         * @param h Given HyperCube.
         * @return Area of intersecting region.
         */
        public double IntersectingArea(HyperCube h)
        {
            if (!Intersection(h))
            {
                return 0;
            }
            double ret = 1;
            for (int i = 0; i < GetDimension(); i++)
            {
                double l1 = _p1.GetFloatCoordinate(i);
                double h1 = _p2.GetFloatCoordinate(i);
                double l2 = h._p1.GetFloatCoordinate(i);
                double h2 = h._p2.GetFloatCoordinate(i);

                if (l1 <= l2 && h1 <= h2)
                {
                    // cube1 left of cube2.
                    ret *= (h1 - l1) - (l2 - l1);
                }
                else if (l2 <= l1 && h2 <= h1)
                {
                    // cube1 right of cube2.
                    ret *= (h2 - l2) - (l1 - l2);
                }
                else if (l2 <= l1 && h1 <= h2)
                {
                    // cube1 inside cube2.
                    ret *= h1 - l1;
                }
                else if (l1 <= l2 && h2 <= h1)
                {
                    // cube1 Contains cube2.
                    ret *= h2 - l2;
                }
                else if (l1 <= l2 && h2 <= h1)
                {
                    // cube1 crosses cube2.
                    ret *= h2 - l2;
                }
                else if (l2 <= l1 && h1 <= h2)
                {
                    // cube1 crossed by cube2.
                    ret *= h1 - l1;
                }
            }
            if (ret <= 0) throw new
                ArithmeticException("Intersecting area cannot be negative!");
            return ret;
        }
예제 #40
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * chooseLeaf finds the most appropriate leaf where the given HyperCube
         * should be stored.
         *
         * @param h The new HyperCube.
         *
         * @return The leaf where the new HyperCube should be inserted.
         */
        internal override Leaf ChooseLeaf(HyperCube h)
        {
            int i;

            switch (Tree.GetTreeType()) {
            case RTree.RTREE_LINEAR:
            case RTree.RTREE_QUADRATIC:
            case RTree.RTREE_EXPONENTIAL:
                i = FindLeastEnlargement(h);
                break;
            case RTree.RSTAR:
                if (Level == 1) {
                    // if this node points to leaves...
                    i = FindLeastOverlap(h);
                } else {
                    i = FindLeastEnlargement(h);
                }
                break;
            default:
                throw new Exception("Invalid tree type.");
            }

            return GetChild(i).ChooseLeaf(h);
        }
예제 #41
0
        ////////////////////////////////////////////////////////////////////////////
        //--------------------------------- REVISIONS ------------------------------
        // Date       Name                 Tracking #         Description
        // ---------  -------------------  -------------      ----------------------
        // 21DEC2008  James Shen                 	          Initial Creation
        ////////////////////////////////////////////////////////////////////////////
        /**
         * Return a copy of the HyperCubes present in this node.
         * @return An array of HyperCubes containing copies of the original data.
         */
        public HyperCube[] GetHyperCubes()
        {
            HyperCube[] h = new HyperCube[UsedSpace];

            for (int i = 0; i < UsedSpace; i++)
            {
                h[i] = (HyperCube)Data[i].Clone();
            }

            return h;
        }