public async Task <DomainResult> Handle(UpdateRouteCommand command, CancellationToken cancellationToken) { var origin = await _pointRepository.FindAsync(command.OriginPointId); var destination = await _pointRepository.FindAsync(command.DestinationPointId); if (origin is null || destination is null) { return(DomainResult.Failure <string>("Origin or Destination not found")); } var route = await _routeRepository.FindAsync(command.Id); if (route is null) { return(DomainResult.Failure <string>("Route not found")); } var arePointsChanged = route.ArePointsChanged(origin, destination); route.Update(origin, destination); if (arePointsChanged && await _routeRepository.AlreadyExistsAsync(x => route.IsTheSame(x))) { return(DomainResult.Failure <string>("Route already exists", HttpStatusCode.Conflict)); } await _routeRepository.UpdateAsync(route); await _mediator.Publish(new RouteUpdatedEvent(route)); return(DomainResult.Ok()); }
/// <summary> /// Find best route using A* Algorithm /// </summary> /// <param name="mapPoint1Id"></param> /// <param name="mapPoint2Id"></param> /// <returns></returns> public async Task <KnownRoute> FindBestRouteAsync(Guid mapPoint1Id, Guid mapPoint2Id) { var routes = await routeRepository .FindAsync(r => (r.ToId.Equals(mapPoint1Id) || r.FromId.Equals(mapPoint1Id)) && (r.FromId != mapPoint2Id || r.FromId != mapPoint2Id)); var initial = routes.Select(r => new { RouteId = r.Id, FullPath = r.ToId.Equals(mapPoint1Id) ? new List <Guid> { r.ToId, r.FromId } : new List <Guid> { r.FromId, r.ToId }, Cost = r.Cost, Time = r.Time }).ToList(); var visited = initial.Select(r => r.RouteId).Distinct().ToList(); for (int i = 0; i < initial.Count(); i++) { var nextEl = initial.ElementAt(i); routes = await routeRepository .FindAsync(r => !visited.Contains(r.Id) && (r.ToId.Equals(nextEl.FullPath.Last()) || r.FromId.Equals(nextEl.FullPath.Last())) && !nextEl.FullPath.Take(nextEl.FullPath.Count() - 1).Contains(r.ToId) && !nextEl.FullPath.Take(nextEl.FullPath.Count() - 1).Contains(r.FromId)); var iteration = routes.Select(r => new { RouteId = r.Id, FullPath = nextEl.FullPath.Append(r.ToId.Equals(nextEl.FullPath.Last()) ? r.FromId : r.ToId).ToList(), Cost = nextEl.Cost + r.Cost, Time = nextEl.Time + r.Time }).ToList(); initial.AddRange(iteration); visited.AddRange(iteration.Select(r => r.RouteId)); } var chosenRoute = initial.OrderBy(r => r.Time) .FirstOrDefault(r => r.FullPath.First().Equals(mapPoint1Id) && r.FullPath.Last().Equals(mapPoint2Id)); if (chosenRoute == null) { return(null); } return(new KnownRoute(chosenRoute.FullPath, chosenRoute.Time, chosenRoute.Cost)); }