Hi,

What "underlying bitmap" are you referring to? In the onDraw() method, the
Canvas is used to draw onto your application's window buffer.

On Mon, Feb 14, 2011 at 7:55 PM, Mikey <[email protected]> wrote:

> Here's my problem. I finally figured out how to get my custom view
> working, but discovered that "canvas.drawCircle(..)" draws based on
> the screens dimensions and not the underlying bitmap (I may be
> misusing some terms/concepts here, still a little iffy on the whole
> custom view).
>
> Basically, I have a bitmap of a map image, and I want to be able to
> draw based on the bitmap's pixel dimensions, and to the bitmap if
> possible, so that when it's panned/zoomed, it stays in its respective
> place. Here is the code for my custom view. I x'd out my latitude and
> longitude. The touch handling is code adapted from a Hello, Android
> (3e) excerpt.
>
> package mikey.gps.NAV;
>
> import java.util.Vector;
>
> import android.content.Context;
> import android.graphics.Bitmap;
> import android.graphics.BitmapFactory;
> import android.graphics.Canvas;
> import android.graphics.Matrix;
> import android.graphics.Paint;
> import android.graphics.PointF;
> import android.util.AttributeSet;
> import android.util.FloatMath;
> import android.view.MotionEvent;
> import android.view.View;
>
> public class CustomView extends View {
>        private int mMode;
>        private double curLat, curLng;
>        public static final int MAP = 0;
>        public static final int NAV = 1;
>        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
>        Vector<LocationNode> mPath = new Vector<LocationNode>();
>        Bitmap map;
>
>        //Geographical information for translating to pixels
>        private double XZero = xxxxxx;
>        private double YZero = yyyyyyy;
>        private double XWidth = 0.01388333333334;
>        private double YWidth = 0.00693333333334;
>              //Image dimensions
>        private double IWidth = 1389;
>        private double IHeight = 971;
>
>
>        //Matrices for scaling the image
>        public Matrix matrix = new Matrix();
>        Matrix savedMatrix = new Matrix();
>
>        static final int NONE = 0;
>        static final int DRAG = 1;
>        static final int ZOOM = 2;
>        int mode = NONE;
>
>              PointF start = new PointF();
>        PointF mid = new PointF();
>        float oldDist = 1f;
>
>        public CustomView(Context context, AttributeSet attrs) {
>                super(context, attrs);
>                init();
>        }
>
>        public CustomView(Context context, AttributeSet attrs, int defStyle)
> {
>                super(context, attrs, defStyle);
>                // TODO Auto-generated constructor stub
>        }
>
>        public CustomView(Context context) {
>                super(context);
>                init();
>        }
>        private void init() {
>                map =
> BitmapFactory.decodeResource(getContext().getResources(),
> R.drawable.campus);
>                //mPaint.setFilterBitmap(true);
>                matrix.setTranslate(1f, 1f);
>                invalidate();
>        }
>
>        /* When the view is invalidated, onDraw does different actions
>         * depending on its mode. If it is the map display, it simply
>         * draws a circle on the current location. If it is on navigate,
>         * it draws a circle on the start and goal nodes, then lines to
>         * form the path.
>         *
>         * (non-Javadoc)
>         * @see android.view.View#onDraw(android.graphics.Canvas)
>         */
>        @Override
>        protected void onDraw(Canvas canvas) {
>                // TODO Auto-generated method stub
>                super.onDraw(canvas);
>                canvas.drawBitmap(map, matrix, mPaint);
>                if(mMode == NAV) {
>
>  canvas.drawCircle(translateX(mPath.lastElement().lat),
>                                        translateY(mPath.lastElement().lng),
> 10, mPaint);
>
>  canvas.drawCircle(translateX(mPath.firstElement().lat),
>
>  translateY(mPath.firstElement().lng), 10, mPaint);
>                        for(int i = 0; i < mPath.size()- 1; i++) {
>                                LocationNode startNode = mPath.elementAt(i);
>                                LocationNode stopNode =
> mPath.elementAt(i+1);
>                                float startX = translateX(startNode.lat);
>                                float startY = translateY(startNode.lng);
>                                float stopX = translateX(stopNode.lat);
>                                float stopY = translateY(stopNode.lng);
>                                canvas.drawLine(startX, startY, stopX,
> stopY, mPaint);
>                        }
>                }
>                else if (mMode == MAP) {
>                        canvas.drawCircle(translateX(curLat),
>                                        translateY(curLng), 10, mPaint);
>                }
>        }
>
>        @Override
>        public boolean onTouchEvent(MotionEvent e) {
>                // TODO Auto-generated method stub
>                WrapMotionEvent event = WrapMotionEvent.wrap(e);
>                switch (event.getAction() & MotionEvent.ACTION_MASK) {
>              case MotionEvent.ACTION_DOWN:
>                 savedMatrix.set(matrix);
>                 start.set(event.getX(), event.getY());
>                 mode = DRAG;
>                 break;
>              case MotionEvent.ACTION_POINTER_DOWN:
>                 oldDist = spacing(event);
>                 if (oldDist > 10f) {
>                    savedMatrix.set(matrix);
>                    midPoint(mid, event);
>                    mode = ZOOM;
>                 }
>                 break;
>              case MotionEvent.ACTION_UP:
>              case MotionEvent.ACTION_POINTER_UP:
>                 mode = NONE;
>                 break;
>              case MotionEvent.ACTION_MOVE:
>                 if (mode == DRAG) {
>                    // ...
>                    matrix.set(savedMatrix);
>                    matrix.postTranslate(event.getX() - start.x,
>                          event.getY() - start.y);
>                 }
>                 else if (mode == ZOOM) {
>                    float newDist = spacing(event);
>                    if (newDist > 10f) {
>                       matrix.set(savedMatrix);
>                       float scale = newDist / oldDist;
>                       matrix.postScale(scale, scale, mid.x, mid.y);
>                    }
>                 }
>                 break;
>              }
>                invalidate();
>                return true;
>        }
>
>
>
>        /* Handler method for touch events. The event
>         * is passed in from the overlying activity.
>         */
>        public void setMatrix(WrapMotionEvent event) {
>                // Handle touch events here...
>              switch (event.getAction() & MotionEvent.ACTION_MASK) {
>              case MotionEvent.ACTION_DOWN:
>                 savedMatrix.set(matrix);
>                 start.set(event.getX(), event.getY());
>                 mode = DRAG;
>                 break;
>              case MotionEvent.ACTION_POINTER_DOWN:
>                 oldDist = spacing(event);
>                 if (oldDist > 10f) {
>                    savedMatrix.set(matrix);
>                    midPoint(mid, event);
>                    mode = ZOOM;
>                 }
>                 break;
>              case MotionEvent.ACTION_UP:
>              case MotionEvent.ACTION_POINTER_UP:
>                 mode = NONE;
>                 break;
>              case MotionEvent.ACTION_MOVE:
>                 if (mode == DRAG) {
>                    // ...
>                    matrix.set(savedMatrix);
>                    matrix.postTranslate(event.getX() - start.x,
>                          event.getY() - start.y);
>                 }
>                 else if (mode == ZOOM) {
>                    float newDist = spacing(event);
>                    if (newDist > 10f) {
>                       matrix.set(savedMatrix);
>                       float scale = newDist / oldDist;
>                       matrix.postScale(scale, scale, mid.x, mid.y);
>                    }
>                 }
>                 break;
>              }
>           }
>
>           /** Determine the space between the first two fingers */
>           private float spacing(WrapMotionEvent event) {
>              // ...
>              float x = event.getX(0) - event.getX(1);
>              float y = event.getY(0) - event.getY(1);
>              return FloatMath.sqrt(x * x + y * y);
>           }
>
>           /** Calculate the mid point of the first two fingers */
>           private void midPoint(PointF point, WrapMotionEvent event) {
>              // ...
>              float x = event.getX(0) + event.getX(1);
>              float y = event.getY(0) + event.getY(1);
>              point.set(x / 2, y / 2);
>           }
>           /* Translates the latitude coordinate into a pixel coordinate */
>           public float translateX(double x) {
>                   float newX = (float) (IWidth * ((x - XZero) / XWidth));
>                   return newX;
>                }
>           /* Translates the longitude coordinate into a pixel coordinate */
>                public float translateY(double y) {
>                        float newY = (float) (IHeight * ((YZero - y) /
> YWidth));
>                        return newY;
>                }
>           /* Called by the navigator to enable drawing the route */
>           public void setPath(Vector<LocationNode> path) {
>                   mPath.clear();
>                   mPath = new Vector<LocationNode>(path);
>           }
>           /* Called by the map display to enable drawing the
>            *  current location */
>           public void setCurLocation(double lat, double lng) {
>                   curLat = lat;
>                   curLng = lng;
>           }
>        public void setMode(int mode) {
>                mMode = mode;
>        }
>        }
>
> I'm currently  working with "MAP" mode, but it will also come into
> play for NAV. But I basically need to draw to the bitmap, which is
> scaled and manipulated through the canvas(?) so that the current
> location dot will stay in the same spot when the bitmap is panned or
> zoomed, instead of staying in a static location based on the screen's
> dimensions. Any advice?
>
> -Mike
>
> --
> 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
>



-- 
Romain Guy
Android framework engineer
[email protected]

Note: please don't send private questions to me, as I don't have time to
provide private support.  All such questions should be posted on public
forums, where I and others can see and answer them

-- 
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