public static byte[] ToFlatGeobuf(FeatureCollection fc, GeometryType?geometryType = null, byte dimensions = 2, IList <ColumnMeta> columns = null) { ulong count = (ulong)fc.Features.LongCount(); if (count == 0) { return(new byte[0]); } var index = new PackedHilbertRTree(count); foreach (var f in fc.Features) { var b = f.Geometry.EnvelopeInternal; index.Add(b.MinX, b.MinY, b.MaxX, b.MaxY); } index.Finish(); var featureFirst = fc.Features.First(); if (geometryType == null) { geometryType = GeometryConversions.ToGeometryType(featureFirst.Geometry); } if (columns == null && featureFirst.Attributes != null) { columns = featureFirst.Attributes.GetNames() .Select(n => new ColumnMeta() { Name = n, Type = ToColumnType(featureFirst.Attributes.GetType(n)) }) .ToList(); } using (var memoryStream = new MemoryStream()) { using (var featuresStream = new MemoryStream()) using (var offsetsStream = new MemoryStream()) using (var offetsWriter = new BinaryWriter(offsetsStream)) { ulong offset = 0; for (ulong i = 0; i < count; i++) { var feature = fc.Features[(int)index.Indices[i]]; var buffer = FeatureConversions.ToByteBuffer(feature, geometryType.Value, dimensions, columns); featuresStream.Write(buffer, 0, buffer.Length); offetsWriter.Write(offset); offset += (ulong)buffer.Length; } var header = BuildHeader(count, geometryType.Value, dimensions, columns, index); memoryStream.Write(header, 0, header.Length); var indexBytes = index.ToBytes(); memoryStream.Write(indexBytes, 0, indexBytes.Length); offsetsStream.WriteTo(memoryStream); featuresStream.WriteTo(memoryStream); } return(memoryStream.ToArray()); } }
public static void Serialize(Stream output, IEnumerable <IFeature> features, GeometryType geometryType, byte dimensions = 2, IList <ColumnMeta> columns = null) { output.Write(Constants.MagicBytes); var header = BuildHeader(0, geometryType, columns, null); output.Write(header); foreach (var feature in features) { var featureGeometryType = geometryType == GeometryType.Unknown ? GeometryConversions.ToGeometryType(feature.Geometry) : geometryType; var buffer = FeatureConversions.ToByteBuffer(feature, featureGeometryType, dimensions, columns); output.Write(buffer); } }
public static async ValueTask SerializeAsync(Stream output, IEnumerable <IFeature> features, GeometryType geometryType, byte dimensions = 2, IList <ColumnMeta> columns = null) { output.Write(Constants.MagicBytes); var headerBuffer = BuildHeader(0, geometryType, dimensions, columns, null); await output.WriteAsync(headerBuffer.ToReadOnlyMemory(headerBuffer.Position, headerBuffer.Length - headerBuffer.Position)); headerBuffer.Position += 4; var header = Header.GetRootAsHeader(headerBuffer).UnPack(); foreach (var feature in features) { var buffer = FeatureConversions.ToByteBuffer(feature, header); await output.WriteAsync(buffer.ToReadOnlyMemory(buffer.Position, buffer.Length - buffer.Position)); } }
public static byte[] ToFlatGeobuf(FeatureCollection fc, IList <LayerMeta> layers = null) { ulong count = (ulong)fc.Features.LongCount(); if (count == 0) { throw new ApplicationException("Empty feature collection is not allowed as input"); } var index = new PackedHilbertRTree(count); foreach (var f in fc.Features) { var b = f.Geometry.EnvelopeInternal; index.Add(b.MinX, b.MinY, b.MaxX, b.MaxY); } index.Finish(); if (layers == null) { layers = IntrospectLayers(fc); } using (var memoryStream = new MemoryStream()) { using (var featuresStream = new MemoryStream()) using (var offsetsStream = new MemoryStream()) using (var offetsWriter = new BinaryWriter(offsetsStream)) { ulong offset = 0; for (ulong i = 0; i < count; i++) { var feature = fc.Features[(int)index.Indices[i]]; var buffer = FeatureConversions.ToByteBuffer(feature, layers); featuresStream.Write(buffer, 0, buffer.Length); offetsWriter.Write(offset); offset += (ulong)buffer.Length; } var header = BuildHeader(count, offset, layers, index); memoryStream.Write(header, 0, header.Length); featuresStream.WriteTo(memoryStream); var indexBytes = index.ToBytes(); memoryStream.Write(indexBytes, 0, indexBytes.Length); offsetsStream.WriteTo(memoryStream); } return(memoryStream.ToArray()); } }
public static async Task SerializeAsync(Stream output, IEnumerable <IFeature> features, GeometryType geometryType, byte dimensions = 2, IList <ColumnMeta> columns = null) { await output.WriteAsync(Constants.MagicBytes, 0, Constants.MagicBytes.Length); var headerBuffer = BuildHeader(0, geometryType, dimensions, columns, null); var bytes = headerBuffer.ToSizedArray(); await output.WriteAsync(bytes, 0, bytes.Length); headerBuffer.Position += 4; var header = Header.GetRootAsHeader(headerBuffer).UnPack(); foreach (var feature in features) { var buffer = FeatureConversions.ToByteBuffer(feature, header); bytes = buffer.ToSizedArray(); await output.WriteAsync(bytes, 0, bytes.Length); } }