6

Android 用 Google マップの V1 では、ItemizedOverlay クラスを使用してクラスタリングの形式を実装しました。各クラスターには、中心点 (緯度/経度)、半径 (マイル単位)、およびクラスター内のアイテム数のカウントがあります。私は ItemizedOverlay.draw(Canvas, MapView, shadow) を使用して、drawCircle() や drawText() などの Canvas オブジェクト メソッドを使用してクラスターを描画しました。各クラスターは、カウントを含む塗りつぶされた円 (カウントに必要なスペースに応じたサイズ) と半径を示す円で構成されていました。

V2 のドキュメントを読み、デモ アプリで遊んだ後、ItemizedOverlay に相当するものはなく、明白な代替手段もありません。これを行う唯一の方法は、クラスターのリストを自分で管理し、MapView をサブクラス化し、その onDraw() メソッドの実装を提供することだと思います。

MapView をサブクラス化するよりも優れている V2 API の何かを見逃していませんか?

ありがとう、

マーク

4

1 に答える 1

4

いくつかの調査の後、その場でマーカーのビットマップを作成するよりも良いオプションは見つかりませんでした。しかし、地図上に多角形で円も作成しています。これは実際には高性能なソリューションではないことに注意してください。ただし、私の場合は適切なオプションです。コードサンプル:

private static final int CIRCLE_POLYGON_VERTICES = 16;
private static final double EARTH_RADIUS = 6378.1d;


private List<LatLng> createCirclePolygon(LatLng center, double r) {
    List<LatLng> res = new ArrayList<LatLng>(CIRCLE_POLYGON_VERTICES);

    double r_latitude = MathUtils.rad2deg(r/EARTH_RADIUS);
    double r_longitude = r_latitude / Math.cos(MathUtils.deg2rad(center.latitude));

    for (int point = 0; point < CIRCLE_POLYGON_VERTICES + 1; point++) {
         double theta = Math.PI * ((double)point / (CIRCLE_POLYGON_VERTICES / 2));
         double circle_x = center.longitude + (r_longitude * Math.cos(theta));  
         double circle_y = center.latitude + (r_latitude * Math.sin(theta));     

         res.add(new LatLng(circle_y, circle_x));
     }
     return res;
}   

private Bitmap getClusteredLabel(String cnt, Context ctx) {
    Resources r = ctx.getResources();
    Bitmap res = BitmapFactory.decodeResource(r, R.drawable.map_cluster_bg);        
    res = res.copy(Bitmap.Config.ARGB_8888, true);
    Canvas c = new Canvas(res);

    Paint textPaint = new Paint();
    textPaint.setAntiAlias(true);
    textPaint.setTextAlign(Paint.Align.CENTER);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);
    textPaint.setColor(Color.WHITE);
    textPaint.setTextSize(21);      

    c.drawText(String.valueOf(cnt), res.getWidth()/2, res.getHeight()/2 + textPaint.getTextSize() / 3, textPaint);

    return res;
}   

public void createClusteredOverlay(MapPinData point, GoogleMap map, Context ctx) {
    if (point.getCount() > 1) {
        map.addMarker(new MarkerOptions().position(point.getLatLng()).anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromBitmap(getClusteredLabel(String.valueOf(point.getCount()), ctx))));

        map.addPolygon(new PolygonOptions()         
        .addAll(createCirclePolygon(point.getLatLng(), point.getRadius()))
        .fillColor(Color.argb(50, 0, 0, 10))     
        .strokeWidth(0)
        );
    } else {
        map.addMarker(new MarkerOptions().position(point.getLatLng()).title(point.getTitle()));
    }
}

私の MathUtils メソッド:

public static double deg2rad(double deg) {
    return (deg * Math.PI / 180.0);
}

public static double rad2deg(double rad) {
    return (rad * 180.0 / Math.PI);
}   

半径がマイルの場合、EARTH_RADIUS 定数をマイル (3963 AFAIK) に変更する必要があります。

于 2012-12-25T11:17:24.580 に答える