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

Commit

Permalink
Added working heatmap example (#683)
Browse files Browse the repository at this point in the history
  • Loading branch information
Langston Smith authored Apr 19, 2018
1 parent 0593d1d commit 9025d36
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 5 deletions.
7 changes: 7 additions & 0 deletions MapboxAndroidDemo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.dds.HeatmapActivity"
android:label="@string/activity_dds_heatmap_title">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.mapbox.mapboxandroiddemo.MainActivity" />
</activity>
<activity
android:name=".examples.camera.RestrictCameraActivity"
android:label="@string/activity_camera_restrict_title">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import com.mapbox.mapboxandroiddemo.examples.dds.ChoroplethJsonVectorMixActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.ChoroplethZoomChangeActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.CreateHotspotsActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.HeatmapActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.MultipleGeometriesActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.StyleCirclesCategoricallyActivity;
import com.mapbox.mapboxandroiddemo.examples.dds.StyleLineIdentityPropertyActivity;
Expand Down Expand Up @@ -407,19 +408,19 @@ private void listItems(int id) {
exampleItemModels.add(new ExampleItemModel(
R.string.activity_plugins_places_plugin_title, R.string.activity_plugins_places_plugin_description,
new Intent(MainActivity.this, PlacesPluginActivity.class),
R.string.activity_plugins_places_plugin_url, true, BuildConfig.MIN_SDK_VERSION));
R.string.activity_plugins_places_plugin_url, false, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.string.activity_plugins_marker_clusters_plugin_title,
R.string.activity_plugins_geojson_marker_clusters_description,
new Intent(MainActivity.this, MarkerClustersPluginActivity.class),
R.string.activity_plugins_markers_clusters_plugin_url, true, BuildConfig.MIN_SDK_VERSION)
R.string.activity_plugins_markers_clusters_plugin_url, false, BuildConfig.MIN_SDK_VERSION)
);
exampleItemModels.add(new ExampleItemModel(
R.string.activity_plugins_localization_plugin_title,
R.string.activity_plugins_localization_plugin_description,
new Intent(MainActivity.this, LocalizationPluginActivity.class),
R.string.activity_plugins_localization_plugin_url, true, BuildConfig.MIN_SDK_VERSION)
R.string.activity_plugins_localization_plugin_url, false, BuildConfig.MIN_SDK_VERSION)
);
currentCategory = R.id.nav_plugins;
break;
Expand Down Expand Up @@ -588,7 +589,7 @@ private void listItems(int id) {
R.string.activity_lab_symbol_layer_and_mapillary_on_map_title,
R.string.activity_lab_symbol_layer_and_mapillary_on_map_description,
new Intent(MainActivity.this, SymbolLayerMapillaryActivity.class),
R.string.activity_lab_symbol_layer_on_map_url, true, BuildConfig.MIN_SDK_VERSION));
R.string.activity_lab_symbol_layer_on_map_url, false, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.string.activity_lab_los_angeles_tourism_title,
Expand Down Expand Up @@ -642,11 +643,18 @@ private void listItems(int id) {
R.string.activity_labs_gif_on_map_title,
R.string.activity_labs_gif_on_map_description,
new Intent(MainActivity.this, AnimatedImageSourceActivity.class),
R.string.activity_labs_gif_on_map_url, true, BuildConfig.MIN_SDK_VERSION
R.string.activity_labs_gif_on_map_url, false, BuildConfig.MIN_SDK_VERSION
));
currentCategory = R.id.nav_lab;
break;
case R.id.nav_dds:

exampleItemModels.add(new ExampleItemModel(
R.string.activity_dds_heatmap_title,
R.string.activity_dds_heatmap_description,
new Intent(MainActivity.this, HeatmapActivity.class),
R.string.activity_dds_heatmap_url, true, BuildConfig.MIN_SDK_VERSION));

exampleItemModels.add(new ExampleItemModel(
R.string.activity_dds_style_circle_categorically_title,
R.string.activity_dds_style_circle_categorically_description,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package com.mapbox.mapboxandroiddemo.examples.dds;

import android.os.Bundle;
import android.support.v7.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.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.HeatmapLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;

import java.net.MalformedURLException;
import java.net.URL;

import timber.log.Timber;

import static com.mapbox.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.expressions.Expression.heatmapDensity;
import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate;
import static com.mapbox.mapboxsdk.style.expressions.Expression.linear;
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgb;
import static com.mapbox.mapboxsdk.style.expressions.Expression.rgba;
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.circleColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleOpacity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeWidth;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapIntensity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapOpacity;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.heatmapWeight;

public class HeatmapActivity extends AppCompatActivity {

private static final String EARTHQUAKE_SOURCE_URL = "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson";
private static final String EARTHQUAKE_SOURCE_ID = "earthquakes";
private static final String HEATMAP_LAYER_ID = "earthquakes-heat";
private static final String HEATMAP_LAYER_SOURCE = "earthquakes";
private static final String CIRCLE_LAYER_ID = "earthquakes-circle";

private MapView mapView;
private MapboxMap mapboxMap;

@Override
public 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_heatmap);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(MapboxMap mapboxMap) {
HeatmapActivity.this.mapboxMap = mapboxMap;
addEarthquakeSource();
addHeatmapLayer();
addCircleLayer();
}
});
}

