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