public Task When_a_road_segment_was_imported()
        {
            var geometry       = _fixture.Create <MultiLineString>();
            var european_roads = _fixture.CreateMany <ImportedRoadSegmentEuropeanRoadAttributes>().ToArray();
            var numbered_roads = _fixture.CreateMany <ImportedRoadSegmentNumberedRoadAttributes>().ToArray();
            var national_roads = _fixture.CreateMany <ImportedRoadSegmentNationalRoadAttributes>().ToArray();
            var lanes          = _fixture.CreateMany <ImportedRoadSegmentLaneAttributes>().ToArray();
            var widths         = _fixture.CreateMany <ImportedRoadSegmentWidthAttributes>().ToArray();
            var hardenings     = _fixture.CreateMany <ImportedRoadSegmentSurfaceAttributes>().ToArray();
            var content        = new PolyLineMShapeContent(Be.Vlaanderen.Basisregisters.Shaperon.Geometries.GeometryTranslator.FromGeometryMultiLineString(geometry));

            return(new RoadNetworkInfoProjection()
                   .Scenario()
                   .Given(
                       new BeganRoadNetworkImport(),
                       new ImportedRoadSegment
            {
                Id = _fixture.Create <int>(),
                StartNodeId = _fixture.Create <int>(),
                EndNodeId = _fixture.Create <int>(),
                Geometry = BackOffice.Core.GeometryTranslator.Translate(geometry),
                GeometryVersion = _fixture.Create <int>(),
                MaintenanceAuthority = _fixture.Create <MaintenanceAuthority>(),
                GeometryDrawMethod = _fixture.Create <RoadSegmentGeometryDrawMethod>(),
                Morphology = _fixture.Create <RoadSegmentMorphology>(),
                Status = _fixture.Create <RoadSegmentStatus>(),
                Category = _fixture.Create <RoadSegmentCategory>(),
                AccessRestriction = _fixture.Create <RoadSegmentAccessRestriction>(),
                LeftSide = _fixture.Create <ImportedRoadSegmentSideAttributes>(),
                RightSide = _fixture.Create <ImportedRoadSegmentSideAttributes>(),
                PartOfEuropeanRoads = european_roads,
                PartOfNationalRoads = national_roads,
                PartOfNumberedRoads = numbered_roads,
                Lanes = lanes,
                Widths = widths,
                Surfaces = hardenings,
                Version = _fixture.Create <int>(),
                RecordingDate = _fixture.Create <DateTime>(),
                Origin = _fixture.Create <ImportedOriginProperties>()
            }
                       )
                   .Expect(
                       new RoadNetworkInfo {
                Id = 0,
                CompletedImport = false,
                OrganizationCount = 0,
                RoadNodeCount = 0,
                TotalRoadNodeShapeLength = 0,
                RoadSegmentCount = 1,
                RoadSegmentSurfaceAttributeCount = hardenings.Length,
                RoadSegmentLaneAttributeCount = lanes.Length,
                RoadSegmentWidthAttributeCount = widths.Length,
                RoadSegmentEuropeanRoadAttributeCount = european_roads.Length,
                RoadSegmentNationalRoadAttributeCount = national_roads.Length,
                RoadSegmentNumberedRoadAttributeCount = numbered_roads.Length,
                TotalRoadSegmentShapeLength = ShapeRecord.HeaderLength.Plus(content.ContentLength).ToInt32(),
                GradeSeparatedJunctionCount = 0
            }
                       ));
        }
            private bool Equals(PolyLineMShapeContent left, PolyLineMShapeContent right)
            {
                var sameContentLength = left.ContentLength.Equals(right.ContentLength);
                var sameShapeType     = left.ShapeType.Equals(right.ShapeType);
                var sameShape         = left.Shape.Equals(right.Shape);

                return(sameContentLength && sameShapeType && sameShape);
            }
        public Task When_road_segments_are_imported()
        {
            var random = new Random();
            var data   = _fixture
                         .CreateMany <ImportedRoadSegment>(random.Next(1, 10))
                         .Select(importedRoadSegment =>
            {
                var geometry = GeometryTranslator.Translate(importedRoadSegment.Geometry);
                var polyLineMShapeContent = new PolyLineMShapeContent(Be.Vlaanderen.Basisregisters.Shaperon.Geometries.GeometryTranslator.FromGeometryMultiLineString(geometry));

                var expected = new RoadSegmentRecord
                {
                    Id = importedRoadSegment.Id,
                    ShapeRecordContent       = polyLineMShapeContent.ToBytes(_services.MemoryStreamManager, Encoding.UTF8),
                    ShapeRecordContentLength = polyLineMShapeContent.ContentLength.ToInt32(),
                    BoundingBox = RoadSegmentBoundingBox.From(polyLineMShapeContent.Shape),
                    DbaseRecord = new RoadSegmentDbaseRecord
                    {
                        WS_OIDN   = { Value = importedRoadSegment.Id },
                        WS_UIDN   = { Value = importedRoadSegment.Id + "_" + importedRoadSegment.Version },
                        WS_GIDN   = { Value = importedRoadSegment.Id + "_" + importedRoadSegment.GeometryVersion },
                        B_WK_OIDN = { Value = importedRoadSegment.StartNodeId },
                        E_WK_OIDN = { Value = importedRoadSegment.EndNodeId },
                        STATUS    = { Value = RoadSegmentStatus.Parse(importedRoadSegment.Status).Translation.Identifier },
                        LBLSTATUS = { Value = RoadSegmentStatus.Parse(importedRoadSegment.Status).Translation.Name },
                        MORF      = { Value = RoadSegmentMorphology.Parse(importedRoadSegment.Morphology).Translation.Identifier },
                        LBLMORF   = { Value = RoadSegmentMorphology.Parse(importedRoadSegment.Morphology).Translation.Name },
                        WEGCAT    = { Value = RoadSegmentCategory.Parse(importedRoadSegment.Category).Translation.Identifier },
                        LBLWEGCAT = { Value = RoadSegmentCategory.Parse(importedRoadSegment.Category).Translation.Name },
                        LSTRNMID  = { Value = importedRoadSegment.LeftSide.StreetNameId },
                        LSTRNM    = { Value = importedRoadSegment.LeftSide.StreetName },
                        RSTRNMID  = { Value = importedRoadSegment.RightSide.StreetNameId },
                        RSTRNM    = { Value = importedRoadSegment.RightSide.StreetName },
                        BEHEER    = { Value = importedRoadSegment.MaintenanceAuthority.Code },
                        LBLBEHEER = { Value = importedRoadSegment.MaintenanceAuthority.Name },
                        METHODE   = { Value = RoadSegmentGeometryDrawMethod.Parse(importedRoadSegment.GeometryDrawMethod).Translation.Identifier },
                        LBLMETHOD = { Value = RoadSegmentGeometryDrawMethod.Parse(importedRoadSegment.GeometryDrawMethod).Translation.Name },
                        OPNDATUM  = { Value = importedRoadSegment.RecordingDate },
                        BEGINTIJD = { Value = importedRoadSegment.Origin.Since },
                        BEGINORG  = { Value = importedRoadSegment.Origin.OrganizationId },
                        LBLBGNORG = { Value = importedRoadSegment.Origin.Organization },
                        TGBEP     = { Value = RoadSegmentAccessRestriction.Parse(importedRoadSegment.AccessRestriction).Translation.Identifier },
                        LBLTGBEP  = { Value = RoadSegmentAccessRestriction.Parse(importedRoadSegment.AccessRestriction).Translation.Name }
                    }.ToBytes(_services.MemoryStreamManager, Encoding.UTF8)
                };
                return(new { importedRoadSegment, expected });
            }).ToList();

            return(new RoadRegistry.Product.Projections.RoadSegmentRecordProjection(_services.MemoryStreamManager, Encoding.UTF8)
                   .Scenario()
                   .Given(data.Select(d => d.importedRoadSegment))
                   .Expect(data.Select(d => d.expected)));
        }
