Example #1
0
        public override Envelope GetExtents()
        {
            if (_cachedExtents != null)
                return new Envelope(_cachedExtents);

            Envelope box = null;

            if (_spatiaLiteIndex == SpatiaLiteIndex.RTree)
            {
                using (var conn = new SQLiteConnection(ConnectionString))
                {   
                    conn.Open();
                    var strSQL = string.Format("SELECT \"data\" FROM \"idx_{0}_{1}_node\" WHERE \"nodeno\"=1;", 
                                                _table, _geometryColumn);
                    
                    using (var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = strSQL;
                        var result = cmd.ExecuteScalar();
                        if (result != null && result != DBNull.Value)
                        {
                            var buffer = (byte[]) result;
                            var node = new RTreeNode(buffer);

                            _cachedExtents = float.IsNaN(node.XMin)
                                ? new Envelope()
                                : new Envelope(node.XMin, node.XMax, node.YMin, node.YMax);
                            return new Envelope(_cachedExtents);

                            //var entities = new float[2*_numOrdinateDimensions];
                            //var offset = 12;
                            //for (var i = 0; i < 2*_numOrdinateDimensions; i++)
                            //{
                            //    Array.Reverse(buffer, offset, 4);
                            //    entities[i] = BitConverter.ToSingle(buffer, offset);
                            //    offset += 4;
                            //}
                            //return new Envelope(entities[0], entities[2], entities[1], entities[3]);

                        }
                        throw new Exception();
                    }
                }
            }

            using (SQLiteConnection conn = SpatiaLiteConnection(ConnectionString))
            {
                //string strSQL = "SELECT Min(minx) AS MinX, Min(miny) AS MinY, Max(maxx) AS MaxX, Max(maxy) AS MaxY FROM " + this.Table;
                string strSQL;
                if (_spatiaLiteIndex == SpatiaLiteIndex.RTree && String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL = string.Format(
                        "SELECT MIN(xmin) AS minx, MAX(xmax) AS maxx, MIN(ymin) AS miny, MAX(ymax) AS maxy from {0};",
                        string.Format("idx_{0}_{1}", _table, _geometryColumn));
                }
                else
                {
                    strSQL = string.Format(
                        "SELECT MIN(MbrMinX({0})) AS minx, MIN(MbrMinY({0})) AS miny, MAX(MbrMaxX({0})) AS maxx, MAX(MbrMaxY({0})) AS maxy FROM {1};",
                        _geometryColumn, FromClause(_table));
                }

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    using (var dr = command.ExecuteReader())
                        if (dr.Read())
                        {
                            if (dr.IsDBNull(0))
                                return new Envelope(0,0,0,0);

                            box = new Envelope(
                                (double) dr["minx"], (double) dr["maxx"], 
                                (double) dr["miny"], (double) dr["maxy"]);
                        }
                    conn.Close();
                }
                _cachedExtents = box;
                return new Envelope(box);
            }
        }
