private static byte[] BuildHeader(ulong count, GeometryType geometryType, IList <ColumnMeta> columns, PackedRTree index) { var builder = new FlatBufferBuilder(4096); VectorOffset?columnsOffset = null; if (columns != null) { var columnsArray = columns .Select(c => Column.CreateColumn(builder, builder.CreateString(c.Name), c.Type)) .ToArray(); columnsOffset = Header.CreateColumnsVector(builder, columnsArray); } Header.StartHeader(builder); Header.AddGeometryType(builder, geometryType); if (columnsOffset.HasValue) { Header.AddColumns(builder, columnsOffset.Value); } //if (index != null) Header.AddIndexNodeSize(builder, 0); Header.AddFeaturesCount(builder, count); var offset = Header.EndHeader(builder); builder.FinishSizePrefixed(offset.Value); return(builder.DataBuffer.ToSizedArray()); }
public static IEnumerable <IFeature> Deserialize(Stream stream, Envelope rect = null) { var reader = new BinaryReader(stream); var magicBytes = reader.ReadBytes(8); if (!magicBytes.SequenceEqual(Constants.MagicBytes)) { throw new Exception("Not a FlatGeobuf file"); } var headerSize = reader.ReadInt32(); var header = Header.GetRootAsHeader(new ByteBuffer(reader.ReadBytes(headerSize))); var count = header.FeaturesCount; var nodeSize = header.IndexNodeSize; var geometryType = header.GeometryType; IList <ColumnMeta> columns = null; if (header.ColumnsLength > 0) { columns = new List <ColumnMeta>(); for (int i = 0; i < header.ColumnsLength; i++) { var column = header.Columns(i).Value; columns.Add(new ColumnMeta() { Name = column.Name, Type = column.Type }); } } if (nodeSize > 0) { long offset = 8 + 4 + headerSize; var size = PackedRTree.CalcSize(count, nodeSize); if (rect != null) { var result = PackedRTree.StreamSearch(count, nodeSize, rect, (ulong treeOffset, ulong size) => { stream.Seek(offset + (long)treeOffset, SeekOrigin.Begin); return(stream); }).ToList(); foreach (var item in result) { stream.Seek(offset + (long)size + (long)item.Offset, SeekOrigin.Begin); var featureLength = reader.ReadInt32(); var feature = FeatureConversions.FromByteBuffer(new ByteBuffer(reader.ReadBytes(featureLength)), geometryType, 2, columns); yield return(feature); } yield break; } stream.Seek(8 + 4 + headerSize + (long)size, SeekOrigin.Begin); } while (stream.Position < stream.Length) { var featureLength = reader.ReadInt32(); var feature = FeatureConversions.FromByteBuffer(new ByteBuffer(reader.ReadBytes(featureLength)), geometryType, 2, columns); yield return(feature); } }