Below is a generalized version of the map overlay class of an
application I'm developing. The feature I'm trying to highlight is
that the class does all of its drawing to a bitmap and then re-renders
the bitmap when requested to draw the overlay onto a map that hasn't
moved. There are more details in the comments. I've realized
significant performance improvements in my app since implemented my
overlay this way.

I'm posting this in the hopes that it may be useful to others and also
for critiques. Any constructive criticism will be appreciated.

Thanks,
Dave



import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

/**
 * BitmapMapOverlay extends Overlay and implements an optimized draw()
method.
 *
 * Overview:
 *
 * My application maintains 1000's of geographic data points scattered
 * across the globe but only a few are rendered by a typical draw()
call.
 * Determining which data points to render is expensive.
 *
 * draw() is often called several times for the same map projection.
(It
 * appears to be called as map tiles are retrieved or refined.)
Therefore,
 * the same items are often drawn repeatedly. The draw() method below
draws
 * its items to a bitmap and then just re-draws the bitmap if the
projection
 * hasn't changed.
 *
 */
public class BitmapMapOverlay extends Overlay {

        // Used to determine whether the overlay bitmap needs to be redrawn
        private GeoPoint prevZeroZeroGeoPoint = new GeoPoint(0, 0);

        private Bitmap mOverlayBitmap = null;
        private Canvas mOverlayCanvas = null;
        private Paint  mOverlayBitmapPaint;

        public BitmapMapOverlay() {
                mOverlayBitmapPaint = new Paint();
                mOverlayBitmapPaint.setStyle(Paint.Style.FILL);
        }

        @Override
        public void draw(Canvas mapCanvas, MapView mapView, boolean shadow) {

                super.draw(mapCanvas, mapView, shadow);

                if (shadow) {
                        // All drawing done in the non-shadow layer
                        return;
                }

                // Retrieve the GeoPoint (longitude and latitude) under pixel 
0:0.
                GeoPoint zeroZeroGeoPoint = 
mapView.getProjection().fromPixels(0,
0);

                // Determine if overlay needs to be redrawn
                //
                // Note: Add whatever additional conditions you may need to
determine if the data has changed
                //       and needs to be redrawn. For example, my application's
database accessor class maintains
                //       a static "last modified time." I record the modified 
time
along with the GeoPoint at 0:0
                //       and redraw if either changes.
                //
                // Note 2: I originally thought I could compare the MapView's 
map
center GeoPoint and latitude
                //         span to the previously drawn values to determine 
whether
to redraw but I got
                //         weird results. It seems that draw() is called several
times during a map zoom's
                //         animation but that 'mapView' is set to the end of the
zoom so its center and span
                //         don't change. However, the projection does reflect 
the
current state of the zoom so
                //         checking if 0:0 moved works as desired.
                //
                if (zeroZeroGeoPoint.equals(prevZeroZeroGeoPoint)) {
                        // Map hasn't moved. Copy the previous drawing to the 
map's canvas
                        mapCanvas.drawBitmap(mOverlayBitmap, 0, 0, 
mOverlayBitmapPaint);
                        return;
                }

                // Save the value(s) used on the next draw to determine if the 
map
has scrolled or scaled
                prevZeroZeroGeoPoint = zeroZeroGeoPoint;

                if (mOverlayBitmap == null) {
                        // First call. Allocate the bitmap and attach it to the 
canvas
                        mOverlayBitmap = 
Bitmap.createBitmap(mapCanvas.getWidth(),
mapCanvas.getHeight(), Bitmap.Config.ARGB_8888);
                        mOverlayCanvas = new Canvas(mOverlayBitmap);
                }

                // Clear the overlay bitmap
                mOverlayBitmap.eraseColor(Color.TRANSPARENT);

                // 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
                //
                // Perform drawing operations here drawing everything on
'overlayCanvas'.
                //
                // Once drawing is complete, overlayBitmap will contain the 
image
                // to transfer to mapCanvas.
                //
                // 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

                // Copy the overlay bitmap to the map's canvas
                mapCanvas.drawBitmap(mOverlayBitmap, 0, 0, mOverlayBitmapPaint);

        }

}

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to