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); }
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 } }); }