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); }
/// <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); }
/// <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(); }
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); }
/// <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; } }
/// <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); } }
public void Reset() { _index = -1; _currentBin = null; }
void IDisposable.Dispose() { _firstBin = null; _currentBin = null; }
internal SbnFeatureEnumerator(SbnBin firstBin) { _firstBin = firstBin; }