예제 #1
0
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
}
예제 #2
0
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)
}