Пример #1
0
            private SbnFeature[] ReadBins(int nid, SbnBinIndex binIndex)
            {
                var numFeatures = binIndex.GetNumFeatures(nid);
                var res         = new SbnFeature[numFeatures];

                if (numFeatures == 0)
                {
                    return(res);
                }

                var firstBinIndex = binIndex.GetFirstBinIndex(nid);
                var numBins       = (int)Math.Ceiling(numFeatures / 100d);

                for (var i = 0; i < numBins; i++)
                {
                    using (var ms = new BinaryReader(new MemoryStream(_tree.GetBinData(firstBinIndex + i))))
                    {
                        var bin   = new SbnBin();
                        var binId = bin.Read(ms);
                        if (binId != firstBinIndex + i)
                        {
                            throw new SbnException("Corrupt sbn file");
                        }
                        bin.CopyTo(res, i * 100);
                    }
                }
                return(res);
            }
Пример #2
0
        /// <summary>
        /// Creates the tree reading data from the <paramref name="reader"/>
        /// </summary>
        /// <param name="reader">The reader to use</param>
        private SbnTree(BinaryReader reader)
        {
            Monitor.Enter(_syncRoot);

            _header = new SbnHeader();
            _header.Read(reader);

            BuildTree(_header.NumRecords);

            if (BinaryIOExtensions.ReadUInt32BE(reader) != 1)
            {
                throw new SbnException("Invalid format, expecting 1");
            }

            var maxNodeId = BinaryIOExtensions.ReadInt32BE(reader) / 4;
            var ms        = new MemoryStream(reader.ReadBytes(maxNodeId * 8));

            using (var msReader = new BinaryReader(ms))
            {
                var indexNodeId = 1;
                while (msReader.BaseStream.Position < msReader.BaseStream.Length)
                {
                    var nid          = BinaryIOExtensions.ReadInt32BE(msReader);
                    var featureCount = BinaryIOExtensions.ReadInt32BE(msReader);

                    if (nid > 1)
                    {
                        var node = Nodes[indexNodeId];
                        while (node.FeatureCount < featureCount)
                        {
                            var bin = new SbnBin();
                            bin.Read(reader);
                            node.AddBin(bin, true);
                        }
                        Debug.Assert(node.VerifyBins());
                    }
                    indexNodeId++;
                }
            }

            //Gather all feature ids
            GatherFids();

            //Assertions
            Debug.Assert(reader.BaseStream.Position == reader.BaseStream.Length);
            Debug.Assert(_featureIds.Count == _header.NumRecords);


            Monitor.Exit(_syncRoot);
        }
Пример #3
0
        /// <summary>
        /// Method to describe the tree's content
        /// </summary>
        /// <param name="sbnTree"></param>
        /// <param name="writer"></param>
        public static void SbnToText(string sbnTree, TextWriter writer)
        {
            using (var br = new BinaryReader(File.OpenRead(sbnTree)))
            {
                // header
                var header = new SbnHeader();
                header.Read(br);
                writer.WriteLine(header.ToString());

                // Bin header
                writer.WriteLine("[BinHeader]");

                if (BinaryIOExtensions.ReadUInt32BE(br) != 1)
                {
                    throw new SbnException("Invalid format, expecting 1");
                }

                var maxNodeId = BinaryIOExtensions.ReadInt32BE(br) / 4;
                writer.WriteLine("#1, {0} => MaxNodeId = {1}", maxNodeId * 4, maxNodeId);

                var ms = new MemoryStream(br.ReadBytes(maxNodeId * 8));

                using (var msReader = new BinaryReader(ms))
                {
                    var index = 2;
                    while (msReader.BaseStream.Position < msReader.BaseStream.Length)
                    {
                        writer.WriteLine("#{2}, Index {0}, NumFeatures={1}",
                                         BinaryIOExtensions.ReadInt32BE(msReader), BinaryIOExtensions.ReadInt32BE(msReader), index++);
                    }
                }

                writer.WriteLine("[Bins]");
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    var bin   = new SbnBin();
                    var binId = bin.Read(br);
                    writer.Write("[SbnBin {0}: {1}]\n", binId, bin.NumFeatures);
                    for (var i = 0; i < bin.NumFeatures; i++)
                    {
                        writer.WriteLine("  " + bin[i]);
                    }
                }
            }
            writer.Flush();
        }
