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 void SingleItemTest()
        {
            var tree = new PackedHilbertRTree(1);

            tree.Add(0, 0, 1, 1);
            tree.Finish();
            var list = tree.Search(0, 0, 1, 1);

            Assert.AreEqual(1, list.Count);
        }
        public void TwoItemsTest()
        {
            var tree = new PackedHilbertRTree(2);

            tree.Add(0, 0, 1, 1);
            tree.Add(2, 2, 3, 3);
            tree.Finish();
            var result = tree.Search(1, 1, 2, 2);

            Assert.AreEqual(2, result.Count);
        }
Пример #4
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());
            }
        }
        public void SingleItemRoundtripTest()
        {
            var tree = new PackedHilbertRTree(1);

            tree.Add(0, 0, 1, 1);
            tree.Finish();
            var data = tree.ToBytes();

            Assert.AreEqual(tree.Size, (ulong)data.LongLength);

            var tree2 = new PackedHilbertRTree(1, 16);

            tree2.Load(data);
            var list = tree2.Search(0, 0, 1, 1);

            Assert.AreEqual(1, list.Count);
        }