> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/java/llms.txt)

# Straight line distance

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/android/android/assets/medias/example-straight-line-distance-map-movement-activity-40a3a3a1cd04bfe47b7d3396e61bed33.mp4).

> **Note**
> 
> This example is a part of the [Mapbox Android Demo app](https://github.com/mapbox/mapbox-android-demo). You can find the values for all referenced resources in the [`res`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res) directory. For example, see [`res/values/activity_strings.xml`](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res/values/activity_strings.xml) for `R.string.*` references used in this example. The dependencies can be found [here.](https://github.com/mapbox/mapbox-navigation-android-examples/blob/main/app/build.gradle) The examples use View binding. [See setup documention if necessary.](https://developer.android.com/topic/libraries/view-binding)

Title: `activity_javaservices_straight_line_distance`

[View on GitHub](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/res/layout/activity_javaservices_straight_line_distance.xml)

```xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/constraint_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".examples.javaservices.TurfLineDistanceActivity">

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        mapbox:layout_constraintBottom_toBottomOf="parent"
        mapbox:layout_constraintEnd_toEndOf="parent"
        mapbox:layout_constraintStart_toStartOf="parent"
        mapbox:layout_constraintTop_toTopOf="parent"
        mapbox:mapbox_cameraTargetLat="21.3011229"
        mapbox:mapbox_cameraTargetLng="-157.851376"
        mapbox:mapbox_cameraZoom="12" />

    <TextView
        android:id="@+id/straight_line_distance_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        mapbox:layout_constraintBottom_toBottomOf="parent"
        mapbox:layout_constraintEnd_toEndOf="parent"
        mapbox:layout_constraintStart_toStartOf="@+id/mapView"
        mapbox:layout_constraintTop_toTopOf="@+id/mapView" />

</androidx.constraintlayout.widget.ConstraintLayout>
```

**Java**

Title: `StraightLineDistanceMapMovementActivity.java`

[View on GitHub](https://github.com/mapbox/mapbox-android-demo/tree/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/javaservices/StraightLineDistanceMapMovementActivity.java)

```java
package com.mapbox.mapboxandroiddemo.examples.javaservices;

import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.geojson.LineString;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Style;
import com.mapbox.mapboxsdk.style.layers.LineLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import com.mapbox.turf.TurfMeasurement;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import static com.mapbox.mapboxsdk.style.layers.Property.LINE_JOIN_ROUND;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth;
import static com.mapbox.turf.TurfConstants.UNIT_METERS;

/**
 * Use {@link com.mapbox.turf.TurfMeasurement#distance(Point, Point)} to calculate a straight line distance
 * ("as the crow flies") between the device location and the map camera's target.
 */
public class StraightLineDistanceMapMovementActivity extends AppCompatActivity implements
  PermissionsListener, MapboxMap.OnCameraMoveListener {

  private static final String DISTANCE_SOURCE_ID = "DISTANCE_SOURCE_ID";
  private static final String DISTANCE_LINE_LAYER_ID = "DISTANCE_LINE_LAYER_ID";

  // Adjust private static final variables below to change the example's UI
  private static final int LINE_COLOR = Color.RED;
  private static final float LINE_WIDTH = 2f;

  private PermissionsManager permissionsManager;
  private List<Point> pointList;
  private MapView mapView;
  private MapboxMap mapboxMap;
  private TextView distanceTextView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Mapbox access token is configured here. This needs to be called either in your application
    // object or in the same activity which contains the mapview.
    Mapbox.getInstance(this, getString(R.string.access_token));

    // This contains the MapView in XML and needs to be called after the access token is configured.
    setContentView(R.layout.activity_javaservices_straight_line_distance);

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);

    mapView.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(@NonNull MapboxMap mapboxMap) {

        StraightLineDistanceMapMovementActivity.this.mapboxMap = mapboxMap;

        mapboxMap.setStyle(new Style.Builder()
            .fromUri(Style.DARK)

            // Add the source to the map
            .withSource(new GeoJsonSource(DISTANCE_SOURCE_ID))

            // Style and add the LineLayer to the map.
            .withLayer(new LineLayer(DISTANCE_LINE_LAYER_ID, DISTANCE_SOURCE_ID).withProperties(
              lineColor(LINE_COLOR),
              lineWidth(LINE_WIDTH),
              lineJoin(LINE_JOIN_ROUND))), new Style.OnStyleLoaded() {
                @Override
                  public void onStyleLoaded(@NonNull Style style) {
                    enableLocationComponent(style);

                    StraightLineDistanceMapMovementActivity.this.mapboxMap
                      .addOnCameraMoveListener(StraightLineDistanceMapMovementActivity.this);

                    distanceTextView = findViewById(R.id.straight_line_distance_textview);
                    distanceTextView.setTextColor(Color.RED);

                    Toast.makeText(StraightLineDistanceMapMovementActivity.this,
                      getString(R.string.move_map_around_instruction), Toast.LENGTH_SHORT).show();
                  }
                }
        );
      }
    });
  }

  @Override
  public void onCameraMove() {
    redrawLine(mapboxMap.getCameraPosition().target);
  }

  private void redrawLine(@NonNull LatLng targetLatLng) {
    mapboxMap.getStyle(new Style.OnStyleLoaded() {
      @Override
      public void onStyleLoaded(@NonNull Style style) {
        GeoJsonSource geoJsonSource = style.getSourceAs(DISTANCE_SOURCE_ID);
        if (geoJsonSource != null) {
          pointList = new ArrayList<>();
          Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();
          if (lastKnownLocation != null) {

            // Add the start and ending points to the straight line
            Point targetPoint = Point.fromLngLat(targetLatLng.getLongitude(), targetLatLng.getLatitude());
            Point deviceLocationPoint = Point.fromLngLat(lastKnownLocation.getLongitude(),
              lastKnownLocation.getLatitude());
            pointList.add(targetPoint);
            pointList.add(deviceLocationPoint);

            // Update the source with the new LineString line
            geoJsonSource.setGeoJson(LineString.fromLngLats(pointList));

            // Update the TextView with the new straight line distance
            double distanceBetweenDeviceAndTarget = TurfMeasurement.distance(deviceLocationPoint,
              targetPoint, UNIT_METERS);

            distanceTextView.setText(String.format("%s meters", String.valueOf(
              NumberFormat.getNumberInstance(Locale.US).format(distanceBetweenDeviceAndTarget))));
          }
        }
      }
    });
  }

  @SuppressWarnings( {"MissingPermission"})
  private void enableLocationComponent(@NonNull Style loadedMapStyle) {
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

      // Get an instance of the component
      LocationComponent locationComponent = mapboxMap.getLocationComponent();

      // Activate with options
      locationComponent.activateLocationComponent(
        LocationComponentActivationOptions.builder(this, loadedMapStyle).build());

      // Enable to make component visible
      locationComponent.setLocationComponentEnabled(true);

      // Set the component's camera mode
      locationComponent.setCameraMode(CameraMode.TRACKING);

      // Set the component's render mode
      locationComponent.setRenderMode(RenderMode.COMPASS);
    } else {
      permissionsManager = new PermissionsManager(this);
      permissionsManager.requestLocationPermissions(this);
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                         @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }

  @Override
  public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation,
      Toast.LENGTH_LONG).show();
  }

  @Override
  public void onPermissionResult(boolean granted) {
    if (granted) {
      mapboxMap.getStyle(new Style.OnStyleLoaded() {
        @Override
        public void onStyleLoaded(@NonNull Style style) {
          enableLocationComponent(style);
        }
      });
    } else {
      Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
      finish();
    }
  }

  // Add the mapView lifecycle to the activity's lifecycle methods
  @Override
  public void onResume() {
    super.onResume();
    mapView.onResume();
  }

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

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

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

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

  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (mapboxMap != null) {
      mapboxMap.removeOnCameraMoveListener(this);
    }
    mapView.onDestroy();
  }

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