Example #2
0
        public override Envelope GetExtents()
        {
            if (_cachedExtents != null)
            {
                return(new Envelope(_cachedExtents));
            }

            Envelope box = null;

            if (_spatiaLiteIndex == SpatiaLiteIndex.RTree)
            {
                using (var conn = GetConnection(ConnectionString))
                {
                    var strSQL = string.Format("SELECT \"data\" FROM \"idx_{0}_{1}_node\" WHERE \"nodeno\"=1;",
                                               _table, _geometryColumn);

                    using (var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = strSQL;
                        var result = cmd.ExecuteScalar();
                        if (result != null && result != DBNull.Value)
                        {
                            var buffer = (byte[])result;
                            var node   = new RTreeNode(buffer);
                            _cachedExtents = float.IsNaN(node.XMin)
                                ? new Envelope()
                                : new Envelope(node.XMin, node.XMax, node.YMin, node.YMax);
                            return(new Envelope(_cachedExtents));
                        }
                        throw new Exception();
                    }
                }
            }
            using (var conn = GetConnection(ConnectionString))
            {
                var strSQL = string.Format("SELECT \"{1}\" AS \"_smtmp_\" FROM \"{0}\"",
                                           _table, _geometryColumn);

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    using (var dr = command.ExecuteReader())
                    {
                        if (dr.HasRows)
                        {
                            double minx   = double.MaxValue,
                                   miny   = double.MaxValue,
                                   maxx   = double.MinValue,
                                   maxy   = double.MinValue;
                            var geoReader = new GaiaGeoReader(Factory.CoordinateSequenceFactory, Factory.PrecisionModel,
                                                              _ordinates);

                            while (dr.Read())
                            {
                                var geom = geoReader.Read((byte[])dr.GetValue(0));

                                var env = geom.EnvelopeInternal;
                                if (minx > env.MinX)
                                {
                                    minx = env.MinX;
                                }
                                if (miny > env.MinY)
                                {
                                    miny = env.MinY;
                                }
                                if (maxx < env.MaxX)
                                {
                                    maxx = env.MaxX;
                                }
                                if (maxy < env.MaxY)
                                {
                                    maxy = env.MaxY;
                                }

                                box = new Envelope(minx, maxx, miny, maxy);
                            }
                            dr.Close();
                        }
                        else
                        {
                            box = new Envelope();
                        }
                    }
                    conn.Close();
                }
                _cachedExtents = box;
                return(new Envelope(box));
            }
        }
Example #3
0
        public override Envelope GetExtents()
        {
            if (_cachedExtents != null)
                return new Envelope(_cachedExtents);

            Envelope box = null;

            if (_spatiaLiteIndex == SpatiaLiteIndex.RTree)
            {
                using (var conn = GetConnection(ConnectionString))
                {
                    var strSQL = string.Format("SELECT \"data\" FROM \"idx_{0}_{1}_node\" WHERE \"nodeno\"=1;",
                                                _table, _geometryColumn);

                    using (var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = strSQL;
                        var result = cmd.ExecuteScalar();
                        if (result != null && result != DBNull.Value)
                        {
                            var buffer = (byte[])result;
                            var node = new RTreeNode(buffer);
                            _cachedExtents = float.IsNaN(node.XMin) 
                                ? new Envelope() 
                                : new Envelope(node.XMin, node.XMax, node.YMin, node.YMax);
                            return new Envelope(_cachedExtents);
                        }
                        throw new Exception();
                    }
                }
            }
            using (var conn = GetConnection(ConnectionString))
            {
                var strSQL = string.Format("SELECT \"{1}\" AS \"_smtmp_\" FROM \"{0}\"",
                                           _table, _geometryColumn);

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    using (var dr = command.ExecuteReader())
                    {
                        if (dr.HasRows)
                        {
                            double minx = double.MaxValue,
                                   miny = double.MaxValue,
                                   maxx = double.MinValue,
                                   maxy = double.MinValue;
                            var geoReader = new GaiaGeoReader(Factory.CoordinateSequenceFactory, Factory.PrecisionModel,
                                                              _ordinates);

                            while (dr.Read())
                            {
                                var geom = geoReader.Read((byte[]) dr.GetValue(0));

                                var env = geom.EnvelopeInternal;
                                if (minx > env.MinX)
                                    minx = env.MinX;
                                if (miny > env.MinY)
                                    miny = env.MinY;
                                if (maxx < env.MaxX)
                                    maxx = env.MaxX;
                                if (maxy < env.MaxY)
                                    maxy = env.MaxY;

                                box = new Envelope(minx, maxx, miny, maxy);
                            }
                        }
                        else
                        {
                            box = new Envelope();
                        }
                        dr.Close();
                    }
                }
                conn.Close();
                _cachedExtents = box;
                return new Envelope(box);
            }
        }
