public static FeatureCollection FromFlatGeobuf(byte[] bytes) { var fc = new NetTopologySuite.Features.FeatureCollection(); var bb = new ByteBuffer(bytes); var headerSize = (ulong)ByteBufferUtil.GetSizePrefix(bb); bb.Position = FlatBufferConstants.SizePrefixLength; var header = Header.GetRootAsHeader(bb); var count = header.FeaturesCount; var featuresSize = header.FeaturesSize; var nodeSize = header.IndexNodeSize; bb.Position += (int)headerSize; var index = new PackedHilbertRTree(count, nodeSize); var indexData = bytes.Skip((int)(headerSize + featuresSize)).Take((int)index.Size).ToArray(); index.Load(indexData); while (count-- > 0) { var featureLength = ByteBufferUtil.GetSizePrefix(bb); bb.Position += FlatBufferConstants.SizePrefixLength; var feature = FeatureConversions.FromByteBuffer(bb, header); fc.Add(feature); bb.Position += featureLength; } return(fc); }
public static FeatureCollection FromFlatGeobuf(byte[] bytes) { var fc = new NetTopologySuite.Features.FeatureCollection(); var bb = new ByteBuffer(bytes); var headerSize = ByteBufferUtil.GetSizePrefix(bb); bb.Position = FlatBufferConstants.SizePrefixLength; var header = Header.GetRootAsHeader(bb); var count = header.FeaturesCount; var nodeSize = header.IndexNodeSize; var geometryType = header.GeometryType; var dimensions = header.Dimensions; 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 }); } } bb.Position += headerSize; if (nodeSize > 0) { var index = new PackedHilbertRTree(count, nodeSize); var indexData = bytes.Skip(headerSize).Take((int)index.Size).ToArray(); index.Load(indexData); bb.Position += (int)index.Size + (int)count * 8; } while (bb.Position < bb.Length) { var featureLength = ByteBufferUtil.GetSizePrefix(bb); bb.Position += FlatBufferConstants.SizePrefixLength; var feature = FeatureConversions.FromByteBuffer(bb, geometryType, dimensions, columns); fc.Add(feature); bb.Position += featureLength; } return(fc); }
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); } }