In this page

Custom Heatmap Layer

This example shows how to Add a HeatMap layer to MapView

  1. Create HeatMap source with GeoJson Source

  2. Create HeatMap Layer with heatmap properties

  3. Add HeatMap Layer to MapView

For all code examples, refer to Android Maps SDK Code Examples

activity_heatmaplayer.xml view source

1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    android:layout_width="match_parent"
4    android:layout_height="match_parent"
5    android:orientation="vertical">
6
7    <ai.nextbillion.maps.core.MapView
8        android:id="@+id/mapView"
9        android:layout_width="match_parent"
10        android:layout_height="match_parent" />
11
12</RelativeLayout>

HeatmapLayerActivity view source

1package ai.nextbillion;
2
3import android.os.Bundle;
4
5import java.net.URI;
6import java.net.URISyntaxException;
7
8import ai.nextbillion.maps.core.MapView;
9import ai.nextbillion.maps.core.NextbillionMap;
10import ai.nextbillion.maps.core.Style;
11import ai.nextbillion.maps.style.layers.CircleLayer;
12import ai.nextbillion.maps.style.layers.HeatmapLayer;
13import ai.nextbillion.maps.style.sources.GeoJsonSource;
14import androidx.appcompat.app.AppCompatActivity;
15
16import static ai.nextbillion.maps.style.expressions.Expression.get;
17import static ai.nextbillion.maps.style.expressions.Expression.heatmapDensity;
18import static ai.nextbillion.maps.style.expressions.Expression.interpolate;
19import static ai.nextbillion.maps.style.expressions.Expression.linear;
20import static ai.nextbillion.maps.style.expressions.Expression.literal;
21import static ai.nextbillion.maps.style.expressions.Expression.rgb;
22import static ai.nextbillion.maps.style.expressions.Expression.rgba;
23import static ai.nextbillion.maps.style.expressions.Expression.stop;
24import static ai.nextbillion.maps.style.expressions.Expression.zoom;
25import static ai.nextbillion.maps.style.layers.PropertyFactory.circleColor;
26import static ai.nextbillion.maps.style.layers.PropertyFactory.circleOpacity;
27import static ai.nextbillion.maps.style.layers.PropertyFactory.circleRadius;
28import static ai.nextbillion.maps.style.layers.PropertyFactory.circleStrokeColor;
29import static ai.nextbillion.maps.style.layers.PropertyFactory.circleStrokeWidth;
30import static ai.nextbillion.maps.style.layers.PropertyFactory.heatmapColor;
31import static ai.nextbillion.maps.style.layers.PropertyFactory.heatmapIntensity;
32import static ai.nextbillion.maps.style.layers.PropertyFactory.heatmapOpacity;
33import static ai.nextbillion.maps.style.layers.PropertyFactory.heatmapRadius;
34import static ai.nextbillion.maps.style.layers.PropertyFactory.heatmapWeight;
35
36/**
37 * Test activity showcasing the heatmap layer api.
38 */
39public class HeatmapLayerActivity extends AppCompatActivity {
40
41    private static final String EARTHQUAKE_SOURCE_URL = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson";
42    private static final String EARTHQUAKE_SOURCE_ID = "earthquakes";
43    private static final String HEATMAP_LAYER_ID = "earthquakes-heat";
44    private static final String HEATMAP_LAYER_SOURCE = "earthquakes";
45    private static final String CIRCLE_LAYER_ID = "earthquakes-circle";
46
47    private MapView mapView;
48    private NextbillionMap nextbillionMap;
49
50    @Override
51    public void onCreate(Bundle savedInstanceState) {
52        super.onCreate(savedInstanceState);
53        setContentView(R.layout.activity_heatmaplayer);
54        mapView = findViewById(R.id.mapView);
55        mapView.onCreate(savedInstanceState);
56        mapView.getMapAsync(map -> {
57            nextbillionMap = map;
58
59            try {
60                nextbillionMap.setStyle(new Style.Builder()
61                        .fromUri("https://api.nextbillion.io/maps/dark/style.json")
62                        .withSource(createEarthquakeSource())
63                        .withLayerAbove(createHeatmapLayer(), "waterway-bridge")
64                        .withLayerBelow(createCircleLayer(), HEATMAP_LAYER_ID)
65                );
66            } catch (URISyntaxException exception) {
67            }
68        });
69    }
70
71    private GeoJsonSource createEarthquakeSource() throws URISyntaxException {
72        return new GeoJsonSource(EARTHQUAKE_SOURCE_ID, new URI(EARTHQUAKE_SOURCE_URL));
73    }
74
75    private HeatmapLayer createHeatmapLayer() {
76        HeatmapLayer layer = new HeatmapLayer(HEATMAP_LAYER_ID, EARTHQUAKE_SOURCE_ID);
77        layer.setMaxZoom(9);
78        layer.setSourceLayer(HEATMAP_LAYER_SOURCE);
79        layer.setProperties(
80
81                // Color ramp for heatmap.  Domain is 0 (low) to 1 (high).
82                // Begin color ramp at 0-stop with a 0-transparancy color
83                // to create a blur-like effect.
84                heatmapColor(
85                        interpolate(
86                                linear(), heatmapDensity(),
87                                literal(0), rgba(33, 102, 172, 0),
88                                literal(0.2), rgb(103, 169, 207),
89                                literal(0.4), rgb(209, 229, 240),
90                                literal(0.6), rgb(253, 219, 199),
91                                literal(0.8), rgb(239, 138, 98),
92                                literal(1), rgb(178, 24, 43)
93                        )
94                ),
95
96                // Increase the heatmap weight based on frequency and property magnitude
97                heatmapWeight(
98                        interpolate(
99                                linear(), get("mag"),
100                                stop(0, 0),
101                                stop(6, 1)
102                        )
103                ),
104
105                // Increase the heatmap color weight weight by zoom level
106                // heatmap-intensity is a multiplier on top of heatmap-weight
107                heatmapIntensity(
108                        interpolate(
109                                linear(), zoom(),
110                                stop(0, 1),
111                                stop(9, 3)
112                        )
113                ),
114
115                // Adjust the heatmap radius by zoom level
116                heatmapRadius(
117                        interpolate(
118                                linear(), zoom(),
119                                stop(0, 2),
120                                stop(9, 20)
121                        )
122                ),
123
124                // Transition from heatmap to circle layer by zoom level
125                heatmapOpacity(
126                        interpolate(
127                                linear(), zoom(),
128                                stop(7, 1),
129                                stop(9, 0)
130                        )
131                )
132        );
133        return layer;
134    }
135
136    private CircleLayer createCircleLayer() {
137        CircleLayer circleLayer = new CircleLayer(CIRCLE_LAYER_ID, EARTHQUAKE_SOURCE_ID);
138        circleLayer.setProperties(
139
140                // Size circle radius by earthquake magnitude and zoom level
141                circleRadius(
142                        interpolate(
143                                linear(), zoom(),
144                                literal(7), interpolate(
145                                        linear(), get("mag"),
146                                        stop(1, 1),
147                                        stop(6, 4)
148                                ),
149                                literal(16), interpolate(
150                                        linear(), get("mag"),
151                                        stop(1, 5),
152                                        stop(6, 50)
153                                )
154                        )
155                ),
156
157                // Color circle by earthquake magnitude
158                circleColor(
159                        interpolate(
160                                linear(), get("mag"),
161                                literal(1), rgba(33, 102, 172, 0),
162                                literal(2), rgb(103, 169, 207),
163                                literal(3), rgb(209, 229, 240),
164                                literal(4), rgb(253, 219, 199),
165                                literal(5), rgb(239, 138, 98),
166                                literal(6), rgb(178, 24, 43)
167                        )
168                ),
169
170                // Transition from heatmap to circle layer by zoom level
171                circleOpacity(
172                        interpolate(
173                                linear(), zoom(),
174                                stop(7, 0),
175                                stop(8, 1)
176                        )
177                ),
178                circleStrokeColor("white"),
179                circleStrokeWidth(1.0f)
180        );
181
182        return circleLayer;
183    }
184
185    @Override
186    protected void onStart() {
187        super.onStart();
188        mapView.onStart();
189    }
190
191    @Override
192    protected void onResume() {
193        super.onResume();
194        mapView.onResume();
195    }
196
197    @Override
198    protected void onPause() {
199        super.onPause();
200        mapView.onPause();
201    }
202
203    @Override
204    protected void onStop() {
205        super.onStop();
206        mapView.onStop();
207    }
208
209    @Override
210    public void onSaveInstanceState(Bundle outState) {
211        super.onSaveInstanceState(outState);
212        mapView.onSaveInstanceState(outState);
213    }
214
215    @Override
216    public void onLowMemory() {
217        super.onLowMemory();
218        mapView.onLowMemory();
219    }
220
221    @Override
222    public void onDestroy() {
223        super.onDestroy();
224        mapView.onDestroy();
225    }
226}
227