private void addEarthquakeSource() {
try {
mapboxMap.addSource(new GeoJsonSource(EARTHQUAKE_SOURCE_ID, new URL(EARTHQUAKE_SOURCE_URL)));
} catch (MalformedURLException malformedUrlException) {
Timber.e(malformedUrlException, "That's not an url... ");
}
}

private void addHeatmapLayer() {
HeatmapLayer layer = new HeatmapLayer(HEATMAP_LAYER_ID, EARTHQUAKE_SOURCE_ID);
layer.setMaxZoom(9);
layer.setSourceLayer(HEATMAP_LAYER_SOURCE);
layer.setProperties(

// Color ramp for heatmap. Domain is 0 (low) to 1 (high).
// Begin color ramp at 0-stop with a 0-transparancy color
// to create a blur-like effect.
heatmapColor(
interpolate(
linear(), heatmapDensity(),
literal(0), rgba(33, 102, 172, 0),
literal(0.2), rgb(103, 169, 207),
literal(0.4), rgb(209, 229, 240),
literal(0.6), rgb(253, 219, 199),
literal(0.8), rgb(239, 138, 98),
literal(1), rgb(178, 24, 43)
)
),

// Increase the heatmap weight based on frequency and property magnitude
heatmapWeight(
interpolate(
linear(), get("mag"),
stop(0, 0),
stop(6, 1)
)
),

// Increase the heatmap color weight weight by zoom level
// heatmap-intensity is a multiplier on top of heatmap-weight
heatmapIntensity(
interpolate(
linear(), zoom(),
stop(0, 1),
stop(9, 3)
)
),

// Adjust the heatmap radius by zoom level
heatmapRadius(
interpolate(
linear(), zoom(),
stop(0, 2),
stop(9, 20)
)
),

// Transition from heatmap to circle layer by zoom level
heatmapOpacity(
interpolate(
linear(), zoom(),
stop(7, 1),
stop(9, 0)
)
)
);

mapboxMap.addLayerAbove(layer, "waterway-label");
}

private void addCircleLayer() {
CircleLayer circleLayer = new CircleLayer(CIRCLE_LAYER_ID, EARTHQUAKE_SOURCE_ID);
circleLayer.setProperties(

// Size circle radius by earthquake magnitude and zoom level
circleRadius(
interpolate(
linear(), zoom(),
literal(7), interpolate(
linear(), get("mag"),
stop(1, 1),
stop(6, 4)
),
literal(16), interpolate(
linear(), get("mag"),
stop(1, 5),
stop(6, 50)
)
)
),

// Color circle by earthquake magnitude
circleColor(
interpolate(
linear(), get("mag"),
literal(1), rgba(33, 102, 172, 0),
literal(2), rgb(103, 169, 207),
literal(3), rgb(209, 229, 240),
literal(4), rgb(253, 219, 199),
literal(5), rgb(239, 138, 98),
literal(6), rgb(178, 24, 43)
)
),

// Transition from heatmap to circle layer by zoom level
circleOpacity(
interpolate(
linear(), zoom(),
stop(7, 0),
stop(8, 1)
)
),
circleStrokeColor("white"),
circleStrokeWidth(1.0f)
);

mapboxMap.addLayerBelow(circleLayer, HEATMAP_LAYER_ID);
}

@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();
}
}
14 changes: 14 additions & 0 deletions MapboxAndroidDemo/src/main/res/layout/activity_heatmap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="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"
app:mapbox_styleUrl="@string/mapbox_style_dark"/>

</RelativeLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<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_indoor_3d_description">Create a 3D indoor map with the fill-extrude-height paint property.</string>
<string name="activity_dds_style_circle_categorically_description">Using a categorical circle-color property function for a visualization.</string>
<string name="activity_dds_heatmap_description">Add and customize a heatmap to visualize data.</string>
<string name="activity_dds_choropleth_zoom_change_description">Style a choropleth map with data-driven styling, local JSON data, and vector tile geometries.</string>
<string name="activity_dds_json_vector_mix_description">Style a choropleth map by merging local JSON data with vector tile geometries.</string>
<string name="activity_dds_style_line_identity_property_description">Using an identity line-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 @@ -35,6 +35,7 @@
<string name="activity_dds_style_line_identity_property_title">Style lines using an identity property function</string>
<string name="activity_dds_time_lapse_rainfall_points_title">Data time lapse</string>
<string name="activity_dds_multiple_geometries_title">Draw multiple geometries</string>
<string name="activity_dds_heatmap_title">Show heatmap data</string>
<string name="activity_annotation_marker_title">Draw a marker</string>
<string name="activity_annotation_custom_marker_title">Draw a custom marker icon</string>
<string name="activity_annotation_geojson_line_title">Draw a GeoJSON line</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 @@ -32,6 +32,7 @@
<string name="activity_extrusions_indoor_3d_url" translatable="false">http://i.imgur.com/1at7cMf.png</string>
<string name="activity_extrusions_rotate_extrusions_url" translatable="false">http://i.imgur.com/OzcCsB2.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">http://i.imgur.com/C3mtfgF.png</string>
<string name="activity_dds_choropleth_zoom_change_url" translatable="false">http://i.imgur.com/sPNpLEP.png</string>
<string name="activity_dds_style_line_identity_property_url" translatable="false">http://i.imgur.com/wgpKvZM.png</string>
<string name="activity_dds_json_vector_mix_url">http://i.imgur.com/1IXkw80.png</string>
Expand Down

0 comments on commit 9025d36

Please sign in to comment.