public RoadNodeRecordProjection(RecyclableMemoryStreamManager manager, Encoding encoding)
        {
            if (manager == null)
            {
                throw new ArgumentNullException(nameof(manager));
            }
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            When <Envelope <ImportedRoadNode> >(async(context, envelope, token) =>
            {
                var typeTranslation = RoadNodeType.Parse(envelope.Message.Type).Translation;
                var dbaseRecord     = new RoadNodeDbaseRecord
                {
                    WK_OIDN   = { Value = envelope.Message.Id },
                    WK_UIDN   = { Value = envelope.Message.Id + "_" + envelope.Message.Version },
                    TYPE      = { Value = typeTranslation.Identifier },
                    LBLTYPE   = { Value = typeTranslation.Name },
                    BEGINTIJD = { Value = envelope.Message.Origin.Since },
                    BEGINORG  = { Value = envelope.Message.Origin.OrganizationId },
                    LBLBGNORG = { Value = envelope.Message.Origin.Organization }
                };

                var point             = GeometryTranslator.FromGeometryPoint(BackOffice.Core.GeometryTranslator.Translate(envelope.Message.Geometry));
                var pointShapeContent = new PointShapeContent(point);

                await context.RoadNodes.AddAsync(new RoadNodeRecord
                {
                    Id = envelope.Message.Id,
                    ShapeRecordContent       = pointShapeContent.ToBytes(manager, encoding),
                    ShapeRecordContentLength = pointShapeContent.ContentLength.ToInt32(),
                    DbaseRecord = dbaseRecord.ToBytes(manager, encoding),
                    BoundingBox = RoadNodeBoundingBox.From(pointShapeContent.Shape)
                }, token);
            });

            When <Envelope <RoadNetworkChangesBasedOnArchiveAccepted> >(async(context, envelope, token) =>
            {
                foreach (var message in envelope.Message.Changes.Flatten())
                {
                    switch (message)
                    {
                    case RoadNodeAdded node:
                        var typeTranslation = RoadNodeType.Parse(node.Type).Translation;
                        var dbaseRecord     = new RoadNodeDbaseRecord
                        {
                            WK_OIDN   = { Value = node.Id },
                            WK_UIDN   = { Value = node.Id + "_0" },  // 1?
                            TYPE      = { Value = typeTranslation.Identifier },
                            LBLTYPE   = { Value = typeTranslation.Name },
                            BEGINTIJD = { Value = LocalDateTimeTranslator.TranslateFromWhen(envelope.Message.When) },
                            BEGINORG  = { Value = envelope.Message.OrganizationId },
                            LBLBGNORG = { Value = envelope.Message.Organization }
                        };

                        var point             = GeometryTranslator.FromGeometryPoint(BackOffice.Core.GeometryTranslator.Translate(node.Geometry));
                        var pointShapeContent = new PointShapeContent(point);

                        await context.RoadNodes.AddAsync(new RoadNodeRecord
                        {
                            Id = node.Id,
                            ShapeRecordContent       = pointShapeContent.ToBytes(manager, encoding),
                            ShapeRecordContentLength = pointShapeContent.ContentLength.ToInt32(),
                            DbaseRecord = dbaseRecord.ToBytes(manager, encoding),
                            BoundingBox = RoadNodeBoundingBox.From(pointShapeContent.Shape)
                        }, token);
                        break;
                    }
                }
            });
        }
예제 #2
0
        public async Task WriteAsync(ZipArchive archive, BackOfficeContext context, CancellationToken cancellationToken)
        {
            if (archive == null)
            {
                throw new ArgumentNullException(nameof(archive));
            }
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var count = await context.RoadNodes.CountAsync(cancellationToken);

            var dbfEntry  = archive.CreateEntry("Wegknoop.dbf");
            var dbfHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(count),
                RoadNodeDbaseRecord.Schema
                );

            using (var dbfEntryStream = dbfEntry.Open())
                using (var dbfWriter =
                           new DbaseBinaryWriter(
                               dbfHeader,
                               new BinaryWriter(dbfEntryStream, _encoding, true)))
                {
                    var dbfRecord = new RoadNodeDbaseRecord();
                    foreach (var data in context.RoadNodes.OrderBy(_ => _.Id).Select(_ => _.DbaseRecord))
                    {
                        dbfRecord.FromBytes(data, _manager, _encoding);
                        dbfWriter.Write(dbfRecord);
                    }
                    dbfWriter.Writer.Flush();
                    await dbfEntryStream.FlushAsync(cancellationToken);
                }

            var shpBoundingBox =
                (await context.RoadNodeBoundingBox.SingleOrDefaultAsync(cancellationToken))?.ToBoundingBox3D()
                ?? new BoundingBox3D(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
            var info = await context.RoadNetworkInfo.SingleAsync(cancellationToken);

            var shpEntry  = archive.CreateEntry("Wegknoop.shp");
            var shpHeader = new ShapeFileHeader(
                new WordLength(info.TotalRoadNodeShapeLength),
                ShapeType.Point,
                shpBoundingBox);

            using (var shpEntryStream = shpEntry.Open())
                using (var shpWriter =
                           new ShapeBinaryWriter(
                               shpHeader,
                               new BinaryWriter(shpEntryStream, _encoding, true)))
                {
                    var number = RecordNumber.Initial;
                    foreach (var data in context.RoadNodes.OrderBy(_ => _.Id).Select(_ => _.ShapeRecordContent))
                    {
                        shpWriter.Write(
                            ShapeContentFactory
                            .FromBytes(data, _manager, _encoding)
                            .RecordAs(number)
                            );
                        number = number.Next();
                    }
                    shpWriter.Writer.Flush();
                    await shpEntryStream.FlushAsync(cancellationToken);
                }

            var shxEntry  = archive.CreateEntry("Wegknoop.shx");
            var shxHeader = shpHeader.ForIndex(new ShapeRecordCount(count));

            using (var shxEntryStream = shxEntry.Open())
                using (var shxWriter =
                           new ShapeIndexBinaryWriter(
                               shxHeader,
                               new BinaryWriter(shxEntryStream, _encoding, true)))
                {
                    var offset = ShapeIndexRecord.InitialOffset;
                    var number = RecordNumber.Initial;
                    foreach (var data in context.RoadNodes.OrderBy(_ => _.Id).Select(_ => _.ShapeRecordContent))
                    {
                        var shpRecord = ShapeContentFactory
                                        .FromBytes(data, _manager, _encoding)
                                        .RecordAs(number);
                        shxWriter.Write(shpRecord.IndexAt(offset));
                        number = number.Next();
                        offset = offset.Plus(shpRecord.Length);
                    }
                    shxWriter.Writer.Flush();
                    await shxEntryStream.FlushAsync(cancellationToken);
                }
        }