-
Notifications
You must be signed in to change notification settings - Fork 2
Routing Service
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
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}
}
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.
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
}
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
- 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
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
}
routes, err := service.GetTeamRoutes(&routing.RouteQuery{Limit: 10, Offset: 5})
if err != nil {
//handle errors
return
}
//do something with routes
routeID, err := service.GetRouteID("problem-id")
if err != nil {
t.Error(err)
return
}
//Do something with routeID
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
}
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
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
}
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
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
}
- 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.
optimizations, err := service.GetOptimizations(&RouteQuery{Limit: 5})
if err != nil {
//handle errors
return
}
//do something with optimizations
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
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.
- Activity
- Addressbook
- Routing
- Single Driver Route 10 Stops
- Single Driver Round Trip
- Single Depot Multiple Driver No Time Windows
- Single Depot Multiple Driver Time Windows
- Multiple Depot Multiple Driver
- Multiple Depot Multiple Driver With Time Windows
- Multiple Depot Multiple Driver With Time Windows (24 Stops)
- Tracking
- Geocoding
- Users
- Territories
- Orders
- Vehicles
- Telematics