Animate Image Source Layer
This example shows how to Animate the Runtime Map style layer
-
Add Image Source layer
-
Update the Image source every second

For all code examples, refer to Android Maps Code Examples
activity_animated_image_source.xml view source
1<?xml version="1.0" encoding="utf-8"?>
2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:orientation="vertical">
7
8 <ai.nextbillion.maps.core.MapView
9 android:id="@id/mapView"
10 android:layout_width="match_parent"
11 android:layout_height="match_parent"
12 app:nbmap_cameraTargetLat="41.9567"
13 app:nbmap_cameraTargetLng="-78.6430"
14 app:nbmap_cameraZoom="5" />
15
16</RelativeLayout>
AnimatedImageSourceActivity view source
1package ai.nextbillion;
2
3import android.content.Context;
4import android.graphics.Bitmap;
5import android.graphics.drawable.BitmapDrawable;
6import android.graphics.drawable.Drawable;
7import android.os.Bundle;
8import android.os.Handler;
9
10import ai.nextbillion.maps.Nextbillion;
11import ai.nextbillion.maps.camera.CameraPosition;
12import ai.nextbillion.maps.camera.CameraUpdateFactory;
13import ai.nextbillion.maps.core.MapView;
14import ai.nextbillion.maps.core.NextbillionMap;
15import ai.nextbillion.maps.core.OnMapReadyCallback;
16import ai.nextbillion.maps.core.Style;
17import ai.nextbillion.maps.geometry.LatLng;
18import ai.nextbillion.maps.geometry.LatLngQuad;
19import ai.nextbillion.maps.style.layers.RasterLayer;
20import ai.nextbillion.maps.style.sources.ImageSource;
21import ai.nextbillion.maps.utils.BitmapUtils;
22import androidx.annotation.NonNull;
23import androidx.appcompat.app.AppCompatActivity;
24
25/**
26 * Test activity showing how to use a series of images to create an animation
27 * with an ImageSource
28 */
29public class AnimatedImageSourceActivity extends AppCompatActivity implements OnMapReadyCallback {
30
31 private static final String ID_IMAGE_SOURCE = "animated_image_source";
32 private static final String ID_IMAGE_LAYER = "animated_image_layer";
33
34 private MapView mapView;
35 private final Handler handler = new Handler();
36 private Runnable runnable;
37
38 @Override
39 protected void onCreate(Bundle savedInstanceState) {
40 super.onCreate(savedInstanceState);
41 setContentView(R.layout.activity_animated_image_source);
42 mapView = findViewById(R.id.mapView);
43 mapView.onCreate(savedInstanceState);
44 mapView.getMapAsync(this);
45 }
46
47 @Override
48 public void onMapReady(@NonNull final NextbillionMap map) {
49 LatLngQuad quad = new LatLngQuad(
50 new LatLng(27.40047198444738, 71.53771145635554),
51 new LatLng(27.40047198444738, 90.94171027114842),
52 new LatLng(15.333463356222776, 90.94171027114842),
53 new LatLng(15.333463356222776, 71.53771145635554)
54 );
55
56 CameraPosition position = new CameraPosition.Builder()
57 .target(new LatLng(21.333463356222776, 80.53771145635554))
58 .zoom(3.5)
59 .bearing(0)
60 .tilt(0)
61 .build();
62 map.animateCamera(CameraUpdateFactory.newCameraPosition(position));
63
64 final ImageSource imageSource = new ImageSource(ID_IMAGE_SOURCE, quad, R.mipmap.southeast_radar_0);
65 final RasterLayer layer = new RasterLayer(ID_IMAGE_LAYER, ID_IMAGE_SOURCE);
66 map.setStyle(new Style.Builder()
67 .fromUri("https://api.nextbillion.io/maps/streets/style.json")
68 .withSource(imageSource)
69 .withLayer(layer), style -> {
70 runnable = new RefreshImageRunnable(imageSource, handler);
71 handler.postDelayed(runnable, 100);
72 }
73 );
74 }
75
76 @Override
77 protected void onStart() {
78 super.onStart();
79 mapView.onStart();
80 }
81
82 @Override
83 public void onResume() {
84 super.onResume();
85 mapView.onResume();
86 }
87
88 @Override
89 public void onPause() {
90 super.onPause();
91 mapView.onPause();
92 }
93
94 @Override
95 protected void onStop() {
96 super.onStop();
97 mapView.onStop();
98 handler.removeCallbacks(runnable);
99 }
100
101 @Override
102 protected void onDestroy() {
103 super.onDestroy();
104 mapView.onDestroy();
105 }
106
107 @Override
108 protected void onSaveInstanceState(Bundle outState) {
109 super.onSaveInstanceState(outState);
110 mapView.onSaveInstanceState(outState);
111 }
112
113 private static class RefreshImageRunnable implements Runnable {
114
115 private ImageSource imageSource;
116 private Handler handler;
117 private Bitmap[] drawables;
118 private int drawableIndex;
119
120 Bitmap getBitmap(int resourceId) {
121 Context context = Nextbillion.getApplicationContext();
122 Drawable drawable = BitmapUtils.getDrawableFromRes(context, resourceId);
123 if (drawable instanceof BitmapDrawable) {
124 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
125 return bitmapDrawable.getBitmap();
126 }
127 return null;
128 }
129
130 RefreshImageRunnable(ImageSource imageSource, Handler handler) {
131 this.imageSource = imageSource;
132 this.handler = handler;
133 drawables = new Bitmap[4];
134 drawables[0] = getBitmap(R.mipmap.southeast_radar_0);
135 drawables[1] = getBitmap(R.mipmap.southeast_radar_1);
136 drawables[2] = getBitmap(R.mipmap.southeast_radar_2);
137 drawables[3] = getBitmap(R.mipmap.southeast_radar_3);
138 drawableIndex = 1;
139 }
140
141 @Override
142 public void run() {
143 imageSource.setImage(drawables[drawableIndex++]);
144 if (drawableIndex > 3) {
145 drawableIndex = 0;
146 }
147 handler.postDelayed(this, 1000);
148 }
149 }
150}
This example demonstrates how to create an animation using a series of images with an ImageSource in the NextbillionMap library. The animation consists of a radar image that changes every second.
Initializing MapView:
-
The MapView is initialized in the onCreate method by finding the view with the ID mapView from the layout file.
-
The onCreate method also calls mapView.onCreate(savedInstanceState) to create the MapView and mapView.getMapAsync(this) to get a reference to the NextbillionMap instance when it is ready.
Adding Image Source Layer:
-
The onMapReady method is called when the NextbillionMap instance is ready.
-
A LatLngQuad is created to define the corners of a quadrilateral region on the map.
-
A CameraPosition is defined to set the initial camera position of the map.
-
An ImageSource is created with an ID, the LatLngQuad, and the resource ID of the first radar image.
-
A RasterLayer is created with an ID and the ID of the ImageSource.
-
The map style is set using a Style.Builder by specifying the style JSON URI, adding the ImageSource, and adding the RasterLayer.
-
A RefreshImageRunnable is created to handle the animation by periodically changing the image of the ImageSource.
-
The RefreshImageRunnable is scheduled to run every 100 milliseconds.
Animating Image Source:
-
The RefreshImageRunnable class is a custom Runnable implementation.
-
It keeps track of the current image index and an array of Bitmaps representing the radar images.
-
In the constructor, it initializes the array of Bitmaps with the radar images and sets the initial image index.
-
In the run method, it updates the image of the ImageSource with the current Bitmap.
-
The image index is incremented, and if it exceeds the number of images, it is reset to 0.
-
The RefreshImageRunnable is rescheduled to run after 1 second (1000 milliseconds) using the Handler instance.
Additional notes:
-
The code includes lifecycle methods (onStart, onResume, onPause, onStop, onDestroy, onSaveInstanceState) to manage the lifecycle of the MapView.
-
The code uses Nextbillion map library classes and methods for map-related operations.
-
The code also includes utility methods (getBitmap) to convert resource IDs to Bitmaps for the radar images.