Example #4
0
        /// <summary>
        /// Splits a node into two nodes.
        /// </summary>
        /// <param name="overflownNode">The overflown node.</param>
        /// <param name="firstNode">The first produced node.</param>
        /// <param name="secondNode">The second produced node.</param>
        protected override void SplitNode(RTreeNode overflownNode, out RTreeNode firstNode, out RTreeNode secondNode)
        {
            List <RTreeNode> alongChosenAxis = ChooseSplitAxis(overflownNode);

            Int32  minIndex   = MinChildren;
            Double minOverlap = ComputeOverlap(Envelope.FromEnvelopes(alongChosenAxis.GetRange(0, MinChildren).Select(x => x.Envelope)),
                                               Envelope.FromEnvelopes(alongChosenAxis.GetRange(MinChildren, alongChosenAxis.Count - MinChildren).Select(x => x.Envelope)));

            // ChooseSplitIndex

            for (Int32 i = MinChildren + 1; i <= MaxChildren - MinChildren + 1; i++)
            {
                Double actOverlap = ComputeOverlap(Envelope.FromEnvelopes(alongChosenAxis.GetRange(0, i).Select(x => x.Envelope)),
                                                   Envelope.FromEnvelopes(alongChosenAxis.GetRange(i, alongChosenAxis.Count - i).Select(x => x.Envelope)));
                if (minOverlap > actOverlap)
                {
                    minOverlap = actOverlap;
                    minIndex   = i;
                }
                else if (minOverlap == actOverlap)
                {
                    Double minArea = Envelope.FromEnvelopes(alongChosenAxis.GetRange(0, minIndex).Select(x => x.Envelope)).Surface +
                                     Envelope.FromEnvelopes(alongChosenAxis.GetRange(minIndex, alongChosenAxis.Count - minIndex).Select(x => x.Envelope)).Surface;

                    Double actArea = Envelope.FromEnvelopes(alongChosenAxis.GetRange(0, i).Select(x => x.Envelope)).Surface +
                                     Envelope.FromEnvelopes(alongChosenAxis.GetRange(i, alongChosenAxis.Count - i).Select(x => x.Envelope)).Surface;

                    if (minArea > actArea)
                    {
                        minIndex = i;
                    }
                }
            }

            firstNode  = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);
            secondNode = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);

            foreach (RTreeNode node in alongChosenAxis.GetRange(0, minIndex))
            {
                firstNode.AddChild(node);
            }

            foreach (RTreeNode node in alongChosenAxis.GetRange(minIndex, alongChosenAxis.Count - minIndex))
            {
                secondNode.AddChild(node);
            }
        }
Example #5
0
 internal RTreeNode(int maxKeysPerNode, RTreeNode parent)
 {
     Parent   = parent;
     Children = new List <RTreeNode>();
 }