Пример #4
0
            public bool MoveNext()
            {
                // We don't have a bin at all!
                if (_firstBin == null)
                {
                    return(false);
                }

                // We were resetted or havn't started
                if (_index == -1)
                {
                    _currentBin = _firstBin;
                }

                // did we reach the end!
                if (_index == _currentBin.NumFeatures)
                {
                    return(false);
                }

                // Increment
                _index++;

                // Did we reach the end of the bin now?
                if (_index == 100)
                {
                    //If so move to next
                    _currentBin = _currentBin.Next;
                    //was there another one?
                    if (_currentBin == null)
                    {
                        return(false);
                    }
                    _index = 0;
                }

                return(_index < _currentBin.NumFeatures);
            }
Пример #5
0
        /// <summary>
        /// Method to add a bin to this node
        /// </summary>
        /// <param name="addBin">The bin to add</param>
        /// <param name="setFull">A value indicating that all parent nodes should be set to <see cref="Full"/></param>
        internal void AddBin(SbnBin addBin, bool setFull = false)
        {
            if (FirstBin == null)
            {
                FirstBin = addBin;
                if (setFull)
                {
                    if (Parent != null)
                    {
                        Parent.Full = true;
                    }
                }
            }

            else
            {
                var bin = FirstBin;
                while (bin.Next != null)
                {
                    bin = bin.Next;
                }
                bin.Next = addBin;
            }
        }
Пример #6
0
        /// <summary>
        /// Method to insert a feature at this node
        /// </summary>
        /// <param name="feature">The feature to add</param>
        public void Insert(SbnFeature feature)
        {
            // if this is leaf, just take the feature
            if (Nid >= _tree.FirstLeafNodeId)
            {
                AddFeature(feature);
                return;
            }

            // it takes 8 features to split a node
            // so we'll hold 8 features first
            if (Nid > 1)
            {
                if (!Full)
                {
                    if (FeatureCount < 8)
                    {
                        AddFeature(feature);
                        return;
                    }
                    if (FeatureCount == 8)
                    {
                        var bin = FirstBin;
                        FirstBin = new SbnBin();
                        Full     = true;
                        bin.AddFeature(feature);
                        for (var i = 0; i < 9; i++)
                        {
                            Insert(bin[i]);
                        }
                        return;
                    }
                }
            }

            // The node is split so we can sort features
            int min, max; //, smin, smax;
            var splitAxis = Level % 2;

            if (splitAxis == 1)
            {
                min = feature.MinX;
                max = feature.MaxX;
                //smin = feature.MinY;
                //smax = feature.MaxY;
            }
            else
            {
                min = feature.MinY;
                max = feature.MaxY;
                //smin = feature.MinX;
                //smax = feature.MaxX;
            }
            var seam = GetSplitOridnate(splitAxis);

            // Grab features on the seam we can't split
            if (min <= seam && max > seam)
            {
                AddFeature(feature);
            }

            else if (min < seam)
            {
                Child2.Insert(feature);
            }
            else
            {
                Child1.Insert(feature);
            }
        }
Пример #7
0
 public void Reset()
 {
     _index      = -1;
     _currentBin = null;
 }
Пример #8
0
 void IDisposable.Dispose()
 {
     _firstBin   = null;
     _currentBin = null;
 }
Пример #9
0
 internal SbnFeatureEnumerator(SbnBin firstBin)
 {
     _firstBin = firstBin;
 }