views:

1017

answers:

6

I've developed a GPS app in which i record the user roots and show it on the map.......but Panning around on the map when reviewing my route is painfully slow, it takes at least 4 or 5 seconds for the map to respond the finger swipes......

I've overridden the onDraw() method and drawing the lines to show the routes......is there any better way to do this so that panning becomes faster as in "MyTracks"...........

Thank you all..... Pratap S.

A: 

Overriding onDraw would be the only way. How are you drawing the tracks, maybe that can be made more efficient?

CaseyB
A: 

Thanks CaseyB for ur help.........

Following is the code to draw the routes on map...........please look into it nad guide me how can i make it more efficient so that the panning and zooming works failry well......

Thanks again

Regards PratapS

class PathOverlay extends Overlay{

    public PathOverlay() {
        // TODO Auto-generated constructor stub
        geopoints=new ArrayList<GeoPoint>();
        c.moveToFirst();
        for (int i = 0; i <c.getCount() ; i++){

            if(c.getDouble(c.getColumnIndex("latitude")) != 0.0 ||
                    c.getDouble(c.getColumnIndex("longitude"))!=0.0) {

                geopoints.add(getPoint(c.getDouble(c.getColumnIndex("latitude"))
                        , c.getDouble(c.getColumnIndex("longitude"))));
                gps_status.add(Boolean.parseBoolean(c.getString(c.getColumnIndex("gps") )));
                avgeSpeed_points.add(c.getFloat(9));
            }
            c.moveToNext();


        }

    }
    private GeoPoint getPoint(double lat, double lon) {
        return(new GeoPoint((int)(lat*1000000.0),(int)(lon*1000000.0)));
    }

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

    //  super.draw(canvas, mapView, shadow);
        mapView.getDrawingCache();

        Paint paint_Line=new Paint();
        //paint_Line.setColor(Color.RED);
        paint_Line.setARGB(255, 255, 0, 0);
        paint_Line.setStrokeWidth(3);
        paint_Line.setDither(true);
        paint_Line.setStyle(Style.FILL);
        paint_Line.setAntiAlias(true);
        paint_Line.setStrokeJoin(Paint.Join.ROUND);
        paint_Line.setStrokeCap(Paint.Cap.ROUND);



        mapView.postInvalidateDelayed(6000);


        for(int i=0;i<geopoints.size()-1;i++) {

            Point p1=new Point();
            Point p2=new Point();

            if((geopoints.get(i).getLatitudeE6()!=geopoints.get(i+1).getLatitudeE6())
                    && (geopoints.get(i).getLongitudeE6()!=geopoints.get(i+1).getLongitudeE6())
                    && gps_status.get(i+1)){
            paint_Line.setColor(Color.BLUE);
            mapView.getProjection().toPixels(geopoints.get(i), p1);
            mapView.getProjection().toPixels(geopoints.get(i+1),p2);
            canvas.drawLine(p1.x,p1.y,p2.x,p2.y,paint_Line);
           }    

            mapView.getProjection().toPixels(geopoints.get(i),p1);
            if(i==0){
                canvas.drawBitmap(start, p1.x-2, p1.y-start.getHeight()+2, null);
            }
            if (i+1==geopoints.size()-1) {
                canvas.drawBitmap(finish, p1.x-2, p1.y-finish.getHeight()+2, null);
            }   
        }






    }

}
Pratap S
A: 

Hi, i am facing the same above mentioned problem, whenever we zoom on the map, the lat-long is again drawn by calling onDraw() method , which has the geopoints with lat-lon values, and thus it becomes very slower process to display the map .. am facing from quite a long time , kindly help me on this ...

thank u , regards Sheik

sheik
+1  A: 

I've had to do something similar. My attempt currently does the following in onDraw (simplified for readability - error-handling etc. stripped out):