Example #6
0
        /// <summary>
        /// Chooses seed elements for splitting a node using the linear cost algorithm.
        /// </summary>
        /// <param name="nodes">The nodes contained by the overflown node.</param>
        /// <param name="firstNode">The first seed node.</param>
        /// <param name="secondNode">The second seed node.</param>
        protected virtual void PickSeeds(IList <RTreeNode> nodes, out RTreeNode firstNode, out RTreeNode secondNode)
        {
            // the linear cost algorithm chooses the two points which are
            // the furthest away from each other considering the three axis

            RTreeNode highestLowX = nodes[0];
            RTreeNode highestLowY = nodes[0];
            RTreeNode highestLowZ = nodes[0];

            for (Int32 i = 1; i < nodes.Count; i++)
            {
                if (highestLowX.Envelope.MinX < nodes[i].Envelope.MinX)
                {
                    highestLowX = nodes[i];
                }
                if (highestLowY.Envelope.MinY < nodes[i].Envelope.MinY)
                {
                    highestLowY = nodes[i];
                }
                if (highestLowZ.Envelope.MinZ < nodes[i].Envelope.MinZ)
                {
                    highestLowZ = nodes[i];
                }
            }

            RTreeNode lowestHighX = nodes.FirstOrDefault(x => x != highestLowX);
            RTreeNode lowestHighY = nodes.FirstOrDefault(x => x != highestLowY);
            RTreeNode lowestHighZ = nodes.FirstOrDefault(x => x != highestLowZ);

            Double minX, minY, minZ;

            minX = minY = minZ = Double.MaxValue;

            Double maxX, maxY, maxZ;

            maxX = maxY = maxZ = Double.MinValue;

            foreach (RTreeNode node in nodes)
            {
                if (node.Envelope.MaxX < lowestHighX.Envelope.MaxX && node != highestLowX)
                {
                    lowestHighX = node;
                }

                if (node.Envelope.MaxY < lowestHighY.Envelope.MaxY && node != highestLowY)
                {
                    lowestHighY = node;
                }

                if (node.Envelope.MaxZ < lowestHighZ.Envelope.MaxZ && node != highestLowZ)
                {
                    lowestHighZ = node;
                }

                if (node.Envelope.MinX < minX)
                {
                    minX = node.Envelope.MinX;
                }
                if (node.Envelope.MaxX > maxX)
                {
                    maxX = node.Envelope.MaxX;
                }

                if (node.Envelope.MinY < minY)
                {
                    minY = node.Envelope.MinY;
                }
                if (node.Envelope.MaxY > maxY)
                {
                    maxY = node.Envelope.MaxY;
                }

                if (node.Envelope.MinZ < minZ)
                {
                    minZ = node.Envelope.MinZ;
                }
                if (node.Envelope.MaxZ > maxZ)
                {
                    maxZ = node.Envelope.MaxZ;
                }
            }

            Double normalizedDistanceX = (highestLowX.Envelope.MinX - lowestHighX.Envelope.MaxX) / (maxX - minX);
            Double normalizedDistanceY = (highestLowY.Envelope.MinY - lowestHighY.Envelope.MaxY) / (maxY - minY);


            if (normalizedDistanceX >= normalizedDistanceY)
            {
                firstNode  = lowestHighX;
                secondNode = highestLowX;
            }
            else
            {
                firstNode  = lowestHighY;
                secondNode = highestLowY;
            }

            if (!lowestHighZ.Envelope.IsPlanar || !highestLowZ.Envelope.IsPlanar)
            {
                Double normalizedDistanceZ = (highestLowZ.Envelope.MinZ - lowestHighZ.Envelope.MaxZ) / (maxZ - minZ);

                if ((firstNode == lowestHighX && normalizedDistanceZ > normalizedDistanceX) ||
                    (firstNode == lowestHighY && normalizedDistanceZ > normalizedDistanceX))
                {
                    firstNode  = lowestHighZ;
                    secondNode = highestLowZ;
                }
            }
        }
Example #7
0
 /// <summary>
 /// Adds a node into the tree on a specified height.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="height">The height where the node should be inserted.</param>
 protected override void AddNode(RTreeNode node, Int32 height = -1)
 {
     _visitedLevels = new Boolean[Height];
     InsertInSpecifiedHeight(node, height, height);
 }
Example #8
0
        /// <summary>
        /// Splits a node into two nodes.
        /// </summary>
        /// <param name="overflownNode">The overflown node.</param>
        /// <param name="firstNode">The first produced node.</param>
        /// <param name="secondNode">The second produced node.</param>
        protected virtual void SplitNode(RTreeNode overflownNode, out RTreeNode firstNode, out RTreeNode secondNode)
        {
            RTreeNode firstSeed, secondSeed;

            PickSeeds(overflownNode.Children, out firstSeed, out secondSeed);

            firstNode  = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);
            secondNode = (overflownNode.Parent != null) ? new RTreeNode(overflownNode.Parent) : new RTreeNode(overflownNode.MaxChildren);

            firstNode.AddChild(firstSeed);
            secondNode.AddChild(secondSeed);

            overflownNode.Children.Remove(firstSeed);
            overflownNode.Children.Remove(secondSeed);

            while (overflownNode.ChildrenCount > 0)
            {
                RTreeNode node = PickNext(overflownNode.Children);

                if (firstNode.ChildrenCount + overflownNode.ChildrenCount <= MinChildren)
                {
                    firstNode.AddChild(node);
                }
                else if (secondNode.ChildrenCount + overflownNode.ChildrenCount <= MinChildren)
                {
                    secondNode.AddChild(node);
                }
                else
                {
                    Double firstEnlargement  = firstNode.ComputeEnlargement(node.Envelope);
                    Double secondEnlargement = secondNode.ComputeEnlargement(node.Envelope);

                    if (firstEnlargement < secondEnlargement)
                    {
                        firstNode.AddChild(node);
                    }
                    else if (firstEnlargement > secondEnlargement)
                    {
                        secondNode.AddChild(node);
                    }
                    else
                    {
                        if (firstNode.Envelope.Surface < secondNode.Envelope.Surface)
                        {
                            firstNode.AddChild(node);
                        }
                        else
                        {
                            secondNode.AddChild(node);
                        }
                    }
                }
            }
        }
