public TrackingInformationModel TrackParcel(string parcelCode) { try { TrackingInformationModel result = new TrackingInformationModel(); // i. Validation of Tracking Code ParcelModel parcel = _trackingLogic.GetParcelByCode(parcelCode); _trackingLogic.ValidateParcel(parcel); // ii. Get all previously visited hops for package from DB result.VisitedHops = _trackingLogic.GetAllPastHops(parcel) as List <HopArrivalModel>; // iii. Predict future hops to final destination // 1.Do a GPS distance search e.g. // https://dotnet-snippets.de/snippet/entfernung-zwischen-zwei-geografischen-koordinaten-berechnen/828 // 2.Find the closest Truck // 3.Find the truck’s warehouse, the warehouses parent warehouse, etc. // until you reach the last PAST hop. List <TruckModel> trucks = _warehouseLogic.GetAllTrucks() as List <TruckModel>; TruckModel closestTruck = null; decimal minDistance = decimal.MaxValue; for (int i = 0; i < trucks.Count; i++) { if (trucks[i] == null) { continue; } GeoPoint parcelCoords = new GeoPoint(parcel.Latitude, parcel.Longitude); var distance = (decimal)parcelCoords.DistToOtherInKm(new GeoPoint(trucks[i].Latitude, trucks[i].Longitude)); if (distance < minDistance && trucks[i].Radius >= distance) { closestTruck = trucks[i]; minDistance = distance; } } /*NOT finished, just testing */ HopArrivalModel latestHop; if (result.VisitedHops.Count > 0) { latestHop = result.VisitedHops[result.VisitedHops.Count - 1]; } else { latestHop = null; } result.FutureHops = _warehouseLogic.GetAllFutureHops(latestHop, closestTruck, parcel) as List <HopArrivalModel>; /* end testing */ switch (result.FutureHops.Count) { case 0: result.State = StateEnum.DeliveredEnum; break; case 1: result.State = StateEnum.InTruckDeliveryEnum; break; default: result.State = StateEnum.InTransportEnum; break; } return(result); } catch (Exception ex) { _logger.Error(ex.Message); throw new BLException("BL error tracking parcels: " + ex.Message, ex); } }