Example #4
0
        public RoadSegmentRecordProjection(RecyclableMemoryStreamManager manager,
                                           Encoding encoding)
        {
            if (manager == null)
            {
                throw new ArgumentNullException(nameof(manager));
            }
            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            When <Envelope <ImportedRoadSegment> >(async(context, envelope, token) =>
            {
                var geometry =
                    GeometryTranslator.FromGeometryMultiLineString(BackOffice.Core.GeometryTranslator.Translate(envelope.Message.Geometry));
                var polyLineMShapeContent         = new PolyLineMShapeContent(geometry);
                var statusTranslation             = RoadSegmentStatus.Parse(envelope.Message.Status).Translation;
                var morphologyTranslation         = RoadSegmentMorphology.Parse(envelope.Message.Morphology).Translation;
                var categoryTranslation           = RoadSegmentCategory.Parse(envelope.Message.Category).Translation;
                var geometryDrawMethodTranslation =
                    RoadSegmentGeometryDrawMethod.Parse(envelope.Message.GeometryDrawMethod).Translation;
                var accessRestrictionTranslation =
                    RoadSegmentAccessRestriction.Parse(envelope.Message.AccessRestriction).Translation;
                await context.RoadSegments.AddAsync(
                    new RoadSegmentRecord
                {
                    Id = envelope.Message.Id,
                    ShapeRecordContent       = polyLineMShapeContent.ToBytes(manager, encoding),
                    ShapeRecordContentLength = polyLineMShapeContent.ContentLength.ToInt32(),
                    BoundingBox = RoadSegmentBoundingBox.From(polyLineMShapeContent.Shape),
                    DbaseRecord = new RoadSegmentDbaseRecord
                    {
                        WS_OIDN   = { Value = envelope.Message.Id },
                        WS_UIDN   = { Value = $"{envelope.Message.Id}_{envelope.Message.Version}" },
                        WS_GIDN   = { Value = $"{envelope.Message.Id}_{envelope.Message.GeometryVersion}" },
                        B_WK_OIDN = { Value = envelope.Message.StartNodeId },
                        E_WK_OIDN = { Value = envelope.Message.EndNodeId },
                        STATUS    = { Value = statusTranslation.Identifier },
                        LBLSTATUS = { Value = statusTranslation.Name },
                        MORF      = { Value = morphologyTranslation.Identifier },
                        LBLMORF   = { Value = morphologyTranslation.Name },
                        WEGCAT    = { Value = categoryTranslation.Identifier },
                        LBLWEGCAT = { Value = categoryTranslation.Name },
                        LSTRNMID  = { Value = envelope.Message.LeftSide.StreetNameId },
                        LSTRNM    = { Value = envelope.Message.LeftSide.StreetName },
                        RSTRNMID  = { Value = envelope.Message.RightSide.StreetNameId },
                        RSTRNM    = { Value = envelope.Message.RightSide.StreetName },
                        BEHEER    = { Value = envelope.Message.MaintenanceAuthority.Code },
                        LBLBEHEER = { Value = envelope.Message.MaintenanceAuthority.Name },
                        METHODE   = { Value = geometryDrawMethodTranslation.Identifier },
                        LBLMETHOD = { Value = geometryDrawMethodTranslation.Name },
                        OPNDATUM  = { Value = envelope.Message.RecordingDate },
                        BEGINTIJD = { Value = envelope.Message.Origin.Since },
                        BEGINORG  = { Value = envelope.Message.Origin.OrganizationId },
                        LBLBGNORG = { Value = envelope.Message.Origin.Organization },
                        TGBEP     = { Value = accessRestrictionTranslation.Identifier },
                        LBLTGBEP  = { Value = accessRestrictionTranslation.Name }
                    }.ToBytes(manager, encoding)
                },
                    token);
            });

            When <Envelope <RoadNetworkChangesBasedOnArchiveAccepted> >(async(context, envelope, token) =>
            {
                foreach (var message in envelope.Message.Changes.Flatten())
                {
                    switch (message)
                    {
                    case RoadSegmentAdded segment:
                        var geometry =
                            GeometryTranslator.FromGeometryMultiLineString(BackOffice.Core.GeometryTranslator.Translate(segment.Geometry));
                        var polyLineMShapeContent         = new PolyLineMShapeContent(geometry);
                        var statusTranslation             = RoadSegmentStatus.Parse(segment.Status).Translation;
                        var morphologyTranslation         = RoadSegmentMorphology.Parse(segment.Morphology).Translation;
                        var categoryTranslation           = RoadSegmentCategory.Parse(segment.Category).Translation;
                        var geometryDrawMethodTranslation =
                            RoadSegmentGeometryDrawMethod.Parse(segment.GeometryDrawMethod).Translation;
                        var accessRestrictionTranslation =
                            RoadSegmentAccessRestriction.Parse(segment.AccessRestriction).Translation;
                        await context.RoadSegments.AddAsync(
                            new RoadSegmentRecord
                        {
                            Id = segment.Id,
                            ShapeRecordContent       = polyLineMShapeContent.ToBytes(manager, encoding),
                            ShapeRecordContentLength = polyLineMShapeContent.ContentLength.ToInt32(),
                            BoundingBox = RoadSegmentBoundingBox.From(polyLineMShapeContent.Shape),
                            DbaseRecord = new RoadSegmentDbaseRecord
                            {
                                WS_OIDN   = { Value = segment.Id },
                                WS_UIDN   = { Value = $"{segment.Id}_{segment.Version}" },
                                WS_GIDN   = { Value = $"{segment.Id}_{segment.GeometryVersion}" },
                                B_WK_OIDN = { Value = segment.StartNodeId },
                                E_WK_OIDN = { Value = segment.EndNodeId },
                                STATUS    = { Value = statusTranslation.Identifier },
                                LBLSTATUS = { Value = statusTranslation.Name },
                                MORF      = { Value = morphologyTranslation.Identifier },
                                LBLMORF   = { Value = morphologyTranslation.Name },
                                WEGCAT    = { Value = categoryTranslation.Identifier },
                                LBLWEGCAT = { Value = categoryTranslation.Name },
                                LSTRNMID  = { Value = segment.LeftSide.StreetNameId },
                                // TODO: Where does this come from?
                                LSTRNM   = { Value = null },
                                RSTRNMID = { Value = segment.RightSide.StreetNameId },
                                // TODO: Where does this come from?
                                RSTRNM    = { Value = null },
                                BEHEER    = { Value = segment.MaintenanceAuthority.Code },
                                LBLBEHEER = { Value = segment.MaintenanceAuthority.Name },
                                METHODE   = { Value = geometryDrawMethodTranslation.Identifier },
                                LBLMETHOD = { Value = geometryDrawMethodTranslation.Name },
                                OPNDATUM  = { Value = LocalDateTimeTranslator.TranslateFromWhen(envelope.Message.When) },
                                BEGINTIJD = { Value = LocalDateTimeTranslator.TranslateFromWhen(envelope.Message.When) },
                                BEGINORG  = { Value = envelope.Message.OrganizationId },
                                LBLBGNORG = { Value = envelope.Message.Organization },
                                TGBEP     = { Value = accessRestrictionTranslation.Identifier },
                                LBLTGBEP  = { Value = accessRestrictionTranslation.Name }
                            }.ToBytes(manager, encoding)
                        },
                            token);
                        break;
                    }
                }
            });
        }
