Example #1
0
        private async Task <RouteSegment> GetIntersectingRouteSegment(RouteSegment routeSegmentDigitizedByUser, RouteNode routeNode)
        {
            RouteSegment intersectingRouteSegment = null;

            // This is if triggered by RouteNodeDigitizedByUser
            if (routeSegmentDigitizedByUser is null)
            {
                intersectingRouteSegment = await HandleIntersectionSplit(routeNode);
            }
            // This is required in case that this event was triggered by RouteSegmentDigtizedByUser
            else
            {
                intersectingRouteSegment = (await _geoDatabase.GetIntersectingRouteSegments(routeNode, routeSegmentDigitizedByUser)).First();
            }

            return(intersectingRouteSegment);
        }
        public async Task Handle(RouteNodeLocationChanged request, CancellationToken token)
        {
            _logger.LogInformation($"Starting {nameof(RouteNodeLocationChangedHandler)}");

            var intersectingSegmentsBeforeChange = (await _geoDatabase.GetIntersectingRouteSegments(request.RouteNodeBefore.Coord)).ToList();
            var routeSegmentsToBeUpdated         = new List <RouteSegment>();

            if (intersectingSegmentsBeforeChange.Count > 0)
            {
                var anySegmentIntersectRouteNode = false;
                foreach (var intersectingSegment in intersectingSegmentsBeforeChange)
                {
                    var startNode = (await _geoDatabase.GetIntersectingStartRouteNodes(intersectingSegment)).FirstOrDefault();

                    if (startNode is null)
                    {
                        var lineString = intersectingSegment.GetLineString();
                        lineString.Coordinates[0] = new Coordinate(request.RouteNodeAfter.GetPoint().Coordinate);
                        intersectingSegment.Coord = lineString.AsBinary();
                    }
                    else
                    {
                        var lineString = intersectingSegment.GetLineString();
                        lineString.Coordinates[lineString.Coordinates.Count() - 1] = new Coordinate(request.RouteNodeAfter.GetPoint().Coordinate);
                        intersectingSegment.Coord = lineString.AsBinary();
                    }

                    anySegmentIntersectRouteNode = (await _geoDatabase.GetAllIntersectingRouteNodesNotIncludingEdges(intersectingSegment.Coord, intersectingSegment.Mrid)).Any();
                    if (anySegmentIntersectRouteNode)
                    {
                        break;
                    }

                    routeSegmentsToBeUpdated.Add(intersectingSegment);
                }

                // Rollback in case of segment intersecting with any route nodes
                if (anySegmentIntersectRouteNode)
                {
                    throw new Exception("Route segments intersects with any route nodes");
                }
            }

            var routeNetworkEvents = new List <RouteNetworkEvent>();

            var routeNodeGeometryModifiedEvent = _routeNodeEventFactory.CreateGeometryModified(request.RouteNodeAfter);

            routeNetworkEvents.Add(routeNodeGeometryModifiedEvent);

            for (var i = 0; i < routeSegmentsToBeUpdated.Count; i++)
            {
                var routeSegmentToBeUpdated = routeSegmentsToBeUpdated[i];
                await _geoDatabase.UpdateRouteSegment(routeSegmentToBeUpdated);

                var routeSegmentGeometryModifiedEvent = _routeSegmentEventFactory.CreateGeometryModified(routeSegmentToBeUpdated, true);
                routeNetworkEvents.Add(routeSegmentGeometryModifiedEvent);
            }

            var cmdId = Guid.NewGuid();
            var routeNodeLocationChangedCommand = new RouteNetworkCommand(nameof(RouteNodeLocationChanged), cmdId, routeNetworkEvents.ToArray());

            _eventStore.Insert(routeNodeLocationChangedCommand);
        }
Example #3
0
        public async Task <List <INotification> > CreateUpdatedEvent(RouteNode before, RouteNode after)
        {
            if (before is null || after is null)
            {
                throw new ArgumentNullException($"Parameter {nameof(before)} or {nameof(after)} cannot be null");
            }

            var shadowTableNode = await _geoDatabase.GetRouteNodeShadowTable(after.Mrid);

            if (shadowTableNode is null)
            {
                return new List <INotification> {
                           new DoNothing($"{nameof(RouteNode)} is already deleted, so do nothing.")
                }
            }
            ;

            if (AlreadyUpdated(after, shadowTableNode))
            {
                return new List <INotification> {
                           new DoNothing($"{nameof(RouteNode)} with id: '{after.Mrid}' was already updated therefore do nothing.")
                }
            }
            ;

            await _geoDatabase.UpdateRouteNodeShadowTable(after);

            if (!(await IsValidNodeUpdate(before, after)))
            {
                return new List <INotification> {
                           new RollbackInvalidRouteNode(before, "Is not a valid route node update")
                }
            }
            ;

            // We roll back in-case the update-command intersects with new route-segments
            var intersectingRouteSegments = await _geoDatabase.GetIntersectingRouteSegments(after);

            if (intersectingRouteSegments.Count > 0)
            {
                var previousIntersectingRouteSegments = await _geoDatabase.GetIntersectingRouteSegments(before.Coord);

                var newIntersectingRouteSegments = intersectingRouteSegments
                                                   .Where(x => !previousIntersectingRouteSegments.Any(y => y.Mrid == x.Mrid)).ToList();
                if (newIntersectingRouteSegments.Count > 0)
                {
                    return new List <INotification> {
                               new RollbackInvalidRouteNode(before, "Update to route node is invalid because it is insecting with route-segments.")
                    }
                }
                ;
            }

            if (after.MarkAsDeleted)
            {
                return new List <INotification> {
                           new RouteNodeDeleted {
                               RouteNode = after
                           }
                }
            }
            ;

            return(new List <INotification> {
                new RouteNodeLocationChanged {
                    RouteNodeAfter = after, RouteNodeBefore = before
                }
            });
        }