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
Animate Image Source Layer

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

1
package ai.nextbillion;
2
3
import android.content.Context;
4
import android.graphics.Bitmap;
5
import android.graphics.drawable.BitmapDrawable;
6
import android.graphics.drawable.Drawable;
7
import android.os.Bundle;
8
import android.os.Handler;
9
10
import ai.nextbillion.maps.Nextbillion;
11
import ai.nextbillion.maps.camera.CameraPosition;
12
import ai.nextbillion.maps.camera.CameraUpdateFactory;
13
import ai.nextbillion.maps.core.MapView;
14
import ai.nextbillion.maps.core.NextbillionMap;
15
import ai.nextbillion.maps.core.OnMapReadyCallback;
16
import ai.nextbillion.maps.core.Style;
17
import ai.nextbillion.maps.geometry.LatLng;
18
import ai.nextbillion.maps.geometry.LatLngQuad;
19
import ai.nextbillion.maps.style.layers.RasterLayer;
20
import ai.nextbillion.maps.style.sources.ImageSource;
21
import ai.nextbillion.maps.utils.BitmapUtils;
22
import androidx.annotation.NonNull;
23
import 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
*/
29
public 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.

© 2024 NextBillion.ai all rights reserved.