Ejemplo n.º 1
0
        private async Task <List <RouteNetworkEvent> > InsertReplacementRouteSegments(List <RouteSegment> routeSegments)
        {
            var routeNetworkEvents = new List <RouteNetworkEvent>();

            foreach (var routeSegment in routeSegments)
            {
                await _geoDatabase.InsertRouteSegment(routeSegment);

                var startRouteNode = (await _geoDatabase.GetIntersectingStartRouteNodes(routeSegment)).FirstOrDefault();
                var endRouteNode   = (await _geoDatabase.GetIntersectingEndRouteNodes(routeSegment)).FirstOrDefault();

                var routeSegmentAddedEvent = _routeSegmentEventFactory.CreateAdded(routeSegment, startRouteNode, endRouteNode);
                routeNetworkEvents.Add(routeSegmentAddedEvent);
            }

            return(routeNetworkEvents);
        }
Ejemplo n.º 2
0
        public async Task Handle(RouteSegmentConnectivityChanged request, CancellationToken token)
        {
            _logger.LogInformation($"Starting {nameof(RouteSegmentConnectivityChangedHandler)}");

            var startNode = (await _geoDatabase.GetIntersectingStartRouteNodes(request.After)).FirstOrDefault();
            var endNode   = (await _geoDatabase.GetIntersectingEndRouteNodes(request.After)).FirstOrDefault();

            if ((!(startNode is null) && !(endNode is null)) && startNode.Mrid == endNode.Mrid)
            {
                _logger.LogWarning($"Reverting RouteSegment with mrid '{request.After.Mrid}', because of both ends intersecting with the same RouteNode with mrid '{startNode.Mrid}'");
                await _geoDatabase.UpdateRouteSegment(request.Before);

                return;
            }

            var routeNetworkEvents = new List <RouteNetworkEvent>();

            if (startNode is null)
            {
                startNode = _routeNodeFactory.Create(request.After.FindStartPoint());
                var insertRouteNodeEvent = await InsertRouteNode(startNode);

                routeNetworkEvents.Add(insertRouteNodeEvent);
            }
            else if (_applicationSettings.EnableSegmentEndsAutoSnappingToRouteNode)
            {
                var lineString = request.After.GetLineString();
                lineString.Coordinates[0] = new Coordinate(startNode.GetPoint().Coordinate);
                request.After.Coord       = lineString.AsBinary();
                await _geoDatabase.UpdateRouteSegment(request.After);
            }

            if (endNode is null)
            {
                endNode = _routeNodeFactory.Create(request.After.FindEndPoint());
                var insertRouteNodeEvent = await InsertRouteNode(endNode);

                routeNetworkEvents.Add(insertRouteNodeEvent);
            }
            else if (_applicationSettings.EnableSegmentEndsAutoSnappingToRouteNode)
            {
                var lineString = request.After.GetLineString();
                lineString.Coordinates[lineString.Coordinates.Count() - 1] = new Coordinate(endNode.GetPoint().Coordinate);
                request.After.Coord = lineString.AsBinary();
                await _geoDatabase.UpdateRouteSegment(request.After);
            }

            var(routeSegmentClone, routeSegmentAddedEvent) = await InsertRouteSegmentClone(request.After);

            routeNetworkEvents.Add(routeSegmentAddedEvent);

            var routeSegmentMarkedForDeletionEvent = await MarkRouteSegmentForDeletion(request.Before);

            routeNetworkEvents.Add(routeSegmentMarkedForDeletionEvent);

            var beforeStartNode             = (await _geoDatabase.GetIntersectingStartRouteNodes(request.Before)).FirstOrDefault();
            var beforeEndNode               = (await _geoDatabase.GetIntersectingEndRouteNodes(request.Before)).FirstOrDefault();
            var isBeforeStartNodeDeleteable = await IsRouteNodeDeleteable(beforeStartNode);

            var isBeforeEndNodeDeletable = await IsRouteNodeDeleteable(beforeEndNode);

            if (isBeforeStartNodeDeleteable)
            {
                var routeNodeMarkedForDeletionEvent = await MarkDeleteRouteNode(beforeStartNode);

                routeNetworkEvents.Add(routeNodeMarkedForDeletionEvent);
            }

            if (isBeforeEndNodeDeletable)
            {
                var routeNodeMarkedForDeletionEvent = await MarkDeleteRouteNode(beforeEndNode);

                routeNetworkEvents.Add(routeNodeMarkedForDeletionEvent);
            }

            var cmdId = Guid.NewGuid();
            var routeSegmentConnectivityChangedEvent = new RouteNetworkCommand(nameof(RouteSegmentConnectivityChanged), cmdId, routeNetworkEvents.ToArray());

            _eventStore.Insert(routeSegmentConnectivityChangedEvent);
        }
        public async Task <IEnumerable <INotification> > CreateUpdatedEvent(RouteSegment before, RouteSegment after)
        {
            var routeSegmentShadowTableBeforeUpdate = await _geoDatabase.GetRouteSegmentShadowTable(after.Mrid);

            if (routeSegmentShadowTableBeforeUpdate is null)
            {
                return new List <INotification> {
                           new DoNothing($"{nameof(RouteSegment)} is already deleted, therefore do nothing")
                }
            }
            ;

            if (AlreadyUpdated(after, routeSegmentShadowTableBeforeUpdate))
            {
                return new List <INotification> {
                           new DoNothing($"{nameof(RouteSegment)} is already updated, therefore do nothing.")
                }
            }
            ;

            if (!_routeSegmentValidator.LineIsValid(after.GetLineString()))
            {
                throw new Exception("Linestring is not valid.");
            }

            await _geoDatabase.UpdateRouteSegmentShadowTable(after);

            if (after.MarkAsDeleted)
            {
                return new List <INotification> {
                           CreateRouteSegmentDeleted(after)
                }
            }
            ;

            var intersectingStartSegments = await _geoDatabase.GetIntersectingStartRouteSegments(after);

            var intersectingEndSegments = await _geoDatabase.GetIntersectingEndRouteSegments(after);

            var intersectingStartNodes = await _geoDatabase.GetIntersectingStartRouteNodes(after);

            var intersectingEndNodes = await _geoDatabase.GetIntersectingEndRouteNodes(after);

            var allIntersectingRouteNodesNoEdges = await _geoDatabase.GetAllIntersectingRouteNodesNotIncludingEdges(after);

            if (intersectingStartNodes.Count >= 2 || intersectingEndNodes.Count >= 2)
            {
                throw new Exception("Has more than 2 intersecting start or end nodes.");
            }

            if (await IsGeometryChanged(intersectingStartNodes.FirstOrDefault(), intersectingEndNodes.FirstOrDefault(), routeSegmentShadowTableBeforeUpdate))
            {
                var events = new List <INotification>();
                events.Add(new RouteSegmentLocationChanged {
                    RouteSegment = after
                });

                if (allIntersectingRouteNodesNoEdges.Count > 0)
                {
                    foreach (var intersectingRouteNode in allIntersectingRouteNodesNoEdges)
                    {
                        var routeSegmentSplitted = CreateExistingRouteSegmentSplitted(null, intersectingRouteNode, false);
                        events.Add(routeSegmentSplitted);
                    }
                }

                return(events);
            }

            var notifications = new List <INotification>();

            notifications.AddRange(HandleExistingRouteSegmentSplitted(intersectingStartSegments.Count, intersectingStartNodes.Count, after.FindStartPoint(), after));
            notifications.AddRange(HandleExistingRouteSegmentSplitted(intersectingEndSegments.Count, intersectingEndNodes.Count, after.FindEndPoint(), after));

            notifications.Add(new RouteSegmentConnectivityChanged(before, after));

            return(notifications);
        }
        public async Task Handle(NewRouteSegmentDigitized request, CancellationToken token)
        {
            _logger.LogInformation($"Starting {nameof(NewRouteSegmentDigitizedHandler)}");

            if (request.RouteSegment is null)
            {
                throw new ArgumentNullException($"{nameof(RouteSegment)} cannot be null.");
            }

            var routeSegment = request.RouteSegment;
            var startNode    = (await _geoDatabase.GetIntersectingStartRouteNodes(routeSegment)).FirstOrDefault();
            var endNode      = (await _geoDatabase.GetIntersectingEndRouteNodes(routeSegment)).FirstOrDefault();

            if ((!(startNode is null) && !(endNode is null)) && startNode.Mrid == endNode.Mrid)
            {
                _logger.LogWarning($"Deleting RouteSegment with mrid '{routeSegment.Mrid}', because of both ends intersecting with the same RouteNode with mrid '{startNode.Mrid}'");
                await _geoDatabase.DeleteRouteSegment(routeSegment.Mrid);

                return;
            }

            var routeNetworkEvents = new List <RouteNetworkEvent>();

            if (startNode is null)
            {
                var startPoint = routeSegment.FindStartPoint();
                startNode              = _routeNodeFactory.Create(startPoint);
                startNode.Username     = routeSegment.Username;
                startNode.WorkTaskMrid = routeSegment.WorkTaskMrid;

                await _geoDatabase.InsertRouteNode(startNode);

                var startRouteNodeAddedEvent = _routeNodeEventFactory.CreateAdded(startNode);
                routeNetworkEvents.Add(startRouteNodeAddedEvent);
            }
            else if (_applicationSettings.EnableSegmentEndsAutoSnappingToRouteNode)
            {
                var lineString = routeSegment.GetLineString();
                lineString.Coordinates[0] = new Coordinate(startNode.GetPoint().Coordinate);
                routeSegment.Coord        = lineString.AsBinary();
                await _geoDatabase.UpdateRouteSegment(routeSegment);
            }

            if (endNode is null)
            {
                var endPoint = routeSegment.FindEndPoint();
                endNode              = _routeNodeFactory.Create(endPoint);
                endNode.Username     = routeSegment.Username;
                endNode.WorkTaskMrid = routeSegment.WorkTaskMrid;

                await _geoDatabase.InsertRouteNode(endNode);

                var endRouteNodeAddedEvent = _routeNodeEventFactory.CreateAdded(endNode);
                routeNetworkEvents.Add(endRouteNodeAddedEvent);
            }
            else if (_applicationSettings.EnableSegmentEndsAutoSnappingToRouteNode)
            {
                var lineString = routeSegment.GetLineString();
                lineString.Coordinates[lineString.Coordinates.Count() - 1] = new Coordinate(endNode.GetPoint().Coordinate);
                routeSegment.Coord = lineString.AsBinary();
                await _geoDatabase.UpdateRouteSegment(routeSegment);
            }

            var routeSegmentAddedEvent = _routeSegmentEventFactory.CreateAdded(routeSegment, startNode, endNode);

            routeNetworkEvents.Add(routeSegmentAddedEvent);

            var cmdId = Guid.NewGuid();
            var newRouteSegmentDigitizedCommand = new RouteNetworkCommand(nameof(NewRouteSegmentDigitized), cmdId, routeNetworkEvents.ToArray());

            _eventStore.Insert(newRouteSegmentDigitizedCommand);
        }