Replacement for ItemizedOverlay in Google maps V2 for Android?

In V1 Google Maps for Android, I implemented a clustering form using the ItemizedOverlay class. Each cluster has a central point (lat / lon), radius (in miles) and the number of elements in the cluster. I used ItemizedOverlay.draw (Canvas, MapView, shadow) to draw clusters using Canvas object methods such as drawCircle () and drawText (). Each cluster consisted of a filled circle (size in accordance with the space necessary for counting), containing a counter and a circle showing the radius.

After reading V2 documents and playing with the demo application, I don't see the equivalent of ItemizedOverlay and there is no obvious alternative. I suspect that the only way to do this is to save the list of clusters myself, and then subclass MapView and ensure that its onDraw () method is implemented.

Am I missing something in API V2, which is better than subclassing MapView?

Thanks,

Mark

+6
source share
1 answer

After some research, I did not find a better option than to create a Bitmap for the marker on the fly. But I also create a circle with a polygon on the map. Keep in mind that this is not a very high-performance solution, but for my case it is a worthy option. Code example:

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())); } } 

My MathUtils methods:

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

If you have a radius in miles, you must change the EARTH_RADIUS constant to miles, 3963 AFAIK.

+4
source

All Articles