Adjust light location and color
A newer version of the Maps SDK is available
This page uses v9.7.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.16.2, in the Maps SDK documentation.
Note
This example is a part of the Mapbox Android Demo app. You can find the values for all referenced resources in the res directory. For example, see res/values/activity_strings.xml for R.string.* references used in this example. The dependencies can be found here.The examples use View binding.See setup documention if necessary.
activity_extrusion_light
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:mapbox="http://schemas.android.com/apk/res-auto"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="vertical">
    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:mapbox_cameraTargetLat="40.7135"
        mapbox:mapbox_cameraTargetLng="-74.0066"
        mapbox:mapbox_cameraTilt="45"
        mapbox:mapbox_cameraZoom="16"
        />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabLightPosition"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_marginBottom="82dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:src="@drawable/ic_my_location"
        mapbox:backgroundTint="@color/mapboxPink"
        mapbox:layout_anchorGravity="top"/>
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabLightColor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/ic_paint"
        mapbox:backgroundTint="@color/mapboxBlue"/>
</FrameLayout>
AdjustExtrusionLightActivity.java
package com.mapbox.mapboxandroiddemo.examples.extrusions;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
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.FillExtrusionLayer;
import com.mapbox.mapboxsdk.style.layers.Property;
import com.mapbox.mapboxsdk.style.light.Light;
import com.mapbox.mapboxsdk.style.light.Position;
import com.mapbox.mapboxsdk.utils.ColorUtils;
import static com.mapbox.mapboxsdk.style.expressions.Expression.eq;
import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential;
import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate;
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
import static com.mapbox.mapboxsdk.style.expressions.Expression.stop;
import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity;
/**
 * Change the location and color of the light that's shined on extrusions
 */
public class AdjustExtrusionLightActivity extends AppCompatActivity {
  private MapView mapView;
  private Light light;
  private boolean isMapAnchorLight;
  private boolean isLowIntensityLight;
  private boolean isRedColor;
  private boolean isInitPosition;
  @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));
    setContentView(R.layout.activity_extrusion_light);
    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(new OnMapReadyCallback() {
      @Override
      public void onMapReady(@NonNull final MapboxMap map) {
        map.setStyle(Style.DARK, new Style.OnStyleLoaded() {
          @Override
          public void onStyleLoaded(@NonNull Style style) {
            setupBuildings(style);
            setupLight(style);
          }
        });
      }
    });
  }
  private void setupBuildings(@NonNull Style loadedMapStyle) {
    FillExtrusionLayer fillExtrusionLayer = new FillExtrusionLayer("3d-buildings", "composite");
    fillExtrusionLayer.setSourceLayer("building");
    fillExtrusionLayer.setFilter(eq(get("extrude"), "true"));
    fillExtrusionLayer.setMinZoom(15);
    fillExtrusionLayer.setProperties(
      fillExtrusionColor(Color.LTGRAY),
      fillExtrusionHeight(
        interpolate(
          exponential(1f),
          zoom(),
          stop(15, literal(0)),
          stop(16, get("height"))
        )
      ),
      fillExtrusionBase(get("min_height")),
      fillExtrusionOpacity(0.9f)
    );
    loadedMapStyle.addLayer(fillExtrusionLayer);
  }
  private void setupLight(@NonNull Style loadedMapStyle) {
    light = loadedMapStyle.getLight();
    findViewById(R.id.fabLightPosition).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        isInitPosition = !isInitPosition;
        if (isInitPosition) {
          light.setPosition(new Position(1.5f, 90, 80));
        } else {
          light.setPosition(new Position(1.15f, 210, 30));
        }
      }
    });
    findViewById(R.id.fabLightColor).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        isRedColor = !isRedColor;
        light.setColor(ColorUtils.colorToRgbaString(isRedColor ? Color.RED : Color.BLUE));
      }
    });
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_building, menu);
    return true;
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (light != null) {
      int id = item.getItemId();
      if (id == R.id.menu_action_anchor) {
        isMapAnchorLight = !isMapAnchorLight;
        light.setAnchor(isMapAnchorLight ? Property.ANCHOR_MAP : Property.ANCHOR_VIEWPORT);
      } else if (id == R.id.menu_action_intensity) {
        isLowIntensityLight = !isLowIntensityLight;
        light.setIntensity(isLowIntensityLight ? 0.35f : 1.0f);
      } else if (id == android.R.id.home) {
        finish();
        return true;
      }
    }
    return super.onOptionsItemSelected(item);
  }
  @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
  protected void onStop() {
    super.onStop();
    mapView.onStop();
  }
  @Override
  public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);
  }
  @Override
  public void onLowMemory() {
    super.onLowMemory();
    mapView.onLowMemory();
  }
  @Override
  public void onDestroy() {
    super.onDestroy();
    mapView.onDestroy();
  }
}