Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Adding extrusion coloring match expression Kotlin example #1370

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.mapbox.mapboxandroiddemo.examples.dds.PropertyIconDeterminationActivity;
import com.mapbox.mapboxandroiddemo.examples.camera.ZoomToShowClusterLeavesActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.WithinExpressionActivity;
import com.mapbox.mapboxandroiddemo.examples.extrusions.ExtrusionColorExpressionKotlinActivity;
import com.mapbox.mapboxandroiddemo.examples.extrusions.OpacityZoomChangeExtrusionKotlinActivity;
import com.mapbox.mapboxandroiddemo.examples.javaservices.DirectionsProfileToggleActivity;
import com.mapbox.mapboxandroiddemo.examples.javaservices.KotlinBorderedCircleActivity;
Expand Down Expand Up @@ -793,6 +794,14 @@ private void initializeModels() {
null,
R.string.activity_extrusions_single_highlighted_building_extrusion_url, false, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.id.nav_extrusions,
R.string.activity_extrusions_color_expression_title,
R.string.activity_extrusions_color_expression_description,
null,
new Intent(MainActivity.this, ExtrusionColorExpressionKotlinActivity.class),
R.string.activity_extrusions_color_expression_url, false, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.id.nav_plugins,
R.string.activity_plugins_traffic_plugin_title,
Expand Down
7 changes: 7 additions & 0 deletions MapboxAndroidDemo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.extrusions.ExtrusionColorExpressionKotlinActivity"
android:label="@string/activity_extrusions_color_expression_title">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.dds.PolygonHolesActivity"
android:label="@string/activity_dds_polygon_holes_title">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package com.mapbox.mapboxandroiddemo.examples.extrusions

import android.graphics.Color
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.Feature
import com.mapbox.mapboxandroiddemo.R
import com.mapbox.mapboxsdk.Mapbox
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.expressions.Expression
import com.mapbox.mapboxsdk.style.expressions.Expression.color
import com.mapbox.mapboxsdk.style.expressions.Expression.get
import com.mapbox.mapboxsdk.style.expressions.Expression.id
import com.mapbox.mapboxsdk.style.expressions.Expression.literal
import com.mapbox.mapboxsdk.style.expressions.Expression.match
import com.mapbox.mapboxsdk.style.expressions.Expression.stop
import com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionColor
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight
import com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity
import com.mapbox.mapboxsdk.style.layers.PropertyValue
import kotlinx.android.synthetic.main.activity_extrusion_color_expression.mapView

/**
* Use runtime styling to make a [FillExtrusionLayer]'s opacity based on the
* map's zoom level. The 3D building extrusions will be come less opaque as the
* camera moves closer to the buildings.
*/
class ExtrusionColorExpressionKotlinActivity : AppCompatActivity(), MapboxMap.OnMapClickListener {
private var mapboxMap: MapboxMap? = null
private var lastQueryLatLng: LatLng? = null

override fun onCreate(savedInstanceState: Bundle?) {
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_color_expression)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync { mapboxMap ->
this.mapboxMap = mapboxMap
mapboxMap.setStyle(Style.DARK) { style ->
lastQueryLatLng = mapboxMap.cameraPosition.target
addExtrusionLayerToMap(style)
mapboxMap.addOnMapClickListener(this)
Toast.makeText(this,
R.string.tap_on_building_to_highlight,
Toast.LENGTH_SHORT).show()
}
}
}

override fun onMapClick(mapTapLatLng: LatLng): Boolean {
adjustUiForSelectedBuilding(mapTapLatLng)
return true
}

/**
* Adjusts the example's UI for the selected building in the [FillExtrusionLayer].
* Depending on whether all buildings are shown or not, the entire extrusion will move
* or just the color of the selected extrusion will change.
*
* @param clickLatLng The [LatLng] of wherever the map was tapped.
*/
private fun adjustUiForSelectedBuilding(clickLatLng: LatLng) {
lastQueryLatLng = clickLatLng
mapboxMap?.getStyle { style ->
val buildingExtrusionLayer = style.getLayerAs<FillExtrusionLayer>(EXTRUSION_BUILDING_LAYER_ID)
buildingExtrusionLayer?.setProperties(getFillExtrusionColorProperty(lastQueryLatLng))
}
}

/**
* Returns a [fillExtrusionColor] statement so that the selected building is colored
* appropriately.
*/
private fun getFillExtrusionColorProperty(queryLatLng: LatLng?): PropertyValue<Expression> {
return fillExtrusionColor(match(
Expression.toString(id()),
color(Color.parseColor(EXTRUSION_COLOR_HEX)),
stop(literal(getBuildingId(queryLatLng)), color(Color.parseColor(SELECTED_EXTRUSION_COLOR_HEX)))))
}

/**
* Gets the [Feature.id] of the building [Feature] that has the queryLatLng
* within its footprint. This ID is then used in the filter that's applied to the
* [FillExtrusionLayer].
*
* @param queryLatLng the [LatLng] to use for querying the [MapboxMap] to eventually
* get the building ID.
* @return the selected building's ID
*/
private fun getBuildingId(queryLatLng: LatLng?): String {
mapboxMap?.let {
val renderedBuildingFootprintFeatures = it.queryRenderedFeatures(
it.projection.toScreenLocation(queryLatLng!!), BUILDING_LAYER_ID)
if (renderedBuildingFootprintFeatures.isNotEmpty()) {
return renderedBuildingFootprintFeatures[0].id()!!
}
}
return DEFAULT_BUILDING_ID
}

/**
* Adds a [FillExtrusionLayer] to the map.
*
* @param loadedMapStyle A loaded [Style] on the [MapboxMap].
*/
private fun addExtrusionLayerToMap(loadedMapStyle: Style) {
FillExtrusionLayer(EXTRUSION_BUILDING_LAYER_ID, COMPOSITE_SOURCE_ID).also {
it.sourceLayer = BUILDING_LAYER_ID
it.setProperties(
getFillExtrusionColorProperty(lastQueryLatLng),
fillExtrusionHeight(get("height")),
fillExtrusionOpacity(EXTRUSION_OPACITY))
loadedMapStyle.addLayer(it)
}
}

override fun onStart() {
super.onStart()
mapView.onStart()
}

override fun onResume() {
super.onResume()
mapView.onResume()
}

override fun onPause() {
super.onPause()
mapView.onPause()
}

override fun onStop() {
super.onStop()
mapView.onStop()
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView.onSaveInstanceState(outState)
}

override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}

