Preparing the Steps Parameter
Preparing the steps
Parameter for Toll Calculation
The Adastra Toll API’s steps
parameter is crucial for calculating accurate toll costs for a given route. It requires a specific format: a string of semicolon-separated latitude and longitude pairs, with each coordinate value rounded to exactly 5 decimal places. Failing to adhere to this format can lead to incorrect or failed toll calculations.
This guide will walk you through how to obtain and format the steps
parameter correctly, specifically focusing on data retrieved from Google Maps Platform APIs.
steps
Parameter Format Requirement
- Type:
string
- Description: The route’s coordinates string, representing the path the vehicle will take.
- Format:
"latitude,longitude;latitude,longitude;..."
- Decimal Places: Each latitude and longitude value must be rounded to 5 decimal places.
- Separator: Points must be separated by a semicolon (
;
). Latitude and longitude within a point must be separated by a comma (,
). - Example:
"40.90878,29.31577;41.00305,28.96113;41.00312,28.96123"
Obtaining Route Coordinates from Google Maps Platform
The method you use to generate your route will determine how you extract and prepare the coordinate data. We’ll cover the two primary Google Maps Platform APIs for this purpose:
- Routes API (
routes.googleapis.com/directions/v2:computeRoutes
) - Maps JavaScript API (
google.maps.DirectionsService
)
1. From Google Maps Routes API (computeRoutes
)
The Routes API’s computeRoutes
method returns the route’s geometry as an encodedPolyline
string. This string is a compact, URL-safe representation of the path and needs to be decoded into individual latitude and longitude points before it can be formatted for the Adastra Toll API.
Step 1: Make a computeRoutes
Request
Ensure your computeRoutes
request is configured to return the encodedPolyline
. Using X-Goog-FieldMask: routes.polyline.encodedPolyline
is recommended to optimize the response payload.
Example computeRoutes
Request Body:
{
"origin": {
"location": {
"latLng": {
"latitude": 40.712776,
"longitude": -74.005974
}
}
},
"destination": {
"location": {
"latLng": {
"latitude": 34.052235,
"longitude": -118.243683
}
}
},
"travelMode": "DRIVE",
"routingPreference": "TRAFFIC_AWARE",
"computeAlternativeRoutes": false,
"routeModifiers": {
"avoidFerries": true
},
"languageCode": "en",
"units": "METRIC",
"polylineQuality": "HIGH_QUALITY"
}
Step 2: Decode the encodedPolyline
Once you receive the encodedPolyline
from the Routes API response, you need to decode it into a series of latitude and longitude coordinates. Many client libraries offer built-in polyline decoding functions. If not, you can use a custom decoder.
JavaScript Example (Decoding and Formatting):
// Helper function to decode an encoded polyline string (standard algorithm)
function decodePolyline(encodedPolyline) {
const points = [];
let index = 0;
let lat = 0;
let lng = 0;
while (index < encodedPolyline.length) {
let b;
let shift = 0;
let result = 0;
do {
b = encodedPolyline.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
const dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encodedPolyline.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
const dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
points.push({ latitude: lat / 1e5, longitude: lng / 1e5 });
}
return points;
}
// --- Main logic: Fetching from Routes API, decoding, and formatting ---
const originPayload = { /* ... define your origin ... */ };
const destinationPayload = { /* ... define your destination ... */ };
const googleMapsApiKey = 'YOUR_GOOGLE_MAPS_API_KEY';
async function getFormattedAdastraStepsFromRoutesAPI() {
const routeRequestData = {
origin: originPayload,
destination: destinationPayload,
travelMode: 'DRIVE',
routingPreference: 'TRAFFIC_AWARE',
computeAlternativeRoutes: false,
routeModifiers: { avoidFerries: true },
languageCode: 'en',
units: 'METRIC',
polylineQuality: "HIGH_QUALITY" // Important for detailed routes
};
try {
const response = await fetch(`https://routes.googleapis.com/directions/v2:computeRoutes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Goog-Api-Key': googleMapsApiKey,
'X-Goog-FieldMask': 'routes.polyline.encodedPolyline', // Request only the polyline
},
body: JSON.stringify(routeRequestData),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Routes API Error: ${response.status} - ${errorData.error.message}`);
}
const result = await response.json();
if (result.routes && result.routes.length > 0) {
const encodedPolyline = result.routes[0].polyline.encodedPolyline;
console.log("Routes API Encoded Polyline:", encodedPolyline);
// 1. Decode the polyline into an array of {latitude, longitude} objects
const decodedPoints = decodePolyline(encodedPolyline);
// 2. Format each point to 5 decimal places and join with semicolons
const stepsString = decodedPoints.map(point =>
`${point.latitude.toFixed(5)},${point.longitude.toFixed(5)}`
).join(';');
console.log("Formatted Adastra Toll API Steps String (from Routes API):", stepsString);
return stepsString;
} else {
console.warn("No routes found by Google Routes API.");
return "";
}
} catch (error) {
console.error("Error processing route data from Routes API:", error);
return "";
}
}
// Example usage:
// getFormattedAdastraStepsFromRoutesAPI().then(adastraSteps => {
// if (adastraSteps) {
// console.log("Adastra Toll API 'steps' parameter ready:", adastraSteps);
// // Now you can call the Adastra Toll API with this 'steps' string
// // const adastraTollRequest = { vehicleTypeId: "1", mapsource: "google", steps: adastraSteps };
// // fetch('https://api.adastrai.com/toll?key=YOUR_ADASTRA_API_KEY', { /* ... */ });
// }
// });
2. From Google Maps JavaScript API (DirectionsService
)
When using the google.maps.DirectionsService
(typically in a web browser), the route information is provided in a DirectionsResult
object. This object contains routes
, each with legs
, and each leg
contains steps
. Every step
object has a polyline
property, which itself has a path
property, an array of google.maps.LatLng
objects.
You need to extract these LatLng
objects from all steps, combine them into a single array, and then format them.
Step 1: Perform a DirectionsService.route()
Request
Ensure your DirectionsService
request is made and successfully returns a DirectionsResult
.
JavaScript Example (Extracting and Formatting):
// This function assumes you have a `google.maps.DirectionsResult` object
// obtained from a successful `directionsService.route()` call.
async function getFormattedAdastraStepsFromDirectionsService(directionsResult) {
if (!directionsResult || !directionsResult.routes || directionsResult.routes.length === 0) {
console.warn("No routes found in DirectionsResult.");
return "";
}
const route = directionsResult.routes[0]; // Usually, you'd pick the first route
let allRoutePoints = [];
// Iterate through all legs (segments between waypoints) of the route
for (const leg of route.legs) {
// Iterate through all individual steps within each leg
for (const step of leg.steps) {
// Each step.polyline.path is an array of google.maps.LatLng objects
const stepPoints = step.polyline.path.map(latLng => ({
latitude: latLng.lat(),
longitude: latLng.lng(),
}));
// Concatenate points from this step to the overall list
allRoutePoints = allRoutePoints.concat(stepPoints);
}
}
// 1. Format the combined points to 5 decimal places
// DirectionsService usually provides distinct points, so no explicit deduplication is needed.
const stepsString = allRoutePoints.map(point =>
`${point.latitude.toFixed(5)},${point.longitude.toFixed(5)}`
).join(';');
console.log("Formatted Adastra Toll API Steps String (from DirectionsService):", stepsString);
return stepsString;
}
// Example usage within your DirectionsService callback:
/*
// Assuming 'map' is your google.maps.Map object
// Assuming 'directionsService' is your google.maps.DirectionsService object
// Assuming 'directionsRenderer' is your google.maps.DirectionsRenderer object
function initMapAndCalculateRoute() {
const request = {
origin: "Istanbul, Turkey",
destination: "Ankara, Turkey",
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
avoidFerries: true,
};
directionsService.route(request, function(result, status) {
if (status === google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(result); // Renders the route on the map
getFormattedAdastraStepsFromDirectionsService(result).then(adastraSteps => {
if (adastraSteps) {
console.log("Adastra Toll API 'steps' parameter ready (from DirectionsService):", adastraSteps);
// Now you can call the Adastra Toll API with this 'steps' string
// const adastraTollRequest = { vehicleTypeId: "1", mapsource: "google", steps: adastraSteps };
// fetch('https://api.adastrai.com/toll?key=YOUR_ADASTRA_API_KEY', { /* ... */ });
}
});
} else {
window.alert("Directions request failed due to " + status);
}
});
}
// Call initMapAndCalculateRoute after the Google Maps JavaScript API has loaded.
// Make sure to include the 'routes' library in your API script tag:
// <script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&libraries=routes&callback=initMapAndCalculateRoute"></script>
*/
General JavaScript Formatting Example
If you already have your route points in an array of { latitude: number, longitude: number }
objects, the final formatting step is straightforward:
// This array represents a hypothetical set of route points.
// You would obtain this from a polyline decoder or by extracting from API responses.
const rawRoutePoints = [
{ latitude: 40.90878345, longitude: 29.31577123 },
{ latitude: 41.00305489, longitude: 28.96112578 },
{ latitude: 41.00312345, longitude: 28.96123456 },
{ latitude: 40.90878000, longitude: 29.31577000 }, // Example with more trailing zeros
];
// Format each point to exactly 5 decimal places and join them with semicolons
const formattedStepsString = rawRoutePoints.map(point =>
`${point.latitude.toFixed(5)},${point.longitude.toFixed(5)}`
).join(';');
console.log("General formatted steps string:", formattedStepsString);
// Expected output: "40.90878,29.31577;41.00305,28.96113;41.00312,28.96123;40.90878,29.31577"
// This `formattedStepsString` is now ready to be used as the `steps` parameter
// in your Adastra Toll API request.
Important Considerations for steps
- Decimal Precision: Always ensure you round to exactly 5 decimal places. Using more or fewer decimal places can lead to errors in toll calculation, as the API might not recognize the exact route segments.
- Coordinate Order: The order of
latitude,longitude
pairs in thesteps
string defines the direction of the route. Ensure your points are ordered sequentially from origin to destination. - Completeness: Provide a sufficiently detailed set of
steps
that accurately represents the entire route, especially sections that might include toll roads. Missing segments could result in incomplete or incorrect toll calculations. - API Key: Remember to use your correct Google Maps Platform API Key for routing requests and your Adastra Toll API Key for toll calculation requests.
- Error Handling: Implement robust error handling for both Google Maps API calls and Adastra Toll API calls to gracefully manage issues like invalid routes, API key problems, or unavailable pricing data.
By carefully preparing your steps
parameter using the guidelines and examples above, you can ensure accurate and reliable toll calculations with the Adastra Toll API.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Preparing the Steps Parameter",
"description": "Detailed guide on how to prepare the `steps` parameter for the Adastra Toll API, including examples from Google Maps Routes API and Maps JavaScript API.",
"image": "https://tollapidocs.adastrai.com/featured-image.png",
"author": {
"@type": "Organization",
"name": "Adastra"
},
"publisher": {
"@type": "Organization",
"name": "Adastra",
"logo": {
"@type": "ImageObject",
"url": "https://tollapidocs.adastrai.com/logo.png"
}
},
"datePublished": "2024-01-03T11:30:00+00:00",
"dateModified": "2024-01-03T11:30:00+00:00"
}
</script>