internal static SbnBinIndex Read(BinaryReader reader) { if (BinaryIOExtensions.ReadInt32BE(reader) != 1) { throw new SbnException("Sbn file corrupt"); } var length = BinaryIOExtensions.ReadInt32BE(reader); var maxNodeId = length / 4; var nodeToBin = new SbnNodeToBinIndexEntry[maxNodeId + 1]; for (var i = 1; i <= maxNodeId; i++) { var binIndex = BinaryIOExtensions.ReadInt32BE(reader); var numFeatures = BinaryIOExtensions.ReadInt32BE(reader); if (binIndex > 0) { nodeToBin[i] = new SbnNodeToBinIndexEntry { FirstBinIndex = binIndex, NumFeatures = numFeatures } } ; } return(new SbnBinIndex(nodeToBin)); }
/// <summary> /// Method to read the index header using the provided reader /// </summary> /// <param name="reader">The reader to use</param> public void Read(BinaryReader reader) { var fileCode = BinaryIOExtensions.ReadInt32BE(reader); var fileCodeIndex = BinaryIOExtensions.ReadInt32BE(reader); if (fileCode != FileCode || fileCodeIndex != FileCodeIndex) { throw new SbnException("Not a Shapefile index file"); } reader.BaseStream.Seek(16, SeekOrigin.Current); FileLength = BinaryIOExtensions.ReadInt32BE(reader) * 2; NumRecords = BinaryIOExtensions.ReadInt32BE(reader); var minX = BinaryIOExtensions.ReadDoubleBE(reader); var minY = BinaryIOExtensions.ReadDoubleBE(reader); XRange = Interval.Create(minX, BinaryIOExtensions.ReadDoubleBE(reader)); YRange = Interval.Create(minY, BinaryIOExtensions.ReadDoubleBE(reader)); ZRange = Interval.Create(BinaryIOExtensions.ReadDoubleBE(reader), BinaryIOExtensions.ReadDoubleBE(reader)); MRange = Interval.Create(BinaryIOExtensions.ReadDoubleBE(reader), BinaryIOExtensions.ReadDoubleBE(reader)); reader.BaseStream.Seek(4, SeekOrigin.Current); }
/// <summary> /// Method to read a bin /// </summary> /// <param name="reader">The reader to use</param> internal int Read(BinaryReader reader) { var bid = BinaryIOExtensions.ReadInt32BE(reader); NumFeatures = BinaryIOExtensions.ReadInt32BE(reader) / 4; ReadBuffer(reader); return(bid); }
/// <summary> /// Creates an instance of this class using a binary reader /// </summary> /// <param name="sr">The binary reader</param> internal SbnFeature(BinaryReader sr) { MinX = sr.ReadByte(); MinY = sr.ReadByte(); MaxX = sr.ReadByte(); MaxY = sr.ReadByte(); _fid = BinaryIOExtensions.ReadUInt32BE(sr); }
/// <summary> /// Method to write the feature to an index /// </summary> /// <param name="writer"></param> internal void Write(BinaryWriter writer) { writer.Write(MinX); writer.Write(MinY); writer.Write(MaxX); writer.Write(MaxY); BinaryIOExtensions.WriteBE(writer, _fid); }
/// <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 write a bin /// </summary> /// <param name="bid">The bin's id</param> /// <param name="sbnWriter">The writer to use</param> /// <param name="sbxWriter"></param> internal void Write(ref int bid, BinaryWriter sbnWriter, BinaryWriter sbxWriter = null) { if (sbxWriter != null) { BinaryIOExtensions.WriteBE(sbxWriter, (int)(sbnWriter.BaseStream.Position / 2)); BinaryIOExtensions.WriteBE(sbxWriter, NumFeatures * 4); } BinaryIOExtensions.WriteBE(sbnWriter, bid++); BinaryIOExtensions.WriteBE(sbnWriter, NumFeatures * 4); WriteBuffer(sbnWriter); if (Next != null) { Next.Write(ref bid, sbnWriter, sbxWriter); } }
private byte[] GetBinData(int binIndex) { binIndex--; Monitor.Enter(_indexLock); _sbxStream.Seek(100 + binIndex * 8, SeekOrigin.Begin); var sbxReader = new BinaryReader(_sbxStream); var sbnPosition = BinaryIOExtensions.ReadUInt32BE(sbxReader) * 2; var sbnSize = 8 + BinaryIOExtensions.ReadInt32BE(sbxReader) * 2; _sbnStream.Seek(sbnPosition, SeekOrigin.Begin); var res = new byte[sbnSize]; _sbnStream.Read(res, 0, sbnSize); Monitor.Exit(_indexLock); return(res); }
/// <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(); }
/// <summary> /// Method to write the bin header to the sbn file /// </summary> /// <param name="sbnsw"></param> /// <param name="lastBinIndex"></param> private void WriteBinHeader(BinaryWriter sbnsw, int lastBinIndex) { var binIndex = 2; for (var i = 1; i <= lastBinIndex; i++) { if (Nodes[i].FeatureCount > 0) { BinaryIOExtensions.WriteBE(sbnsw, binIndex); BinaryIOExtensions.WriteBE(sbnsw, Nodes[i].FeatureCount); binIndex += (int)Math.Ceiling(Nodes[i].FeatureCount / 100d); } else { BinaryIOExtensions.WriteBE(sbnsw, -1); BinaryIOExtensions.WriteBE(sbnsw, 0); } } }
/// <summary> /// Method to write the index header using the provided writer /// </summary> /// <param name="writer">The writer to use</param> /// <param name="fileLength"></param> internal void Write(BinaryWriter writer, int?fileLength = null) { BinaryIOExtensions.WriteBE(writer, FileCode); BinaryIOExtensions.WriteBE(writer, FileCodeIndex); writer.Write(new byte[16]); BinaryIOExtensions.WriteBE(writer, (fileLength ?? FileLength) / 2); BinaryIOExtensions.WriteBE(writer, NumRecords); BinaryIOExtensions.WriteBE(writer, XRange.Min); BinaryIOExtensions.WriteBE(writer, YRange.Min); BinaryIOExtensions.WriteBE(writer, XRange.Max); BinaryIOExtensions.WriteBE(writer, YRange.Max); BinaryIOExtensions.WriteBE(writer, ZRange); BinaryIOExtensions.WriteBE(writer, MRange); writer.Write(0); }
/// <summary> /// Method to write the tree /// </summary> /// <param name="sbnsw">A writer for the sbn stream</param> /// <param name="sbxsw">A writer for the sbx stream</param> private void Write(BinaryWriter sbnsw, BinaryWriter sbxsw) { // Gather header data int numBins, lastBinIndex; GetHeaderValues(out numBins, out lastBinIndex); // we have one additional bin numBins++; // first bin descriptors var numBinHeaderRecords = lastBinIndex; var binHeaderSize = (numBinHeaderRecords) * 8; // then bins with features var usedBinSize = numBins * 8; var sbxSize = 100 + usedBinSize; var sbnSize = 100 + binHeaderSize + usedBinSize + FeatureCount * 8; // Write headers _header.Write(sbnsw, sbnSize); _header.Write(sbxsw, sbxSize); // sbn and sbx records // first create bin descriptors record var recLen = (numBinHeaderRecords) * 4; BinaryIOExtensions.WriteBE(sbnsw, 1); BinaryIOExtensions.WriteBE(sbnsw, recLen); BinaryIOExtensions.WriteBE(sbxsw, 50); BinaryIOExtensions.WriteBE(sbxsw, recLen); WriteBinHeader(sbnsw, lastBinIndex); WriteBins(sbnsw, sbxsw); }