Example #5
0
        static void Main(string[] args)
        {
            Directory.CreateDirectory("output");

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            var node1Record = new RoadNodeChangeDbaseRecord();

            node1Record.TYPE.Value       = (short)RoadNodeType.EndNode.Translation.Identifier;
            node1Record.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;
            node1Record.WEGKNOOPID.Value = 1;
            var node1Shape = new PointShapeContent(new Point(0.0, 0.0));

            var node2Record = new RoadNodeChangeDbaseRecord();

            node2Record.TYPE.Value       = (short)RoadNodeType.EndNode.Translation.Identifier;
            node2Record.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;
            node2Record.WEGKNOOPID.Value = 2;
            var node2Shape = new PointShapeContent(new Point(0.0, 1.0));

            var segment1Record = new RoadSegmentChangeDbaseRecord();

            segment1Record.WS_OIDN.Value    = 1;
            segment1Record.B_WK_OIDN.Value  = 1;
            segment1Record.E_WK_OIDN.Value  = 2;
            segment1Record.TGBEP.Value      = (short)RoadSegmentAccessRestriction.PublicRoad.Translation.Identifier;
            segment1Record.STATUS.Value     = RoadSegmentStatus.InUse.Translation.Identifier;
            segment1Record.WEGCAT.Value     = RoadSegmentCategory.SecondaryRoad.Translation.Identifier;
            segment1Record.METHODE.Value    = (short)RoadSegmentGeometryDrawMethod.Measured.Translation.Identifier;
            segment1Record.MORFOLOGIE.Value = (short)RoadSegmentMorphology.Motorway.Translation.Identifier;
            segment1Record.LSTRNMID.Value   = 123;
            segment1Record.RSTRNMID.Value   = 456;
            segment1Record.BEHEERDER.Value  = "-8";
            segment1Record.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;
            var segmentShape = new PolyLineMShapeContent(GeometryTranslator.FromGeometryMultiLineString(new NetTopologySuite.Geometries.MultiLineString(new NetTopologySuite.Geometries.LineString[]
            {
                new NetTopologySuite.Geometries.LineString(new NetTopologySuite.Geometries.Implementation.CoordinateArraySequence(new[]
                {
                    new NetTopologySuite.Geometries.CoordinateM(0.0, 0.0, 0.0),
                    new NetTopologySuite.Geometries.CoordinateM(0.0, 1.0, 1.0)
                }), GeometryConfiguration.GeometryFactory)
            })));

            var laneRecord = new RoadSegmentLaneChangeDbaseRecord();

            laneRecord.RS_OIDN.Value    = 1;
            laneRecord.WS_OIDN.Value    = 1;
            laneRecord.RICHTING.Value   = (short)RoadSegmentLaneDirection.Independent.Translation.Identifier;
            laneRecord.AANTAL.Value     = 2;
            laneRecord.VANPOSITIE.Value = 0.0;
            laneRecord.TOTPOSITIE.Value = 1.0;
            laneRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var surfaceRecord = new RoadSegmentSurfaceChangeDbaseRecord();

            surfaceRecord.WV_OIDN.Value    = 1;
            surfaceRecord.WS_OIDN.Value    = 1;
            surfaceRecord.TYPE.Value       = (short)RoadSegmentSurfaceType.SolidSurface.Translation.Identifier;
            surfaceRecord.VANPOSITIE.Value = 0.0;
            surfaceRecord.TOTPOSITIE.Value = 1.0;
            surfaceRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var widthRecord = new RoadSegmentWidthChangeDbaseRecord();

            widthRecord.WB_OIDN.Value    = 1;
            widthRecord.WS_OIDN.Value    = 1;
            widthRecord.BREEDTE.Value    = 1;
            widthRecord.VANPOSITIE.Value = 0.0;
            widthRecord.TOTPOSITIE.Value = 1.0;
            widthRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var nodeDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(2),
                new RoadNodeChangeDbaseSchema());
            var nodeShapeHeader = new ShapeFileHeader(
                ShapeFileHeader.Length.Plus(node1Shape.ContentLength).Plus(node2Shape.ContentLength),
                ShapeType.Point,
                BoundingBox3D
                .FromGeometry(node1Shape.Shape)
                .ExpandWith(
                    BoundingBox3D.FromGeometry(node2Shape.Shape)
                    )
                );

            // node

            using (var nodeDbaseFile = new BinaryWriter(File.OpenWrite("output/WEGKNOOP_ALL.dbf")))
                using (var nodeDbaseWriter = new DbaseBinaryWriter(nodeDbaseHeader, nodeDbaseFile))
                {
                    nodeDbaseWriter.Write(node1Record);
                    nodeDbaseWriter.Write(node2Record);
                }
            using (var nodeShapeIndexFile = new BinaryWriter(File.OpenWrite("output/WEGKNOOP_ALL.shx")))
                using (var nodeShapeFile = new BinaryWriter(File.OpenWrite("output/WEGKNOOP_ALL.shp")))
                    using (var nodeShapeWriter = new ShapeBinaryWriter(nodeShapeHeader, nodeShapeFile))
                        using (var nodeShapeIndexWriter =
                                   new ShapeIndexBinaryWriter(nodeShapeHeader.ForIndex(new ShapeRecordCount(2)), nodeShapeIndexFile))
                        {
                            var node1ShapeRecord = node1Shape.RecordAs(RecordNumber.Initial);
                            nodeShapeWriter.Write(node1ShapeRecord);
                            var node2ShapeRecord = node2Shape.RecordAs(RecordNumber.Initial.Next());
                            nodeShapeWriter.Write(node2ShapeRecord);

                            var offset = ShapeIndexRecord.InitialOffset;
                            var node1ShapeIndexRecord = node1ShapeRecord.IndexAt(offset);
                            var node2ShapeIndexRecord = node2ShapeRecord.IndexAt(offset.Plus(node1ShapeRecord.Length));
                            nodeShapeIndexWriter.Write(node1ShapeIndexRecord);
                            nodeShapeIndexWriter.Write(node2ShapeIndexRecord);
                        }

            // segment

            var segmentDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new RoadSegmentChangeDbaseSchema());
            var segmentShapeHeader = new ShapeFileHeader(
                ShapeFileHeader.Length.Plus(segmentShape.ContentLength),
                ShapeType.PolyLineM,
                BoundingBox3D
                .FromGeometry(segmentShape.Shape)
                );

            using (var segmentDbaseFile = new BinaryWriter(File.OpenWrite("output/WEGSEGMENT_ALL.dbf")))
                using (var segmentDbaseWriter = new DbaseBinaryWriter(segmentDbaseHeader, segmentDbaseFile))
                {
                    segmentDbaseWriter.Write(segment1Record);
                }
            using (var segmentShapeIndexFile = new BinaryWriter(File.OpenWrite("output/WEGSEGMENT_ALL.shx")))
                using (var segmentShapeFile = new BinaryWriter(File.OpenWrite("output/WEGSEGMENT_ALL.shp")))
                    using (var segmentShapeWriter = new ShapeBinaryWriter(segmentShapeHeader, segmentShapeFile))
                        using (var segmentShapeIndexWriter =
                                   new ShapeIndexBinaryWriter(segmentShapeHeader.ForIndex(new ShapeRecordCount(2)), segmentShapeIndexFile))
                        {
                            var segment1ShapeRecord = segmentShape.RecordAs(RecordNumber.Initial);
                            segmentShapeWriter.Write(segment1ShapeRecord);

                            var offset = ShapeIndexRecord.InitialOffset;
                            var segment1ShapeIndexRecord = segment1ShapeRecord.IndexAt(offset);
                            segmentShapeIndexWriter.Write(segment1ShapeIndexRecord);
                        }

            // lane
            var laneDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new RoadSegmentLaneChangeDbaseSchema());

            using (var laneDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTRIJSTROKEN_ALL.DBF")))
                using (var laneDbaseWriter = new DbaseBinaryWriter(laneDbaseHeader, laneDbaseFile))
                {
                    laneDbaseWriter.Write(laneRecord);
                }

            // width
            var widthDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new RoadSegmentWidthChangeDbaseSchema());

            using (var widthDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTWEGBREEDTE_ALL.DBF")))
                using (var widthDbaseWriter = new DbaseBinaryWriter(widthDbaseHeader, widthDbaseFile))
                {
                    widthDbaseWriter.Write(widthRecord);
                }

            // surface
            var surfaceDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new RoadSegmentSurfaceChangeDbaseSchema());

            using (var surfaceDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTWEGVERHARDING_ALL.DBF")))
                using (var surfaceDbaseWriter = new DbaseBinaryWriter(surfaceDbaseHeader, surfaceDbaseFile))
                {
                    surfaceDbaseWriter.Write(surfaceRecord);
                }

            // european road
            var europeanRoadRecord = new EuropeanRoadChangeDbaseRecord();

            europeanRoadRecord.EU_OIDN.Value    = 1;
            europeanRoadRecord.WS_OIDN.Value    = 1;
            europeanRoadRecord.EUNUMMER.Value   = EuropeanRoadNumber.E40.ToString();
            europeanRoadRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var europeanDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new EuropeanRoadChangeDbaseSchema());

            using (var europeanDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTEUROPWEG_ALL.DBF")))
                using (var europeanDbaseWriter = new DbaseBinaryWriter(europeanDbaseHeader, europeanDbaseFile))
                {
                    europeanDbaseWriter.Write(europeanRoadRecord);
                }

            // national road
            var nationalRoadRecord = new NationalRoadChangeDbaseRecord();

            nationalRoadRecord.NW_OIDN.Value    = 1;
            nationalRoadRecord.WS_OIDN.Value    = 1;
            nationalRoadRecord.IDENT2.Value     = NationalRoadNumber.All[5].ToString();
            nationalRoadRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var nationalDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new NationalRoadChangeDbaseSchema());

            using (var nationalDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTNATIONWEG_ALL.DBF")))
                using (var nationalDbaseWriter = new DbaseBinaryWriter(nationalDbaseHeader, nationalDbaseFile))
                {
                    nationalDbaseWriter.Write(nationalRoadRecord);
                }

            // numbered road
            var numberedRoadRecord = new NumberedRoadChangeDbaseRecord();

            numberedRoadRecord.GW_OIDN.Value    = 1;
            numberedRoadRecord.WS_OIDN.Value    = 1;
            numberedRoadRecord.IDENT8.Value     = NumberedRoadNumber.Parse("A0001231").ToString();
            numberedRoadRecord.RICHTING.Value   = (short)RoadSegmentNumberedRoadDirection.Backward.Translation.Identifier;
            numberedRoadRecord.VOLGNUMMER.Value = 1;
            numberedRoadRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var numberedDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new NumberedRoadChangeDbaseSchema());

            using (var numberedDbaseFile = new BinaryWriter(File.OpenWrite("output/ATTGENUMWEG_ALL.DBF")))
                using (var numberedDbaseWriter = new DbaseBinaryWriter(numberedDbaseHeader, numberedDbaseFile))
                {
                    numberedDbaseWriter.Write(numberedRoadRecord);
                }

            // grade separated junction
            var gradeSeparatedJunctionRecord = new GradeSeparatedJunctionChangeDbaseRecord();

            gradeSeparatedJunctionRecord.OK_OIDN.Value    = 1;
            gradeSeparatedJunctionRecord.BO_WS_OIDN.Value = 1;
            gradeSeparatedJunctionRecord.ON_WS_OIDN.Value = 1;
            gradeSeparatedJunctionRecord.TYPE.Value       = (short)GradeSeparatedJunctionType.Unknown.Translation.Identifier;
            gradeSeparatedJunctionRecord.RECORDTYPE.Value = (short)RecordType.Added.Translation.Identifier;

            var gradeSeparatedJunctionDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                new GradeSeparatedJunctionChangeDbaseSchema());

            using (var gradeSeparatedJunctionDbaseFile = new BinaryWriter(File.OpenWrite("output/RLTOGKRUISING_ALL.DBF")))
                using (var gradeSeparatedJunctionDbaseWriter = new DbaseBinaryWriter(gradeSeparatedJunctionDbaseHeader, gradeSeparatedJunctionDbaseFile))
                {
                    gradeSeparatedJunctionDbaseWriter.Write(gradeSeparatedJunctionRecord);
                }


            // transaction zone
            var transactionZoneRecord = new TransactionZoneDbaseRecord();

            transactionZoneRecord.ORG.Value        = "11053";
            transactionZoneRecord.OPERATOR.Value   = "Yves Reynhout";
            transactionZoneRecord.TYPE.Value       = 1;
            transactionZoneRecord.SOURCE_ID.Value  = 1;
            transactionZoneRecord.BESCHRIJV.Value  = "Nieuwe wijk";
            transactionZoneRecord.APPLICATIE.Value = "Wegenregister BLL";

            var transactionZoneDbaseHeader = new DbaseFileHeader(
                DateTime.Now,
                DbaseCodePage.Western_European_ANSI,
                new DbaseRecordCount(1),
                TransactionZoneDbaseRecord.Schema);

            using (var transactionZoneDbaseFile = new BinaryWriter(File.OpenWrite("output/TRANSACTIEZONE.DBF")))
                using (var transactionZoneDbaseWriter = new DbaseBinaryWriter(transactionZoneDbaseHeader, transactionZoneDbaseFile))
                {
                    transactionZoneDbaseWriter.Write(transactionZoneRecord);
                }

            var suffix =
                DateTimeOffset.UtcNow.ToString("yyyyMMdd") + "-" +
                Convert.ToInt32(DateTimeOffset.UtcNow.TimeOfDay.TotalSeconds);

            using (var archiveStream = File.OpenWrite($"output/oplading-{suffix}.zip"))
                using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create))
                {
                    foreach (var file in Directory.EnumerateFiles("output"))
                    {
                        if (file.ToLowerInvariant().EndsWith(".dbf") ||
                            file.ToLowerInvariant().EndsWith(".shp") ||
                            file.ToLowerInvariant().EndsWith(".shx"))
                        {
                            var entry = archive.CreateEntry(Path.GetFileName(file));
                            using (var fileStream = File.OpenRead(file))
                                using (var entryStream = entry.Open())
                                {
                                    fileStream.CopyTo(entryStream);
                                }
                        }
                    }
                }
        }