Beispiel #1
0
        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 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 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 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));
            }
        }
Beispiel #6
0
        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());
            }
        }
Beispiel #7
0
        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);
            }
        }
        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);
            }
        }