All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mapbox.api.directions.v5.MapboxDirections Maven / Gradle / Ivy

There is a newer version: 5.9.0-alpha.1
Show newest version
package com.mapbox.api.directions.v5;

import androidx.annotation.FloatRange;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.auto.value.AutoValue;
import com.google.gson.GsonBuilder;
import com.mapbox.api.directions.v5.DirectionsCriteria.AnnotationCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.ExcludeCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.GeometriesCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.OverviewCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.ProfileCriteria;
import com.mapbox.api.directions.v5.DirectionsCriteria.VoiceUnitCriteria;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.RouteLeg;
import com.mapbox.api.directions.v5.utils.FormatUtils;
import com.mapbox.core.MapboxService;
import com.mapbox.core.constants.Constants;
import com.mapbox.core.exceptions.ServicesException;
import com.mapbox.core.utils.ApiCallHelper;
import com.mapbox.core.utils.MapboxUtils;
import com.mapbox.geojson.Point;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import okhttp3.EventListener;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * The Directions API allows the calculation of routes between coordinates. The fastest route can be
 * returned with geometries, turn-by-turn instructions, and much more. The Mapbox Directions API
 * supports routing for driving cars (including live traffic), riding bicycles and walking.
 * Requested routes can include as much as 25 coordinates anywhere on earth (except the traffic
 * profile).
 * 

* Requesting a route at a bare minimal must include, a Mapbox access token, destination, and an * origin. *