override fun onDestroy() {
super.onDestroy()
mapboxMap?.removeOnMapClickListener(this)
mapView.onDestroy()
}

companion object {
private const val EXTRUSION_OPACITY = 0.6f
private const val EXTRUSION_COLOR_HEX = "#ecca02"
private const val SELECTED_EXTRUSION_COLOR_HEX = "#e700d2"
private const val DEFAULT_BUILDING_ID = "0"
private const val BUILDING_LAYER_ID = "building"
private const val COMPOSITE_SOURCE_ID = "composite"
private const val EXTRUSION_BUILDING_LAYER_ID = "EXTRUSION_BUILDING_LAYER_ID"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?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">

<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
mapbox:mapbox_cameraTargetLat="50.1094589"
mapbox:mapbox_cameraTargetLng="8.68256759"
mapbox:mapbox_cameraTilt="45"
mapbox:mapbox_cameraZoom="17.7" />

</FrameLayout>
3 changes: 3 additions & 0 deletions MapboxAndroidDemo/src/main/res/values/activity_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -499,4 +499,7 @@
<!-- Single building highlight -->
<string name="tap_on_building">Tap on a building to get started</string>
<string name="keep_tapping_on_building_footprint">Keep tapping on any building footprints!</string>

<!-- Extrusion color expression highlight -->
<string name="tap_on_building_to_highlight">Tap on a building to highlight it</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<string name="activity_extrusions_adjust_extrusions_description">Change the location and color of the light shined on extrusions.</string>
<string name="activity_extrusions_rotate_extrusions_description">Rotate and tilt device to change camera and see all around 3D buildings.</string>
<string name="activity_extrusions_zoom_opacity_change_description">Use runtime styling to make the 3D buildings\' opacity dependent on the map\'s zoom level.</string>
<string name="activity_extrusions_color_expression_description">Use Maps SDK Expressions to change the color of a single building amongst all of the other extruded buildings.</string>
<string name="activity_extrusions_indoor_3d_description">Create a 3D indoor map with the fill-extrude-height paint property.</string>
<string name="activity_extrusions_single_highlighted_building_extrusion_description">Highlight a single building extrusion with a different color when tapped on.</string>
<string name="activity_dds_style_circle_categorically_description">Using a categorical circle-color property function for a visualization.</string>
Expand Down
1 change: 1 addition & 0 deletions MapboxAndroidDemo/src/main/res/values/titles_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<string name="activity_extrusions_indoor_3d_title">Extrude polygons for 3D indoor mapping</string>
<string name="activity_extrusions_zoom_opacity_change_title">Zoom-based opacity</string>
<string name="activity_extrusions_single_highlighted_building_extrusion_title">Highlighted building</string>
<string name="activity_extrusions_color_expression_title">Single color expression</string>
<string name="activity_dds_style_circle_categorically_title">Style circles categorically</string>
<string name="activity_dds_style_kotlin_circle_categorically_title">Kotlin: Styled circles</string>
<string name="activity_dds_choropleth_zoom_change_title">Update a choropleth layer by zoom level</string>
Expand Down
1 change: 1 addition & 0 deletions MapboxAndroidDemo/src/main/res/values/urls_strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<string name="activity_extrusions_rotate_extrusions_url" translatable="false">http://i.imgur.com/OzcCsB2.png</string>
<string name="activity_extrusions_zoom_opacity_change_url" translatable="false">https://i.imgur.com/7FomeoZ.png</string>
<string name="activity_extrusions_single_highlighted_building_extrusion_url" translatable="false">https://i.imgur.com/Wy3Gh1Q.png</string>
<string name="activity_extrusions_color_expression_url" translatable="false">https://i.imgur.com/dfc61TL.png</string>
<string name="activity_dds_style_circle_categorically_url" translatable="false">http://i.imgur.com/C3mtfgF.png</string>
<string name="activity_dds_heatmap_url" translatable="false">https://i.imgur.com/VektJUJ.png</string>
<string name="activity_dds_multiple_heatmap_styling_url" translatable="false">https://i.imgur.com/Uw2DHWB.png</string>
Expand Down