/// <summary> /// Method to open an sbn index file /// </summary> /// <param name="sbnFilename">The sbn index filename></param> /// <returns>An sbn index query structure</returns> public static SbnQueryOnlyTree Open(string sbnFilename) { if (string.IsNullOrEmpty(sbnFilename)) { throw new ArgumentNullException(sbnFilename); } if (!File.Exists(sbnFilename)) { throw new FileNotFoundException("File not found", sbnFilename); } var sbxFilename = Path.ChangeExtension(sbnFilename, "sbx"); if (!File.Exists(sbxFilename)) { throw new FileNotFoundException("File not found", sbxFilename); } var res = new SbnQueryOnlyTree(sbnFilename, sbxFilename); var sbxHeader = new SbnHeader(); sbxHeader.Read(new BinaryReader(res._sbxStream)); if (res._sbnHeader.NumRecords != sbxHeader.NumRecords) { throw new SbnException("Sbn and Sbx do not serve the same number of features!"); } 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> /// Creates an istance of this class /// </summary> /// <param name="sbnFilename"></param> /// <param name="sbxFilename"></param> private SbnQueryOnlyTree(string sbnFilename, string sbxFilename) { _sbnStream = new FileStream(sbnFilename, FileMode.Open, FileAccess.Read, FileShare.Read, 8192); _sbnHeader = new SbnHeader(); var sbnReader = new BinaryReader(_sbnStream); _sbnHeader.Read(sbnReader); _sbnBinIndex = SbnBinIndex.Read(sbnReader); _sbxStream = new FileStream(sbxFilename, FileMode.Open, FileAccess.Read, FileShare.Read, 8192); FirstLeafNodeId = (int)Math.Pow(2, GetNumberOfLevels(_sbnHeader.NumRecords) - 1); MaxCacheLevel = DefaultMaxCacheLevel; SbnQueryOnlyNode.CreateRoot(this); _sbxStream.Position = 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(); }