public static ByteBuffer ToByteBuffer(IFeature feature, ref Header header) { var builder = new FlatBufferBuilder(1024); GeometryType geometryType; if (header.GeometryType != GeometryType.Unknown) { geometryType = header.GeometryType; } else { geometryType = GeometryConversions.ToGeometryType(feature.Geometry); } var go = GeometryConversions.BuildGeometry(builder, feature.Geometry, geometryType, ref header); var memoryStream = new MemoryStream(); if (feature.Attributes != null && feature.Attributes.Count > 0 && header.ColumnsLength > 0) { var writer = new BinaryWriter(memoryStream, Encoding.UTF8); for (ushort i = 0; i < header.ColumnsLength; i++) { var column = header.Columns(i).Value; var type = column.Type; var name = column.Name; if (!feature.Attributes.Exists(name)) { continue; } var value = feature.Attributes[name]; if (value is null) { continue; } writer.Write(i); switch (type) { case ColumnType.Bool: writer.Write((bool)value); break; case ColumnType.Int: writer.Write((int)value); break; case ColumnType.Long: writer.Write((long)value); break; case ColumnType.Double: writer.Write((double)value); break; case ColumnType.String: var bytes = Encoding.UTF8.GetBytes((string)value); writer.Write(bytes.Length); writer.Write(bytes); break; default: throw new ApplicationException("Unknown type " + value.GetType().FullName); } } } var propertiesOffset = default(VectorOffset); if (memoryStream.Position > 0) { propertiesOffset = Feature.CreatePropertiesVectorBlock(builder, memoryStream.ToArray()); } Offset <Geometry> geometryOffset; if (go.gos != null && go.gos.Length > 0) { var partOffsets = new Offset <Geometry> [go.gos.Length]; for (int i = 0; i < go.gos.Length; i++) { var goPart = go.gos[i]; var partOffset = Geometry.CreateGeometry(builder, goPart.endsOffset, goPart.xyOffset, goPart.zOffset, goPart.mOffset, default, default, go.Type, default);
public static byte[] ToByteBuffer(IFeature feature, IList <LayerMeta> layers) { // TODO: size might not be enough, need to be adaptive var builder = new FlatBufferBuilder(1024); // TODO: improve layer introspection var layer = layers.First(l => l.GeometryType == GeometryConversions.ToGeometryType(feature.Geometry)); var layerIndex = (uint)layers.IndexOf(layer); var columns = layer.Columns; var geometryOffset = GeometryConversions.BuildGeometry(builder, feature.Geometry); VectorOffset?valuesOffset = null; if (feature.Attributes != null && feature.Attributes.Count > 0 && columns != null) { var valueOffsets = new List <Offset <Value> >(); foreach (var column in columns) { if (feature.Attributes.Exists(column.Name)) { ushort columnIndex = (ushort)columns.IndexOf(column); var value = feature.Attributes[column.Name]; switch (value) { case bool v: valueOffsets.Add(Value.CreateValue(builder, columnIndex, bool_value: v)); break; case int v: valueOffsets.Add(Value.CreateValue(builder, columnIndex, int_value: v)); break; case long v: valueOffsets.Add(Value.CreateValue(builder, columnIndex, long_value: v)); break; case double v: valueOffsets.Add(Value.CreateValue(builder, columnIndex, double_value: v)); break; case string v: valueOffsets.Add(Value.CreateValue(builder, columnIndex, string_valueOffset: builder.CreateString(v))); break; case null: break; default: throw new ApplicationException("Unknown type"); } } } valuesOffset = Feature.CreateValuesVector(builder, valueOffsets.ToArray()); } Feature.StartFeature(builder); Feature.AddGeometry(builder, geometryOffset); Feature.AddLayer(builder, layerIndex); if (valuesOffset.HasValue) { Feature.AddValues(builder, valuesOffset.Value); } var offset = Feature.EndFeature(builder); builder.FinishSizePrefixed(offset.Value); var bytes = builder.DataBuffer.ToSizedArray(); return(bytes); }
public static byte[] ToByteBuffer(IFeature feature, GeometryType geometryType, byte dimensions, IList <ColumnMeta> columns) { var builder = new FlatBufferBuilder(4096); var go = GeometryConversions.BuildGeometry(builder, feature.Geometry, geometryType, dimensions); var memoryStream = new MemoryStream(); if (feature.Attributes != null && feature.Attributes.Count > 0 && columns != null) { var writer = new BinaryWriter(memoryStream, Encoding.UTF8); for (ushort i = 0; i < columns.Count(); i++) { var column = columns[i]; var type = column.Type; var name = column.Name; if (!feature.Attributes.Exists(name)) { continue; } var value = feature.Attributes[name]; if (value is null) { continue; } writer.Write(i); switch (type) { case ColumnType.Bool: writer.Write((bool)value); break; case ColumnType.Int: writer.Write((int)value); break; case ColumnType.Long: writer.Write((long)value); break; case ColumnType.Double: writer.Write((double)value); break; case ColumnType.String: var bytes = Encoding.UTF8.GetBytes((string)value); writer.Write(bytes.Length); writer.Write(bytes); break; default: throw new ApplicationException("Unknown type " + value.GetType().FullName); } } } var propertiesOffset = default(VectorOffset); if (memoryStream.Position > 0) { propertiesOffset = Feature.CreatePropertiesVector(builder, memoryStream.ToArray()); } var geometryOffset = default(Offset <Geometry>); if (go.gos != null && go.gos.Length > 0) { var partOffsets = new Offset <Geometry> [go.gos.Length]; for (int i = 0; i < go.gos.Length; i++) { var goPart = go.gos[i]; var partOffset = Geometry.CreateGeometry(builder, goPart.endsOffset, goPart.coordsOffset, default(VectorOffset), default(VectorOffset), default(VectorOffset), default(VectorOffset), go.type, default(VectorOffset)); partOffsets[i] = partOffset; } var partsOffset = Geometry.CreatePartsVector(builder, partOffsets); geometryOffset = Geometry.CreateGeometry(builder, default(VectorOffset), default(VectorOffset), default(VectorOffset), default(VectorOffset), default(VectorOffset), default(VectorOffset), go.type, partsOffset); } else { geometryOffset = Geometry.CreateGeometry(builder, go.endsOffset, go.coordsOffset, default(VectorOffset), default(VectorOffset), default(VectorOffset), default(VectorOffset), go.type, default(VectorOffset)); } Feature.StartFeature(builder); Feature.AddGeometry(builder, geometryOffset); Feature.AddProperties(builder, propertiesOffset); var featureOffset = Feature.EndFeature(builder); builder.FinishSizePrefixed(featureOffset.Value); return(builder.DataBuffer.ToSizedArray()); }