func GetNearestDestinationId(startingLat float64, startingLon float64, ids []string) []DistancePriceObject { locationAttributes := model.LocationAttributes{} userResponse := model.UserResponse{} uberEstimate := model.PriceEstimates{} objDistancePrice := DistancePriceObject{} tempStruct := DistancePriceObject{} objDistancePriceArray := DistancePriceArray{} locationAttributes.StartLatitude = startingLat locationAttributes.StartLongitude = startingLon for _, i := range ids { locationId := i if !bson.IsObjectIdHex(locationId) { return nil } objectId := bson.ObjectIdHex(locationId) //Retrieve information about each destination id session, err := mgo.Dial("mongodb://*****:*****@ds041154.mongolab.com:41154/usersdb") if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) err1 := session.DB("usersdb").C("userAddresses").FindId(objectId).One(&userResponse) if err1 != nil { panic(err) } defer session.Close() //Set lattitude and longitude of destination locationAttributes.EndLatitude = userResponse.Coordinates.Lat locationAttributes.EndLongitude = userResponse.Coordinates.Lng uberResponse, err2 := GetUberPriceEstimation(locationAttributes) if err2 != nil { panic(err) } defer session.Close() uberResponseBody, err3 := ioutil.ReadAll(uberResponse) if err3 != nil { panic(err) } defer session.Close() err = json.Unmarshal(uberResponseBody, &uberEstimate) if err != nil { fmt.Println(err.Error()) return nil } objDistancePrice.locationId = locationId objDistancePrice.price = uberEstimate.Prices[0].LowEstimate objDistancePrice.duration = uberEstimate.Prices[0].Duration objDistancePriceArray.AddItem(objDistancePrice) } for i := 0; i < len(objDistancePriceArray.sortedDistanceArray); i++ { for j := i + 1; j < len(objDistancePriceArray.sortedDistanceArray); j++ { if objDistancePriceArray.sortedDistanceArray[i].price > objDistancePriceArray.sortedDistanceArray[j].price { tempStruct = objDistancePriceArray.sortedDistanceArray[i] objDistancePriceArray.sortedDistanceArray[i] = objDistancePriceArray.sortedDistanceArray[j] objDistancePriceArray.sortedDistanceArray[j] = tempStruct } else if objDistancePriceArray.sortedDistanceArray[i].price == objDistancePriceArray.sortedDistanceArray[j].price { if objDistancePriceArray.sortedDistanceArray[i].duration > objDistancePriceArray.sortedDistanceArray[j].duration { tempStruct = objDistancePriceArray.sortedDistanceArray[i] objDistancePriceArray.sortedDistanceArray[i] = objDistancePriceArray.sortedDistanceArray[j] objDistancePriceArray.sortedDistanceArray[j] = tempStruct } } } } return objDistancePriceArray.sortedDistanceArray }
func (uc ConnectionUserDb) CreateTripPlan(rw http.ResponseWriter, req *http.Request, p httprouter.Params) { tripRequest := model.TripRequest{} tripResponse := model.TripResponse{} uberEstimate := model.PriceEstimates{} userResponse := model.UserResponse{} locationAttributes := model.LocationAttributes{} objDistancePriceArray := DistancePriceArray{} isFirstDestination = true isLastDestinationSource = false isLastRequest = false var totalCost int var totalDuration int var totalDistance float64 //Get data from request body, err := ioutil.ReadAll(req.Body) if err != nil { fmt.Println("Fatal error ", err.Error()) } err = json.Unmarshal(body, &tripRequest) if err != nil { fmt.Println("Fatal error ", err.Error()) } //Get the locationId id := tripRequest.StartingLocation StartingLocationFinal = id if !bson.IsObjectIdHex(id) { rw.WriteHeader(404) return } objectId := bson.ObjectIdHex(id) //Get the starting location information if err := uc.session.DB("usersdb").C("userAddresses").FindId(objectId).One(&userResponse); err != nil { rw.WriteHeader(404) return } //Set the starting lattitude and longitude locationAttributes.StartLatitude = userResponse.Coordinates.Lat locationAttributes.StartLongitude = userResponse.Coordinates.Lng ids := tripRequest.LocationIds startLat := locationAttributes.StartLatitude startLon := locationAttributes.StartLongitude var destination []string var locationIdsArray []string var tempIds []string count := len(ids) //Get the best route based on shortest path and cost for i := 0; i < count; i++ { objDistancePriceArray.sortedDistanceArray = GetNearestDestinationId(startLat, startLon, ids) destination = append(destination, objDistancePriceArray.sortedDistanceArray[0].locationId) tempIds = nil for j := 0; j < len(objDistancePriceArray.sortedDistanceArray); j++ { tempIds = append(tempIds, objDistancePriceArray.sortedDistanceArray[j].locationId) } ids = tempIds //Retrieve information about each destination id session, err := mgo.Dial("mongodb://*****:*****@ds041154.mongolab.com:41154/usersdb") if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) objectId := bson.ObjectIdHex(ids[0]) err1 := session.DB("usersdb").C("userAddresses").FindId(objectId).One(&userResponse) if err1 != nil { fmt.Println(err1) } //Set lattitude and longitude of destination startLat = userResponse.Coordinates.Lat startLon = userResponse.Coordinates.Lng if i < count { ids = append(ids[:0], ids[1:]...) } } tripResponse.Id = bson.NewObjectId() tripResponse.Status = "planning" tripResponse.StartingLocation = id tripResponse.BestRoute = destination BestRouteFinal = destination //Append source id for round trip locationIdsArray = append(locationIdsArray, tripRequest.StartingLocation) for i := 0; i < len(destination); i++ { locationIdsArray = append(locationIdsArray, destination[i]) } locationIdsArray = append(locationIdsArray, tripRequest.StartingLocation) for i := 0; i < len(locationIdsArray)-1; i++ { startlocationId := locationIdsArray[i] if !bson.IsObjectIdHex(startlocationId) { rw.WriteHeader(404) return } objectIdLocation := bson.ObjectIdHex(startlocationId) //Retrieve information about each destination id if err := uc.session.DB("usersdb").C("userAddresses").FindId(objectIdLocation).One(&userResponse); err != nil { rw.WriteHeader(404) return } //Set Start Location locationAttributes.StartLatitude = userResponse.Coordinates.Lat locationAttributes.StartLongitude = userResponse.Coordinates.Lng endLocationId := locationIdsArray[i+1] if !bson.IsObjectIdHex(endLocationId) { rw.WriteHeader(404) return } objectIdLocation = bson.ObjectIdHex(endLocationId) //Retrieve information about each destination id if err := uc.session.DB("usersdb").C("userAddresses").FindId(objectIdLocation).One(&userResponse); err != nil { rw.WriteHeader(404) return } //Set lattitude and longitude of destination locationAttributes.EndLatitude = userResponse.Coordinates.Lat locationAttributes.EndLongitude = userResponse.Coordinates.Lng uberResponse, err := GetUberPriceEstimation(locationAttributes) uberResponseBody, err := ioutil.ReadAll(uberResponse) err = json.Unmarshal(uberResponseBody, &uberEstimate) if err != nil { fmt.Println(err.Error()) return } totalCost = totalCost + uberEstimate.Prices[0].LowEstimate totalDuration = totalDuration + uberEstimate.Prices[0].Duration totalDistance = totalDistance + uberEstimate.Prices[0].Distance } tripResponse.TotalCost = totalCost tripResponse.TotalDuration = totalDuration tripResponse.TotalDistance = totalDistance uj, _ := json.Marshal(tripResponse) // Write content-type, statuscode, payload rw.Header().Set("Content-Type", "application/json") rw.WriteHeader(201) fmt.Fprintf(rw, "%s", uj) TotalCostFinal = totalCost TotalDurationFinal = totalDuration TotalDistanceFinal = totalDistance //Save the trip plan in database uc.session.DB("usersdb").C("trips").Insert(tripResponse) }