if ((bmap == null) || (lastZoom != mapv.getLatitudeSpan()))
{
    // bitmap is null - so we haven't previously drawn the path, OR
    //  the map has been zoomed in/out, so we're gonna re-draw it anyway
    //    (alternatively, I could have tried scaling the bitmap... might
    //     be worth investigating if that is more efficient)

    Projection proj = mapv.getProjection();

    // store zoom level for comparing in the next onDraw
    lastZoom = mapv.getLatitudeSpan();

    // draw a path of all of the points in my route
    GeoPoint start = routePoints.get(0);
    Point startPt = new Point();            
    proj.toPixels(start, startPt);

    Path path = new Path();
    path.moveTo(startPt.x, startPt.y);

    Point nxtPt;

    for (GeoPoint nextPoint : routePoints) 
    {
        nxtPt = new Point();
        proj.toPixels(nextPoint, nxtPt);
        path.lineTo(nxtPt.x, nxtPt.y);
    }

    // create a new bitmap, the size of the map view
    bmap = Bitmap.createBitmap(mapv.getWidth(), mapv.getHeight(), Bitmap.Config.ARGB_8888);

    // create an off-screen canvas to prepare new bitmap, and draw path on to it
    Canvas offscreencanvas = new Canvas(bmap);
    offscreencanvas.drawPath(path, mPaint);

    // draw the bitmap of the path onto my map view's canvas
    canvas.drawBitmap(bmap, 0, 0, null);

    // make a note of where we put the bitmap, so we know how much we 
    //  we need to move it by if the user pans the map
    mapStartPosition = proj.fromPixels(0, 0);
}
else
{
    // as we're in onDraw, we think the user has panned/moved the map
    //  if we're in here, the zoom level hasn't changed, and
    //   we've already got a bitmap with a drawing of the route path

    Projection proj = mapv.getProjection();

    // where has the mapview been panned to?
    Point offsetPt = new Point();
    proj.toPixels(mapStartPosition, offsetPt);

    // draw the bitmap in the new correct location
    canvas.drawBitmap(bmap, offsetPt.x, offsetPt.y, null);
}

It's not perfect yet.... for example, the path ends up in the wrong place immediately after zooming - being moved to the correct place once the user starts panning.

But it's a start - and hugely more efficient than redrawing the path on every onDraw call

Hope this helps!

dalelane
Has anyone ever figured out the zooming thing? I've been wrestling this monster on-and-off for 10months.
fiXedd
A: 

Comment to dalelane's answer from May,7th: I used your solution for reducing the load of drawing, but modified it a bit:

  • a new bitmap is created, if the map center, the zoom levelhave cjanged or no old bitmap exists.

After zooming the route is placed on the correct position. It seems that zooming has not finished completely, when a changed zoom level is detected.

I used a timer, which modifies the map center by 10 after a delay of 600 msecs after the zoom level changed. By changing the map center the draw method is called and creates a new bitmap. The route then is placed correctly. This is an ugly work around. Has anyone a better solution?

private void panAfterZoom(MapView mv, long delay){
    timer = new java.util.Timer("drawtimer", true);
    mapView=mv;
    task = new java.util.TimerTask() {
       public void run() {
           GeoPoint center=mapView.getMapCenter();
           GeoPoint point=new GeoPoint(center.getLatitudeE6()+10, center.getLongitudeE6());
           MapController contr=mapView.getController();
           contr.setCenter(point);
           timer.cancel();
       }
       };
    timer.schedule(task, delay);
}

This is called in the draw method as: pabAfterZoom(mapView, 600);

Bost

Bost
A: 

I think I have a problem like yours: I have a view where I draw a picture and some text with the drawTextOnPath() method Before I implemented the drawTextOnPath stuff the application worked fast, but after that it crashed.

Do you know a solution for my problem? Is there a possibility to optimize the code of drawTextOnPath? I used the method 15 times and my prog crashes, but I have to use it much more often

Thanks in advance for your help

AndroidStarter