In this page

Animate Image Source Layer

This example shows how to Animate the Runtime Map style layer

  1. Add Image Source layer

  2. 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:

  1. The MapView is initialized in the onCreate method by finding the view with the ID mapView from the layout file.

  2. 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:

  1. The onMapReady method is called when the NextbillionMap instance is ready.

  2. A LatLngQuad is created to define the corners of a quadrilateral region on the map.

  3. A CameraPosition is defined to set the initial camera position of the map.

  4. An ImageSource is created with an ID, the LatLngQuad, and the resource ID of the first radar image.

  5. A RasterLayer is created with an ID and the ID of the ImageSource.

  6. The map style is set using a Style.Builder by specifying the style JSON URI, adding the ImageSource, and adding the RasterLayer.

  7. A RefreshImageRunnable is created to handle the animation by periodically changing the image of the ImageSource.

  8. The RefreshImageRunnable is scheduled to run every 100 milliseconds.

Animating Image Source:

  1. The RefreshImageRunnable class is a custom Runnable implementation.

  2. It keeps track of the current image index and an array of Bitmaps representing the radar images.

  3. In the constructor, it initializes the array of Bitmaps with the radar images and sets the initial image index.

  4. In the run method, it updates the image of the ImageSource with the current Bitmap.

  5. The image index is incremented, and if it exceeds the number of images, it is reset to 0.

  6. The RefreshImageRunnable is rescheduled to run after 1 second (1000 milliseconds) using the Handler instance.

Additional notes:

  1. The code includes lifecycle methods (onStart, onResume, onPause, onStop, onDestroy, onSaveInstanceState) to manage the lifecycle of the MapView.

  2. The code uses Nextbillion map library classes and methods for map-related operations.

  3. The code also includes utility methods (getBitmap) to convert resource IDs to Bitmaps for the radar images.

DIDN'T FIND WHAT YOU LOOKING FOR?