2011-07-12 10 views
4

これはルートを描くために使用しているコードです。私は1000点のポイントを持っていると、ルートがひどく遅くなります。誰かがコードスニペットやリンクの描画をより効率的に行う方法を説明するリンクを提供する可能性がありますか?私はこれを解決する一つの方法は、ビットマップへのパスをキャッシュすることですが、どのようにそれを行うか分かりません。経路をより効率的に描くには?

public class PathOverlay extends Overlay{ 

private GeoPoint startPoint; 
private GeoPoint finishPoint; 
private ArrayList<GeoPoint> pathPoints; 
private Paint paint; 
private Path path; 
private Point pathStartPoint; 
private Point pathEndPoint; 

private float dx; 
private float dy; 


public PathOverlay(GeoPoint startPoint, GeoPoint finishPoint, ArrayList<GeoPoint> pathPoints, int color){ 
    this.startPoint = startPoint; 
    this.finishPoint = finishPoint; 
    this.pathPoints = pathPoints; 
    this.paint = new Paint(); 
    this.paint.setAntiAlias(true); 
    this.paint.setDither(true); 
    this.paint.setColor(color); 
    this.paint.setAlpha(150); 
    this.paint.setStrokeWidth(4); 
    this.paint.setStyle(Paint.Style.STROKE); 
} 

@Override 
public void draw(Canvas overlayCanvas, MapView mapView, boolean shadow) { 
    if(path == null) { 
     path = getPath(mapView); 
    } else { 
     path = transformPath(mapView); 
    } 
    overlayCanvas.drawPath(path, paint); 
    super.draw(overlayCanvas, mapView, shadow); 
} 

private Path getPath(MapView mapView) { 
    Projection projection = mapView.getProjection(); 
    if(path == null) { 
     path = new Path(); 
     path.setFillType(FillType.WINDING); 
    } else { 
     path.rewind(); 
    } 
    Point point = new Point(); 
    pathStartPoint = new Point(); 
    pathEndPoint = new Point(); 

    projection.toPixels(startPoint, point); 
    projection.toPixels(startPoint, pathStartPoint); 
    path.moveTo(point.x, point.y); 
    path.addCircle(point.x, point.y, (float) 2.0, Direction.CCW); 
    if (pathPoints != null) { 
     for(int i=0;i<pathPoints.size();i++) { 
      projection.toPixels(pathPoints.get(i), point); 
      path.lineTo(point.x, point.y); 
     } 
    } 
    projection.toPixels(finishPoint, point); 
    projection.toPixels(finishPoint, pathEndPoint); 
    path.lineTo(point.x-5, point.y); 
    path.addCircle(point.x-5, point.y, (float) 2.0, Direction.CCW); 


    return path; 
} 

private Path transformPath(MapView mapView) { 
    Projection projection = mapView.getProjection(); 

    Point sPoint = new Point(); 
    Point ePoint = new Point(); 
    projection.toPixels(startPoint, sPoint); 
    projection.toPixels(finishPoint, ePoint); 

    float sx = ((float)ePoint.x - (float)sPoint.x)/((float)pathEndPoint.x - (float)pathStartPoint.x); 
    float sy = ((float)ePoint.y - (float)sPoint.y)/((float)pathEndPoint.y - (float)pathStartPoint.y); 

    if(sx != 1.0 && sy != 1.0) { 
     Log.i("PathOverlay", "resized"); 
     return getPath(mapView); 
    } else { 
     Log.i("PathOverlay", "moved"); 
     Matrix matrix = new Matrix(); 

     dx = (float)sPoint.x - (float)pathStartPoint.x; 
     dy = (float)sPoint.y - (float)pathStartPoint.y; 

     matrix.postTranslate(dx, dy); 
     pathStartPoint = sPoint; 
     pathEndPoint = ePoint; 
     path.transform(matrix); 

     return path; 
    } 
} 

} 
+0

[Androidは大量の経度/緯度ポイントから地図ビュー上のパスを描画します](http://stackoverflow.com/questions/3387894/android-draw-a-path-on- a-mapview-from-a-long-of-longitude-latitude-points) – Pratik

答えて

0

描画速度を向上させる最も良い方法は、パスに含まれるポイント数を減らすことです。おそらく彼らは必要ありません - それらの多くは、ちょうど前後の間に産むので、あなたがすることによって、それらをフィルタリングすることができます:Locationものの、前のポイントから

最小距離(簡単な方法)

最小限のベアリング変化(少し難しくクラスは、それが役立つはず方法bearingTo()

2

あなたは透明Bitmapオブジェクトへのパスを描くことができます。。 -

(あなたがフィットを参照どんなサイズのパスはまだ高いメモリ消費量の詳細、より良い、それが大きいほど)

それを作成してください透明のためにはh Bitmap.config.ARGB_8888

あなたはこれをしたら、あなたはOverlay上のパスを表示するには、2つの長方形を使用しています:

はあなたのtransformPath方法で重要な計算のほとんどをやった、あまりにも難しいことではありません。

を追加しました:

あなたが実際にビットマップに描かれたパスを保持し、実際のパスポイントを再描画の両方の組み合わせを行うことができます。ユーザーがマップを移動したり、ズームイン/ズームアウトしたり、ユーザーが画面を離れるときにパスを再描画したりする場合は、上記の手法を使用します。

+0

私はあなたのアプローチを使いたいですが、私はいくつかの問題を見ています。固定サイズのビットマップを作成してより大きなパスを描画すると、すべてのパス部分がビットマップに描画されるわけではないので、マップが移動された場合、一部のパス部分は表示されません。ビットマップを作成すると、パスのサイズが問題に陥り、ビットマップオブジェクトを作成するために多くのメモリが必要になるため、アプリケーションが強制終了されます。任意のアイデアをどのように解決するには? – Tadas

+0

パスのサイズを縮小することができます。あなたのdstの長方形でそれをスケールアップしてください。これはうまくいくが、あなたのビットマップのサイズに応じてより高いズームレベルで詳細が不足することがあります。このソリューションは、パスが頻繁に変更されていない場合はうまく動作します。そうしないと、パスポイントを削除しない方がよい場合があります。 –

0
  1. draw()メソッドは描画サイクルを約50回描画します。なぜかわからないけど、あなたはそれをテストすることができます。これにより、パフォーマンスが低下します。そして、もしあなたが1000個のオブジェクトを描画しなければならない場合、draw()はそれぞれ30-50個を描画します...それは非常に不器用なものになります。 これを避けるには、キャッシュオーバーレイを作成する必要があります。他のドローを拒否する。

  2. 処理を高速化するには、優先度の低いバックグラウンドスレッドを描画します。

    複数のポイント間に線を描画する最も速い方法は、Canvas.drawLines(float [] pts、int offset、int count、Paint paint)メソッドを使用することです。 私はすべての方法をテストしました。これはアンドロイドが提供する最も速い方法です。

+0

1.キャッシュオーバーレイを作成することにより、必要以上にドローが実行されないように指定できますか? 2.私はバックグラウンドスレッドでどのように描画できますか? SurfaceViewを使用して別のスレッドで描画することができますか、別の方法がありますか? – Tadas

+0

1.ビットマップに描画します。マップに変更があるか確認します(マップセンターの変更、ズームレベルの変更など)。変更がある場合は、ビットマップを再描画します。そうでない場合は、ビットマップを画面に描画します。 2. SurfaceViewで描画しようとしましたが、何も起こりませんでした。スレッドクラスを作成し、UIスレッドとバックグラウンドスレッドの通信モジュールを作成することができます。 HandlerThreadクラスも参照してください。 –

関連する問題