* * @see Android * Directions documentation * @see Directions API * documentation * @since 1.0.0 */ @AutoValue public abstract class MapboxDirections extends MapboxService { protected MapboxDirections() { super(DirectionsService.class); } @Override protected Call initializeCall() { if (usePostMethod() == null) { return callForUrlLength(); } if (usePostMethod()) { return post(); } return get(); } private Call callForUrlLength() { Call get = get(); if (get.request().url().toString().length() < MAX_URL_SIZE) { return get; } return post(); } private Call get() { return getService().getCall( ApiCallHelper.getHeaderUserAgent(clientAppName()), user(), profile(), FormatUtils.formatCoordinates(coordinates()), accessToken(), alternatives(), geometries(), overview(), radius(), steps(), bearing(), continueStraight(), annotation(), language(), roundaboutExits(), voiceInstructions(), bannerInstructions(), voiceUnits(), exclude(), approaches(), waypointIndices(), waypointNames(), waypointTargets(), enableRefresh(), walkingSpeed(), walkwayBias(), alleyBias() ); } private Call post() { return getService().postCall( ApiCallHelper.getHeaderUserAgent(clientAppName()), user(), profile(), FormatUtils.formatCoordinates(coordinates()), accessToken(), alternatives(), geometries(), overview(), radius(), steps(), bearing(), continueStraight(), annotation(), language(), roundaboutExits(), voiceInstructions(), bannerInstructions(), voiceUnits(), exclude(), approaches(), waypointIndices(), waypointNames(), waypointTargets(), enableRefresh(), walkingSpeed(), walkwayBias(), alleyBias() ); } @Override protected GsonBuilder getGsonBuilder() { return super.getGsonBuilder() .registerTypeAdapterFactory(DirectionsAdapterFactory.create()); } /** * Wrapper method for Retrofits {@link Call#execute()} call returning a response specific to the * Directions API. * * @return the Directions v5 response once the call completes successfully * @throws IOException Signals that an I/O exception of some sort has occurred * @since 1.0.0 */ @Override public Response executeCall() throws IOException { Response response = super.executeCall(); DirectionsResponseFactory factory = new DirectionsResponseFactory(this); return factory.generate(response); } /** * Wrapper method for Retrofits {@link Call#enqueue(Callback)} call returning a response specific * to the Directions API. Use this method to make a directions request on the Main Thread. * * @param callback a {@link Callback} which is used once the {@link DirectionsResponse} is * created. * @since 1.0.0 */ @Override public void enqueueCall(final Callback callback) { getCall().enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { DirectionsResponseFactory factory = new DirectionsResponseFactory(MapboxDirections.this); Response generatedResponse = factory.generate(response); callback.onResponse(call, generatedResponse); } @Override public void onFailure(Call call, Throwable throwable) { callback.onFailure(call, throwable); } }); } @Override protected synchronized OkHttpClient getOkHttpClient() { if (okHttpClient == null) { OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); if (isEnableDebug()) { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BASIC); httpClient.addInterceptor(logging); } Interceptor interceptor = interceptor(); if (interceptor != null) { httpClient.addInterceptor(interceptor); } Interceptor networkInterceptor = networkInterceptor(); if (networkInterceptor != null) { httpClient.addNetworkInterceptor(networkInterceptor); } EventListener eventListener = eventListener(); if (eventListener != null) { httpClient.eventListener(eventListener); } okHttpClient = httpClient.build(); } return okHttpClient; } @NonNull abstract String user(); @NonNull abstract String profile(); @NonNull abstract List coordinates(); @NonNull @Override protected abstract String baseUrl(); @NonNull abstract String accessToken(); @Nullable abstract Boolean alternatives(); @Nullable abstract String geometries(); @Nullable abstract String overview(); @Nullable abstract String radius(); @Nullable abstract String bearing(); @Nullable abstract Boolean steps(); @Nullable abstract Boolean continueStraight(); @Nullable abstract String annotation(); @Nullable abstract String language(); @Nullable abstract Boolean roundaboutExits(); @Nullable abstract String clientAppName(); @Nullable abstract Boolean voiceInstructions(); @Nullable abstract Boolean bannerInstructions(); @Nullable abstract String voiceUnits(); @Nullable abstract String exclude(); @Nullable abstract String approaches(); @Nullable abstract String waypointIndices(); @Nullable abstract String waypointNames(); @Nullable abstract String waypointTargets(); @Nullable abstract Boolean enableRefresh(); @Nullable abstract Interceptor interceptor(); @Nullable abstract Interceptor networkInterceptor(); @Nullable abstract EventListener eventListener(); @Nullable abstract Boolean usePostMethod(); @Nullable abstract WalkingOptions walkingOptions(); @Nullable Double walkingSpeed() { if (!hasWalkingOptions()) { return null; } return walkingOptions().walkingSpeed(); } @Nullable Double walkwayBias() { if (!hasWalkingOptions()) { return null; } return walkingOptions().walkwayBias(); } @Nullable Double alleyBias() { if (!hasWalkingOptions()) { return null; } return walkingOptions().alleyBias(); } private boolean hasWalkingOptions() { return walkingOptions() != null; } /** * Build a new {@link MapboxDirections} object with the initial values set for * {@link #baseUrl()}, {@link #profile()}, {@link #user()}, and {@link #geometries()}. * * @return a {@link Builder} object for creating this object * @since 3.0.0 */ public static Builder builder() { return new AutoValue_MapboxDirections.Builder() .baseUrl(Constants.BASE_API_URL) .profile(DirectionsCriteria.PROFILE_DRIVING) .user(DirectionsCriteria.PROFILE_DEFAULT_USER) .geometries(DirectionsCriteria.GEOMETRY_POLYLINE6); } /** * Returns the builder which created this instance of {@link MapboxDirections} and allows for * modification and building a new directions request with new information. * * @return {@link MapboxDirections.Builder} with the same variables set as this directions object * @since 3.0.0 */ public abstract Builder toBuilder(); /** * This builder is used to create a new request to the Mapbox Directions API. At a bare minimum, * your request must include an access token, an origin, and a destination. All other fields can * be left alone inorder to use the default behaviour of the API. *

* By default, the directions profile is set to driving (without traffic) but can be changed to * reflect your users use-case. *

* Note to contributors: All optional booleans in this builder use the object {@code Boolean} * rather than the primitive to allow for unset (null) values. *

* * @since 1.0.0 */ @AutoValue.Builder public abstract static class Builder { // TODO: change List to a custom model or to a Pair private List> bearings = new ArrayList<>(); private List coordinates = new ArrayList<>(); private List annotations = new ArrayList<>(); private List radiuses = new ArrayList<>(); private Point destination; private Point origin; private List approaches = new ArrayList<>(); private List waypointIndices = new ArrayList<>(); private List waypointNames = new ArrayList<>(); private List waypointTargets = new ArrayList<>(); /** * The username for the account that the directions engine runs on. In most cases, this should * always remain the default value of {@link DirectionsCriteria#PROFILE_DEFAULT_USER}. * * @param user a non-null string which will replace the default user used in the directions * request * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder user(@NonNull String user); /** * This selects which mode of transportation the user will be using while navigating from the * origin to the final destination. The options include driving, driving considering traffic, * walking, and cycling. Using each of these profiles will result in different routing biases. * * @param profile required to be one of the String values found in the {@link ProfileCriteria} * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder profile(@NonNull @ProfileCriteria String profile); /** * This sets the starting point on the map where the route will begin. It is one of the * required parameters which must be set for a successful directions response. * * @param origin a GeoJson {@link Point} object representing the starting location for the route * @return this builder for chaining options together * @since 1.0.0 */ public Builder origin(@NonNull Point origin) { this.origin = origin; return this; } /** * This sets the ending point on the map where the route will end. It is one of the required * parameters which must be set for a successful directions response. * * @param destination a GeoJson {@link Point} object representing the starting location for the * route * @return this builder for chaining options together * @since 1.0.0 */ public Builder destination(@NonNull Point destination) { this.destination = destination; return this; } /** * This can be used to set up to 23 additional in-between points which will act as pit-stops * along the users route. Note that if you are using the * {@link DirectionsCriteria#PROFILE_DRIVING_TRAFFIC} that the max number of waypoints allowed * in the request is currently limited to 1. * * @param waypoint a {@link Point} which represents the pit-stop or waypoint where you'd like * one of the {@link RouteLeg} to navigate the user to * @return this builder for chaining options together * @since 3.0.0 */ public Builder addWaypoint(@NonNull Point waypoint) { coordinates.add(waypoint); return this; } /** * This can be used to set up to 23 additional in-between points which will act as pit-stops * along the users route. Note that if you are using the * {@link DirectionsCriteria#PROFILE_DRIVING_TRAFFIC} that the max number of waypoints allowed * in the request is currently limited to 1. * * @param waypoints a list which represents the pit-stops or waypoints where * you'd like one of the {@link RouteLeg} to navigate the user to * @return this builder for chaining options together */ public Builder waypoints(@NonNull List waypoints) { coordinates = waypoints; return this; } /** * Optionally set whether to try to return alternative routes. An alternative is classified as a * route that is significantly different then the fastest route, but also still reasonably fast. * Not in all circumstances such a route exists. At the moment at most one alternative can be * returned. * * @param alternatives true if you'd like to receive an alternative route, otherwise false or * null to use the APIs default value * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder alternatives(@Nullable Boolean alternatives); /** * alter the default geometry being returned for the directions route. A null value will reset * this field to the APIs default value vs this SDKs default value of * {@link DirectionsCriteria#GEOMETRY_POLYLINE6}. *

* Note that while the API supports GeoJson as an option for geometry, this SDK intentionally * removes this as an option since an encoded string for the geometry significantly reduces * bandwidth on mobile devices and speeds up response time. *

* * @param geometries null if you'd like the default geometry, else one of the options found in * {@link GeometriesCriteria}. * @return this builder for chaining options together * @since 2.0.0 */ public abstract Builder geometries(@GeometriesCriteria String geometries); /** * Type of returned overview geometry. Can be {@link DirectionsCriteria#OVERVIEW_FULL} (the most * detailed geometry available), {@link DirectionsCriteria#OVERVIEW_SIMPLIFIED} (a simplified * version of the full geometry), or {@link DirectionsCriteria#OVERVIEW_FALSE} (no overview * geometry). The default is simplified. Passing in null will use the APIs default setting for * the overview field. * * @param overview null or one of the options found in * {@link OverviewCriteria} * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder overview(@Nullable @OverviewCriteria String overview); /** * Setting this will determine whether to return steps and turn-by-turn instructions. Can be * set to either true or false to enable or disable respectively. null can also optionally be * passed in to set the default behavior to match what the API does by default. * * @param steps true if you'd like step information * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder steps(@Nullable Boolean steps); /** * Sets allowed direction of travel when departing intermediate waypoints. If true the route * will continue in the same direction of travel. If false the route may continue in the * opposite direction of travel. API defaults to true for * {@link DirectionsCriteria#PROFILE_DRIVING} and false for * {@link DirectionsCriteria#PROFILE_WALKING} and {@link DirectionsCriteria#PROFILE_CYCLING}. * * @param continueStraight boolean true if you want to always continue straight, else false. * Null can also be passed in here to use the APIs default option * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder continueStraight(@Nullable Boolean continueStraight); /** * Set the instruction language for the directions request, the default is english. Only a * select number of languages are currently supported, reference the table provided in the see * link below. * * @param language a Locale value representing the language you'd like the instructions to be * written in when returned * @return this builder for chaining options together * @see Supported * Languages * @since 2.2.0 */ public Builder language(@Nullable Locale language) { if (language != null) { language(language.getLanguage()); } return this; } abstract Builder language(@Nullable String language); /** * Optionally, set this to true if you want to enable instructions while exiting roundabouts * and rotaries. * * @param roundaboutExits true if you'd like extra roundabout instructions * @return this builder for chaining options together * @since 3.0.0 */ public abstract Builder roundaboutExits(@Nullable Boolean roundaboutExits); /** * Whether or not to return additional metadata along the route. Possible values are: * {@link DirectionsCriteria#ANNOTATION_DISTANCE}, * {@link DirectionsCriteria#ANNOTATION_DURATION} and * {@link DirectionsCriteria#ANNOTATION_CONGESTION}. Several annotation can be used by * separating them with {@code ,}. * * @param annotations string referencing one of the annotation direction criteria's. The strings * restricted to one or multiple values inside the {@link AnnotationCriteria} * or null which will result in no annotations being used * @return this builder for chaining options together * @see RouteLeg object * documentation * @since 2.1.0 * @deprecated use {@link #annotations(List)} */ @Deprecated public Builder annotations(@AnnotationCriteria @NonNull String... annotations) { return annotations(Arrays.asList(annotations)); } /** * Whether or not to return additional metadata along the route. Possible values are: * {@link DirectionsCriteria#ANNOTATION_DISTANCE}, * {@link DirectionsCriteria#ANNOTATION_DURATION} and * {@link DirectionsCriteria#ANNOTATION_CONGESTION} * * @param annotations a list of annotations * @return this builder for chaining options together */ public Builder annotations(@NonNull List annotations) { this.annotations = annotations; return this; } /** * Whether or not to return additional metadata along the route. Possible values are: * {@link DirectionsCriteria#ANNOTATION_DISTANCE}, * {@link DirectionsCriteria#ANNOTATION_DURATION} and * {@link DirectionsCriteria#ANNOTATION_CONGESTION} * * @param annotation string referencing one of the annotation direction criteria's. * @return this builder for chaining options together * @see RouteLeg object * documentation * @since 2.1.0 */ public Builder addAnnotation(@AnnotationCriteria @NonNull String annotation) { this.annotations.add(annotation); return this; } abstract Builder annotation(@Nullable String annotation); /** * Optionally, Use to filter the road segment the waypoint will be placed on by direction and * dictates the angle of approach. This option should always be used in conjunction with the * {@link #radiuses} parameter. *

* The parameter takes two values per waypoint: the first is an angle clockwise from true north * between 0 and 360. The second is the range of degrees the angle can deviate by. We recommend * a value of 45 degrees or 90 degrees for the range, as bearing measurements tend to be * inaccurate. This is useful for making sure we reroute vehicles on new routes that continue * traveling in their current direction. A request that does this would provide bearing and * radius values for the first waypoint and leave the remaining values empty. If provided, the * list of bearings must be the same length as the list of waypoints, but you can skip a * coordinate and show its position by passing in null value for both the angle and tolerance * values. *

* Each bearing value gets associated with the same order which coordinates are arranged in this * builder. For example, the first bearing added in this builder will be associated with the * origin {@code Point}, the nth bearing being associated with the nth waypoint added (if added) * and the last bearing being added will be associated with the destination. *

* * @param angle double value used for setting the corresponding coordinate's angle of travel * when determining the route * @param tolerance the deviation the bearing angle can vary while determining the route, * recommended to be either 45 or 90 degree tolerance * @return this builder for chaining options together * @since 2.0.0 */ public Builder addBearing(@Nullable @FloatRange(from = 0, to = 360) Double angle, @Nullable @FloatRange(from = 0, to = 360) Double tolerance) { bearings.add(Arrays.asList(angle, tolerance)); return this; } /** * Optionally, Use to filter the road segment the waypoint will be placed on by direction and * dictates the angle of approach. This option should always be used in conjunction with the * {@link #radiuses} parameter. * * @param bearings a list of list of doubles. Every list has two values: * the first is an angle clockwise from true north between 0 and 360. The * second is the range of degrees the angle can deviate by. We recommend * a value of 45 degrees or 90 degrees for the range, as bearing measurements * tend to be inaccurate. * @return this builder for chaining options together */ public Builder bearings(@NonNull List> bearings) { this.bearings = bearings; return this; } abstract Builder bearing(@Nullable String bearings); /** * Optionally, set the maximum distance in meters that each coordinate is allowed to move when * snapped to a nearby road segment. There must be as many radiuses as there are coordinates in * the request. Values can be any number greater than 0 or they can be unlimited simply by * passing {@link Double#POSITIVE_INFINITY}. *

* If no routable road is found within the radius, a {@code NoSegment} error is returned. *

* * @param radiuses double array containing the radiuses defined in unit meters. * @return this builder for chaining options together * @since 1.0.0 * @deprecated use {@link #radiuses(List)} */ @Deprecated public Builder radiuses(@NonNull @FloatRange(from = 0) Double... radiuses) { return radiuses(Arrays.asList(radiuses)); } /** * Optionally, set the maximum distance in meters that each coordinate is allowed to move when * snapped to a nearby road segment. There must be as many radiuses as there are coordinates in * the request. Values can be any number greater than 0 or they can be unlimited simply by * passing {@link Double#POSITIVE_INFINITY}. *

* If no routable road is found within the radius, a {@code NoSegment} error is returned. *

* * @param radiuses a list with radiuses defined in unit meters. * @return this builder for chaining options together */ public Builder radiuses(@NonNull List radiuses) { this.radiuses = radiuses; return this; } /** * Optionally, set the maximum distance in meters that each coordinate is allowed to move when * snapped to a nearby road segment. There must be as many radiuses as there are coordinates in * the request. Values can be any number greater than 0 or they can be unlimited simply by * passing {@link Double#POSITIVE_INFINITY}. *

* If no routable road is found within the radius, a {@code NoSegment} error is returned. *

* * @param radius double param defined in unit meters. * @return this builder for chaining options together * @since 1.0.0 */ public Builder addRadius(@NonNull @FloatRange(from = 0) Double radius) { this.radiuses.add(radius); return this; } abstract Builder radius(@Nullable String radiuses); /** * Exclude certain road types from routing. Valid values depend on the profile in use. The * default is to not exclude anything from the profile selected. * * @param exclude one of the constants defined in {@link ExcludeCriteria} * @return this builder for chaining options together * @since 3.0.0 */ public abstract Builder exclude(@ExcludeCriteria String exclude); /** * Request voice instructions objects to be returned in your response. This offers instructions * specific for navigation and provides well spoken text instructions along with the distance * from the maneuver the instructions should be said. *

* It's important to note that the {@link #steps(Boolean)} should be true or else these results * wont be returned. *

* * @param voiceInstructions true if you'd like voice instruction objects be attached to your * response * @return this builder for chaining options together * @since 3.0.0 */ public abstract Builder voiceInstructions(@Nullable Boolean voiceInstructions); /** * Request banner instructions object to be returned in your response. This is useful * specifically for navigation and provides an abundance of information one might want to * display to their user inside an Android view for example. * * @param bannerInstructions true if you'd like the receive banner objects within your response * object * @return this builder for chaining options together * @since 3.0.0 */ public abstract Builder bannerInstructions(@Nullable Boolean bannerInstructions); /** * Specify what unit you'd like voice and banner instructions to use. * * @param voiceUnits either Imperial (default) or Metric * @return this builder for chaining options together * @since 3.0.0 */ public abstract Builder voiceUnits(@Nullable @VoiceUnitCriteria String voiceUnits); /** * Base package name or other simple string identifier. Used inside the calls user agent header. * * @param clientAppName base package name or other simple string identifier * @return this builder for chaining options together * @since 1.0.0 */ public abstract Builder clientAppName(@NonNull String clientAppName); /** * Required to call when this is being built. If no access token provided, * {@link ServicesException} will be thrown. * * @param accessToken Mapbox access token, You must have a Mapbox account inorder to use * the Optimization API * @return this builder for chaining options together * @since 2.1.0 */ public abstract Builder accessToken(@NonNull String accessToken); /** * Optionally change the APIs base URL to something other then the default Mapbox one. * * @param baseUrl base url used as end point * @return this builder for chaining options together * @since 2.1.0 */ public abstract Builder baseUrl(String baseUrl); /** * Adds an optional interceptor to set in the OkHttp client. * * @param interceptor to set for OkHttp * @return this builder for chaining options together */ public abstract Builder interceptor(Interceptor interceptor); /** * Adds an optional network interceptor to set in the OkHttp client. * * @param interceptor to set for OkHttp * @return this builder for chaining options together */ public abstract Builder networkInterceptor(Interceptor interceptor); /** * Adds an optional event listener to set in the OkHttp client. * * @param eventListener to set for OkHttp * @return this builder for chaining options together */ public abstract Builder eventListener(EventListener eventListener); abstract Builder coordinates(@NonNull List coordinates); /** * Indicates from which side of the road to approach a waypoint. * Accepts unrestricted (default), curb or null. * If set to unrestricted , the route can approach waypoints * from either side of the road. If set to curb , the route will be returned * so that on arrival, the waypoint will be found on the side that corresponds with the * driving_side of the region in which the returned route is located. * If provided, the list of approaches must be the same length as the list of waypoints. * * @param approaches null if you'd like the default approaches, * else one of the options found in * {@link com.mapbox.api.directions.v5.DirectionsCriteria.ApproachesCriteria}. * @return this builder for chaining options together * @since 3.2.0 * @deprecated use {@link #approaches(List)} */ @Deprecated public Builder addApproaches(@NonNull String... approaches) { return approaches(Arrays.asList(approaches)); } /** * Indicates from which side of the road to approach a waypoint. * Accepts unrestricted (default), curb or null. * If set to unrestricted , the route can approach waypoints * from either side of the road. If set to curb , the route will be returned * so that on arrival, the waypoint will be found on the side that corresponds with the * driving_side of the region in which the returned route is located. * If provided, the list of approaches must be the same length as the list of waypoints. * * @param approaches empty if you'd like the default approaches, * else one of the options found in * {@link com.mapbox.api.directions.v5.DirectionsCriteria.ApproachesCriteria}. * @return this builder for chaining options together */ public Builder approaches(@NonNull List approaches) { this.approaches = approaches; return this; } abstract Builder approaches(@Nullable String approaches); /** * Indicates from which side of the road to approach a waypoint. * Accepts unrestricted (default), curb or null. * If set to unrestricted , the route can approach waypoints * from either side of the road. If set to curb , the route will be returned * so that on arrival, the waypoint will be found on the side that corresponds with the * driving_side of the region in which the returned route is located. * If provided, the list of approaches must be the same length as the list of waypoints. * * @param approach null if you'd like the default approaches, else one of the options found in * {@link com.mapbox.api.directions.v5.DirectionsCriteria.ApproachesCriteria}. * @return this builder for chaining options together * @since 3.2.0 */ public Builder addApproach(@Nullable String approach) { this.approaches.add(approach); return this; } /** * Optionally, set which input coordinates should be treated as waypoints / separate legs. * Note: coordinate indices not added here act as silent waypoints *

* Most useful in combination with steps=true and requests based on traces * with high sample rates. Can be an index corresponding to any of the input coordinates, * but must contain the first ( 0 ) and last coordinates' indices. * {@link #steps()} *

* * @param waypointIndices integer array of coordinate indices to be used as waypoints * @return this builder for chaining options together * @since 4.4.0 * @deprecated use {@link #waypointIndices(List)} */ @Deprecated public Builder addWaypointIndices(@NonNull @IntRange(from = 0) Integer... waypointIndices) { return waypointIndices(Arrays.asList(waypointIndices)); } /** * Optionally, set which input coordinates should be treated as waypoints / separate legs. * Note: coordinate indices not added here act as silent waypoints *

* Most useful in combination with steps=true and requests based on traces * with high sample rates. Can be an index corresponding to any of the input coordinates, * but must contain the first ( 0 ) and last coordinates' indices. * {@link #steps()} *

* * @param waypointIndices a list of coordinate indices to be used as waypoints * @return this builder for chaining options together */ public Builder waypointIndices(@NonNull List waypointIndices) { this.waypointIndices = waypointIndices; return this; } abstract Builder waypointIndices(@Nullable String waypointIndices); /** * Optionally, set which input coordinates should be treated as waypoints / separate legs. * Note: coordinate indices not added here act as silent waypoints *

* Most useful in combination with steps=true and requests based on traces * with high sample rates. Can be an index corresponding to any of the input coordinates, * but must contain the first ( 0 ) and last coordinates' indices. * {@link #steps()} *

* * @param waypointIndex integer index to be used as waypoint * @return this builder for chaining options together * @since 4.4.0 */ public Builder addWaypointIndex(@NonNull @IntRange(from = 0) Integer waypointIndex) { this.waypointIndices.add(waypointIndex); return this; } /** * Custom names for waypoints used for the arrival instruction. * Values can be any string and total number of all characters cannot exceed 500. * If provided, the list of waypointNames must be the same length as the list of * coordinates, but you can skip a coordinate and show its position with the null value. * * @param waypointNames Custom names for waypoints used for the arrival instruction. * @return this builder for chaining options together * @since 3.3.0 * @deprecated use {@link #waypointNames(List)} */ @Deprecated public Builder addWaypointNames(@NonNull String... waypointNames) { return waypointNames(Arrays.asList(waypointNames)); } /** * Custom names for waypoints used for the arrival instruction. * Values can be any string and total number of all characters cannot exceed 500. * If provided, the list of waypointNames must be the same length as the list of * coordinates, but you can skip a coordinate and show its position with the null value. * * @param waypointNames a list of custom names for waypoints used for the arrival instruction. * @return this builder for chaining options together */ public Builder waypointNames(@NonNull List waypointNames) { this.waypointNames = waypointNames; return this; } abstract Builder waypointNames(@Nullable String waypointNames); /** * Custom names for waypoints used for the arrival instruction. * Values can be any string and total number of all characters cannot exceed 500. * If provided, the list of waypointNames must be the same length as the list of * coordinates, but you can skip a coordinate and show its position with the null value. * * @param waypointName Custom name for waypoint used for the arrival instruction. * @return this builder for chaining options together * @since 3.3.0 */ public Builder addWaypointName(@Nullable String waypointName) { this.waypointNames.add(waypointName); return this; } /** * Points to specify drop-off locations that are distinct from the locations specified in * coordinates. * The number of waypoint targets must be the same as the number of coordinates, * but you can skip a coordinate with a null value. * Must be used with steps=true. * * @param waypointTargets list of coordinate points for drop-off locations * @return this builder for chaining options together * @since 4.3.0 * @deprecated use {@link #waypointTargets(List)} */ @Deprecated public Builder addWaypointTargets(@NonNull Point... waypointTargets) { return waypointTargets(Arrays.asList(waypointTargets)); } /** * A list of points used to specify drop-off locations that are distinct from the locations * specified in coordinates. * The number of waypoint targets must be the same as the number of coordinates, * but you can skip a coordinate with a null value. * Must be used with steps=true. * * @param waypointTargets list of coordinate points for drop-off locations * @return this builder for chaining options together */ public Builder waypointTargets(@NonNull List waypointTargets) { this.waypointTargets = waypointTargets; return this; } abstract Builder waypointTargets(@Nullable String waypointTargets); /** * A point to specify drop-off locations that are distinct from the locations specified in * coordinates. * The number of waypoint targets must be the same as the number of coordinates, * but you can skip a coordinate with a null value. * Must be used with steps=true. * * @param waypointTarget a point for drop-off locations * @return this builder for chaining options together * @since 4.3.0 */ public Builder addWaypointTarget(@Nullable Point waypointTarget) { this.waypointTargets.add(waypointTarget); return this; } /** * Whether the routes should be refreshable via the directions refresh API. * * @param enableRefresh whether the routes should be refreshable * @return this builder * @since 4.4.0 */ public abstract Builder enableRefresh(Boolean enableRefresh); /** * Use POST method to request data. * The default is to use GET. * @return this builder for chaining options together * @since 4.6.0 */ public Builder post() { usePostMethod(true); return this; } /** * Use GET method to request data. * @return this builder for chaining options together * @since 4.6.0 */ public Builder get() { usePostMethod(false); return this; } /** * To be used to specify settings for use with the walking profile. * * @param walkingOptions options to use for walking profile * @return this builder for chaining options together * @since 4.8.0 */ public abstract Builder walkingOptions(@NonNull WalkingOptions walkingOptions); abstract WalkingOptions walkingOptions(); abstract Builder usePostMethod(@NonNull Boolean usePost); abstract Boolean usePostMethod(); abstract MapboxDirections autoBuild(); /** * This uses the provided parameters set using the {@link Builder} and first checks that all * values are valid, formats the values as strings for easier consumption by the API, and lastly * creates a new {@link MapboxDirections} object with the values provided. * * @return a new instance of Mapbox Directions * @since 2.1.0 */ public MapboxDirections build() { if (origin != null) { coordinates.add(0, origin); } if (destination != null) { coordinates.add(destination); } if (coordinates.size() < 2) { throw new ServicesException("An origin and destination are required before making the" + " directions API request."); } if (!waypointIndices.isEmpty()) { if (waypointIndices.size() < 2) { throw new ServicesException( "Waypoints must be a list of at least two indexes separated by ';'"); } if (waypointIndices.get(0) != 0 || waypointIndices.get(waypointIndices.size() - 1) != coordinates.size() - 1) { throw new ServicesException( "Waypoints must contain indices of the first and last coordinates" ); } for (int i = 1; i < waypointIndices.size() - 1; i++) { if (waypointIndices.get(i) < 0 || waypointIndices.get(i) >= coordinates.size()) { throw new ServicesException( "Waypoints index too large (no corresponding coordinate)"); } } } if (!waypointNames.isEmpty()) { final String waypointNamesStr = FormatUtils.formatWaypointNames(waypointNames); waypointNames(waypointNamesStr); } if (!waypointTargets.isEmpty()) { if (waypointTargets.size() != coordinates.size()) { throw new ServicesException("Number of waypoint targets must match " + " the number of waypoints provided."); } waypointTargets(FormatUtils.formatPointsList(waypointTargets)); } if (!approaches.isEmpty()) { if (approaches.size() != coordinates.size()) { throw new ServicesException("Number of approach elements must match " + "number of coordinates provided."); } String formattedApproaches = FormatUtils.formatApproaches(approaches); if (formattedApproaches == null) { throw new ServicesException("All approaches values must be one of curb, unrestricted"); } approaches(formattedApproaches); } coordinates(coordinates); bearing(FormatUtils.formatBearings(bearings)); annotation(FormatUtils.join(",", annotations)); radius(FormatUtils.formatRadiuses(radiuses)); waypointIndices(FormatUtils.join(";", waypointIndices, true)); MapboxDirections directions = autoBuild(); if (!MapboxUtils.isAccessTokenValid(directions.accessToken())) { throw new ServicesException("Using Mapbox Services requires setting a valid access" + " token."); } return directions; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy