# Draw Route line with alternative routes on map

This example shows:

-   How to fetch a route with an alternative route using RouteRequestParams

    -   .origin(origin)
    -   .destination(destination)
    -   .alternatives(true)
    -   .altCount(2)
-   How to draw a route with alternative routes `navMap.drawRoutes(directionsRoutes);`

-   How to show or hide the route duration symbol next to every single route line `navMap.showRouteDurationSymbol(boolean);`


![documentation image](<https://static.nextbillion.io/docs-next/docs/navigation/android/draw-route-line-with-alternative routes.jpg>)

For all code examples, refer to [Navigation Code Examples](https://github.com/nextbillion-ai/nb-navigation-android-demo)

**activity_draw_route_line_with_alt.xml [view source](https://github.com/nextbillion-ai/nb-navigation-android-demo/blob/main/app/src/main/res/layout/activity_draw_route_line_with_alt.xml)**

```xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ai.nextbillion.maps.core.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:nbmap_uiAttribution="false">
    </ai.nextbillion.maps.core.MapView>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:orientation="vertical"
        android:layout_gravity="bottom">
        <Button
            android:id="@+id/fetchRoute"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:text="@string/draw_route"/>

        <Button
            android:id="@+id/hideRouteDuration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:text="@string/draw_route_without"/>

        <Button
            android:id="@+id/startNav"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="12sp"
            android:text="@string/start_navigation"/>

    </LinearLayout>

    <ProgressBar
        android:id="@+id/progress"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>
</FrameLayout>
```

**DrawRouteLineWithAltActivity [view source](https://github.com/nextbillion-ai/nb-navigation-android-demo/blob/main/app/src/main/java/ai/nextbillion/navigation/demo/activity/DrawRouteLineWithAltActivity.java)**

```java
package ai.nextbillion.navigation.demo.activity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;

import java.util.List;

import ai.nextbillion.kits.directions.models.DirectionsResponse;
import ai.nextbillion.kits.directions.models.DirectionsRoute;
import ai.nextbillion.kits.directions.models.RouteRequestParams;
import ai.nextbillion.kits.geojson.Point;
import ai.nextbillion.maps.camera.CameraUpdate;
import ai.nextbillion.maps.camera.CameraUpdateFactory;
import ai.nextbillion.maps.core.MapView;
import ai.nextbillion.maps.core.NextbillionMap;
import ai.nextbillion.maps.core.OnMapReadyCallback;
import ai.nextbillion.maps.geometry.LatLng;
import ai.nextbillion.maps.location.modes.RenderMode;
import ai.nextbillion.navigation.core.routefetcher.RouteFetcher;
import ai.nextbillion.navigation.demo.R;
import ai.nextbillion.navigation.demo.utils.CameraAnimateUtils;
import ai.nextbillion.navigation.ui.NavLauncherConfig;
import ai.nextbillion.navigation.ui.NavigationLauncher;
import ai.nextbillion.navigation.ui.camera.CameraUpdateMode;
import ai.nextbillion.navigation.ui.camera.NavigationCameraUpdate;
import ai.nextbillion.navigation.ui.map.NavNextbillionMap;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class DrawRouteLineWithAltActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener {

    private static final double DEFAULT_CAMERA_ZOOM = 14;

    private Point origin = Point.fromLngLat(78.37463792413473, 17.457302037173775);
    private Point destination = Point.fromLngLat(78.3726774987914, 17.466320809357967);

    private MapView mapView;
    private NavNextbillionMap navMap;

    private Button fetchRoute;
    private Button fetchRouteWithoutDuration;
    private Button startNav;
    private DirectionsRoute directionsRoute;
    private List<DirectionsRoute> directionsRoutes;
    private ProgressBar progress;
    boolean showRouteDurationSymbol = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_draw_route_line_with_alt);
        mapView = findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(this);
        fetchRoute = findViewById(R.id.fetchRoute);
        fetchRouteWithoutDuration = findViewById(R.id.hideRouteDuration);
        startNav = findViewById(R.id.startNav);
        progress = findViewById(R.id.progress);
        fetchRoute.setOnClickListener(this);
        startNav.setOnClickListener(this);
        fetchRouteWithoutDuration.setOnClickListener(this);
        fetchRouteWithoutDuration.setEnabled(false);
        startNav.setEnabled(false);
        fetchRoute.setEnabled(false);
    }

    @Override
    public void onMapReady(@NonNull NextbillionMap nextbillionMap) {
        nextbillionMap.getStyle(style -> {
            navMap = new NavNextbillionMap(mapView, nextbillionMap);
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(origin.latitude(),origin.longitude()), DEFAULT_CAMERA_ZOOM);
            NavigationCameraUpdate navigationCameraUpdate = new NavigationCameraUpdate(cameraUpdate);
            navigationCameraUpdate.setMode(CameraUpdateMode.OVERRIDE);
            navMap.retrieveCamera().update(navigationCameraUpdate, 1000);
            fetchRoute.setEnabled(true);
            fetchRouteWithoutDuration.setEnabled(true);
        });
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.fetchRoute) {
            showRouteDurationSymbol = true;
            fetchRoute();
        } else if (view.getId() == R.id.hideRouteDuration) {
            showRouteDurationSymbol = false;
            fetchRoute();
        } else if (view.getId() == R.id.startNav) {
            NavLauncherConfig.Builder configBuilder = NavLauncherConfig.builder(directionsRoute);
            configBuilder.routes(directionsRoutes);
            configBuilder.locationLayerRenderMode(RenderMode.GPS);
            configBuilder.shouldSimulateRoute(true);
            NavigationLauncher.startNavigation(DrawRouteLineWithAltActivity.this, configBuilder.build());
        }
    }

    private void fetchRoute() {
        progress.setVisibility(View.VISIBLE);

        RouteRequestParams.Builder builder = RouteRequestParams.builder()
                .origin(origin)
                .destination(destination)
                .alternatives(true)
                .altCount(2)
                .language("en")
                .departureTime((int) (System.currentTimeMillis()/1000));

        RouteFetcher.getRoute(builder.build(), new Callback<DirectionsResponse>() {
            @Override
            public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                progress.setVisibility(View.GONE);
                //start navigation with the route we just fetched.
                if (response.body() != null && !response.body().routes().isEmpty()) {
                    directionsRoute = response.body().routes().get(0);
                    directionsRoutes = response.body().routes();
                    drawRouteLine();
                    startNav.setEnabled(true);
                }
            }

            @Override
            public void onFailure(Call<DirectionsResponse> call, Throwable t) {
                progress.setVisibility(View.GONE);
            }
        });
    }

    private void drawRouteLine() {
        navMap.removeRoute();
        navMap.clearMarkers();
        navMap.showRouteDurationSymbol(showRouteDurationSymbol);
        navMap.drawRoutes(directionsRoutes);
        frameCameraToRoute();
    }

    private void frameCameraToRoute() {
        int[] padding = CameraAnimateUtils.createPadding(this);
        CameraAnimateUtils.frameCameraToBounds(navMap, directionsRoutes, padding);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mapView.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mapView.onStop();
    }

    @Override
    protected void onDestroy() {
        mapView.onDestroy();
        super.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

}
```

### Code Highlights

This Code example includes How to display a MapView and draw route lines with alternative routes on the map using `NavNextbillionMap` and start navigation with drawn routes using _NavigationLauncher_

In particular, this example shows we can display or hide the route duration symbol via function `navMap.showRouteDurationSymbol()`, and we can also let navigation API return more than 1 route result if available, by setting `RouteRequestParams.alternatives` as true, and `RouteRequestParams.altCount` as the desired route count you wish to have.

### Code summary

Map Initialization:

-   The `onMapReady()` method is called when the map is ready to be used.

-   The `NavNextbillionMap` class is used to create a navigation-enabled map by passing the _MapView_ and _NextbillionMap_ instances.

-   The camera position is set to the origin point with a default zoom level using `CameraUpdateFactory.newLatLngZoom()` and `NavigationCameraUpdate`.


Fetch route with _RouteFetcher_

-   Constructs a _RouteRequestParams_ object with the

    -   origin

    -   destination

    -   language

    -   alternatives

    -   altCount

    -   departure time

-   The `RouteFetcher.getRoute()` method is used to fetch the route using the `RouteRequestParams`.


Draw route with/without duration symbol

-   The route is drawn on the map using `navMap.drawRoutes()`

-   The camera is framed to fit the route using frameCameraToRoute()

-   To show or hide the duration symbol using `navMap.showRouteDurationSymbol(true/false)`

-   To clear the drawn route and markers using `navMap.removeRoute()` `navMap.clearMarkers()`


### Start Navigation

-   Creates a `NavLauncherConfig.Builder` and configures the navigation settings, including the _location_ _layer_ _render_ _mode_ and whether to _simulate_ the route.

-   The `NavigationLauncher.startNavigation()` method is called to start the navigation activity with the configured NavLauncherConfig.