This code is an example of an Android activity that showcases the use of a heatmap layer in a map view. The activity creates a map view, sets up a heatmap layer with a GeoJSON data source, and adds the heatmap layer to the map view.

initMapView:

  1. The map view is initialized in the onCreate method by calling mapView.onCreate(savedInstanceState). This sets up the map view and prepares it for use.

Create HeatMap source with GeoJson Source:

  1. The createEarthquakeSource method creates a GeoJsonSource for the heatmap layer using a GeoJSON data source. It takes the URL of the GeoJSON data as a parameter and creates a new GeoJsonSource object with a unique ID and the provided data source URL.

Create HeatMap Layer with heatmap properties:

  1. The createHeatmapLayer method creates a HeatmapLayer object with a unique ID and sets various properties for the heatmap layer.

  2. The properties include the color ramp for the heatmap, the weight of the heatmap based on frequency and magnitude, the intensity and radius of the heatmap based on the zoom level, and the opacity transition from the heatmap to the circle layer.

Add HeatMap Layer to MapView:

  1. In the onCreate method, after setting up the map view, the nextbillionMap.setStyle method is called to set the map style and add the heatmap layer to the map view.

  2. The Style.Builder is used to create a new map style and the createEarthquakeSource and createHeatmapLayer methods are called to create the GeoJSON data source and heatmap layer, respectively.

  3. The created source and layer are then added to the map style using the withSource and withLayerAbove or withLayerBelow methods, depending on the desired layer order.

Note: The code also includes methods for creating a circle layer, setting up the map view lifecycle callbacks, and handling various other lifecycle events of the activity.

DIDN'T FIND WHAT YOU LOOKING FOR?