Example #9
0
 /// <summary>
 /// Clears all geometries from the index.
 /// </summary>
 public void Clear()
 {
     _root               = new RTreeNode(_root.MaxChildren);
     _height             = 0;
     _numberOfGeometries = 0;
 }
Example #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RTreeNode" /> class.
 /// </summary>
 /// <param name="parent">The parent of the node.</param>
 /// <param name="geometry">The <see cref="IGeometry" /> contained by the node.</param>
 public RTreeNode(IGeometry geometry, RTreeNode parent = null)
     : this(parent)
 {
     Geometry = geometry;
 }
Example #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RTreeNode" /> class.
 /// </summary>
 /// <param name="parent">The parent of the node.</param>
 public RTreeNode(RTreeNode parent)
 {
     Parent = parent;
 }
Example #12
0
        public override Envelope GetExtents()
        {
            if (_cachedExtents != null)
            {
                return(new Envelope(_cachedExtents));
            }

            Envelope box = null;

            if (_spatiaLiteIndex == SpatiaLiteIndex.RTree)
            {
                using (var conn = new SQLiteConnection(ConnectionString))
                {
                    conn.Open();
                    var strSQL = string.Format("SELECT \"data\" FROM \"idx_{0}_{1}_node\" WHERE \"nodeno\"=1;",
                                               _table, _geometryColumn);

                    using (var cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = strSQL;
                        var result = cmd.ExecuteScalar();
                        if (result != null && result != DBNull.Value)
                        {
                            var buffer = (byte[])result;
                            var node   = new RTreeNode(buffer);

                            _cachedExtents = float.IsNaN(node.XMin)
                                ? new Envelope()
                                : new Envelope(node.XMin, node.XMax, node.YMin, node.YMax);
                            return(new Envelope(_cachedExtents));

                            //var entities = new float[2*_numOrdinateDimensions];
                            //var offset = 12;
                            //for (var i = 0; i < 2*_numOrdinateDimensions; i++)
                            //{
                            //    Array.Reverse(buffer, offset, 4);
                            //    entities[i] = BitConverter.ToSingle(buffer, offset);
                            //    offset += 4;
                            //}
                            //return new Envelope(entities[0], entities[2], entities[1], entities[3]);
                        }
                        throw new Exception();
                    }
                }
            }

            using (SQLiteConnection conn = SpatiaLiteConnection(ConnectionString))
            {
                //string strSQL = "SELECT Min(minx) AS MinX, Min(miny) AS MinY, Max(maxx) AS MaxX, Max(maxy) AS MaxY FROM " + this.Table;
                string strSQL;
                if (_spatiaLiteIndex == SpatiaLiteIndex.RTree && String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL = string.Format(
                        "SELECT MIN(xmin) AS minx, MAX(xmax) AS maxx, MIN(ymin) AS miny, MAX(ymax) AS maxy from {0};",
                        string.Format("idx_{0}_{1}", _table, _geometryColumn));
                }
                else
                {
                    strSQL = string.Format(
                        "SELECT MIN(MbrMinX({0})) AS minx, MIN(MbrMinY({0})) AS miny, MAX(MbrMaxX({0})) AS maxx, MAX(MbrMaxY({0})) AS maxy FROM {1};",
                        _geometryColumn, FromClause(_table));
                }

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    using (var dr = command.ExecuteReader())
                        if (dr.Read())
                        {
                            if (dr.IsDBNull(0))
                            {
                                return(new Envelope(0, 0, 0, 0));
                            }

                            box = new Envelope(
                                (double)dr["minx"], (double)dr["maxx"],
                                (double)dr["miny"], (double)dr["maxy"]);
                        }
                    conn.Close();
                }
                _cachedExtents = box;
                return(new Envelope(box));
            }
        }