Skip to content
Maciej Mionskowski edited this page Apr 24, 2016 · 25 revisions

Routing service is the main service you will use. It provides a wrapper for most of the route4me functionality:

  • Managing(running, updating, fetching) optimizations
  • Managing(updating, fetching) routes

Creating Service

import (
	"github.com/route4me/route4me-go-sdk"
	"github.com/route4me/route4me-go-sdk/routing"
)

func main() {
	client := route4me.NewClient("your-api-key")
	service := &routing.Service{Client: client}
}

Addresses

Examples written below assume that you have an []*Address under addresses variable. It's a recurrent theme. You can find the struct definition here. Member names should be self-descriptive. If something's unclear leave an issue or contact support.

Getting address

In order to get an address you have to acquire route-id and route-destination-id. You can extract that data from here.

address, err = service.GetAddress(&routing.AddressQuery{RouteID: "route-id",
RouteDestinationID: "route-destination-id",
Notes: true, //If this is set to true all notes associated with this address will be returned.
})
if err != nil {
	//handle errors
	return
}

Updating address

In order to update an address you have to have it's object first. You can get it by calling either GetRoute or GetAddress

updated, err := service.UpdateAddress(address)
if err != nil {
	//handle errors
	return
}
//do something with updated address

Routes

  • A Route is a collection of addresses usually sorted in the most optimal sequence
  • One route can have many addresses
  • Each address can have attributes, constraints, and metadata which influence the way the route is sequenced

Getting Route

In order to get a route you need its ID (route-id). Not specifying the ID field will result in an error being returned.

route, err = service.GetRoute(&routing.RouteQuery{ID: route-id})
if err != nil {
	//handle errors
	return
}

Getting Team Routes

routes, err := service.GetTeamRoutes(&routing.RouteQuery{Limit: 10, Offset: 5})
if err != nil {
	//handle errors
	return
}
//do something with routes

Getting Route ID from Optimization Problem ID (problem-id)

routeID, err := service.GetRouteID("problem-id")
if err != nil {
	t.Error(err)
	return
}
//Do something with routeID

Deleting Routes

In order to delete routes You need to know their ids (route-id). You can fetch them by calling GetTeamRoutes().

routes, err = service.DeleteRoutes([]string{"route-id"})
if err != nil {
	//handle errors
	return
}

Updating Route

In order to update the Route you need to have it's id(route-id). It's recommended to use [GetTeamRoutes]https://github.com/route4me/route4me-go-sdk/wiki/Routing-Service#getting-team-routes) to fetch instances.

  • Updating a route supports the Reoptimize: True parameter, which reoptimizes only that route. Also supports the parameters from GET.
  • By sending RecomputeDirections=1 we request that the route directions be recomputed (note that this does happen automatically if certain properties of the route are updated, such as stop sequence_no changes or round-tripness)
  • After updating the route there is no guarantee that the route_destination_id values are preserved! It may create copies resulting in new destination IDs, especially when dealing with multiple depots.
updated, err := service.UpdateRoute(route)
if err != nil {
	//handle errors
	return
}
//do something with updated route

Duplicating Route

Duplicates the route by accepting route-id. The duplicated route has all the same metadata and account ownership information as the original route. However, route notes and visited status flags are not copied into the new route. The name of the new route is automatically appended with the string " (Duplicate)" to indicate that the route is a duplicate route. There is currently no special designation inside the database to indicate that a route originated from another route.

duplicated, err := service.DuplicateRoute(`route-id`)
if err != nil {
	//handle errors
	return
}

Notes

Getting Address Notes

In order to get address notes you have to acquire route_id and address_id. You can do that by calling GetRoute()

query := &NoteQuery{
	RouteID:   "route_id",
	AddressID: "address_id",
}
notes, err := service.GetAddressNotes(query)
if err != nil {
	//handle errors
	return
}
// do something with address notes

Adding a Note to an Address

In order to add a note to an address you have to acquire route_id and address_id. You can do that by calling GetRoute()

query := &NoteQuery{
	RouteID:      get.ID,
	AddressID:    get.Addresses[0].RouteDestinationID.String(),
	Latitude:     33.132675170898,
	Longitude:    -83.244743347168,
	ActivityType: DropOff,
}
addedNote, err = service.AddAddressNote(query, "Note Contents")
if err != nil {
	//handle errors
	return
}

Optimizations

  • An Optimization Problem is a collection of addresses that need to be visited.
  • The optimization problem takes into consideration all of the addresses that need to be visited and all the constraints associated with each address and depot.
  • It is preferable to create an optimization problem with as many orders in it as possible, so that the optimization engine is able to consider the entire problem set.
  • This is different from a Route, which is a sequence of addresses that need to be visited by a single vehicle and a single driver in a fixed time period. Solving an Optimization Problem results in a number of routes. Possibly in the future they may also be recurring.

Getting Optimizations

optimizations, err := service.GetOptimizations(&RouteQuery{Limit: 5})
if err != nil {
	//handle errors
	return
}
//do something with optimizations

Getting a single optimization

In order to get a single optimization you need to obtain the ID. You can do it by calling GetOptimizations

optimization, err = service.GetOptimization(&OptimizationParameters{ProblemID: optimizations[0].ProblemID})
if err != nil {
	//handler errors
	return
}
//do something with optimization

Running optimization

There are multiple configurations of running the route. Examples from C# SDK might be helpful to understand the whole process.

Let's take a look at AlgorithmType:

//AlgorithmType is a type of algorithm used for optimization
type AlgorithmType uint

const (
	//TSP stands for single depot, single driver route
	TSP AlgorithmType = iota + 1
	//VRP stands for single depot, multiple driver, no constraints, no time windows, no capacities
	VRP
	//CVRP_TW_SD stands for single depot, multiple driver, capacitated, time windows
	CVRP_TW_SD
	//CVRP_TW_MD stands for multiple depot, multiple driver, capacitated, time windows
	CVRP_TW_MD
	//TSP_TW stands for single depot, single driver, time windows
	TSP_TW
	//TSP_TW_CR stands for single depot, single driver, time windows, continuous optimization (minimal location shifting)
	TSP_TW_CR
	//BBCVRP stands for shifts addresses from one route to another over time on a recurring schedule
	BBCVRP
)

These options describe what type of optimization should be created. We need to specify RouteParameters

routeParams := &routing.RouteParameters{
	AlgorithmType:        routing.CVRP_TW_MD,
	Name:                 "Multiple Depot, Multiple Driver",
	RouteDate:            time.Now().Unix(),
	RouteTime:            60 * 60 * 7,
	RouteMaxDuration:     86400,
	VehicleCapacity:      1,
	VehicleMaxDistanceMI: 1000,
	Optimize:             routing.Distance,
	DistanceUnit:         routing.Miles,
	DeviceType:           routing.Web,
	TravelMode:           routing.Driving,
}

Members should be self-descriptive, they correspond to the route4me web UI.

Once route parameters are set up we need to wrap it with addresses and execute the optimization.

optParams := &routing.OptimizationParameters{
	Addresses:  addresses,
	Parameters: routeParams,
}
optimization, err := service.RunOptimization(optParams)
if err != nil {
	//handle errors
	return
}
//do something with optimization

The returned object will not contain the optimized route, you have to keep calling GetOptimization to fetch the current status.

You can look at service's test file for more implementation details.