Skip to main content

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.9.0, 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();
}
}