package org.mapsforge.android.maps;
import java.util.ArrayList;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
/**
* CirclesOverlay is a special Overlay to display a series of circles on top of
* the map. The radius of a circle is specified in meters and will be
* automatically converted to pixels at each redraw.
*
* All rendering parameters like color, stroke width, pattern and transparency
* can be configured via the two {@link android.graphics.Paint Paint} objects in
* the {@link #CircleOverlay(Paint,Paint)} constructor.
*/
public class CirclesOverlay extends Overlay {
private static final String THREAD_NAME = "CirclesOverlay";
private byte cachedZoomLevel;
private Paint fillPaint;
private Paint outlinePaint;
private final Path path;
private ArrayList center;
private ArrayList radius;
private ArrayList cachedCenterPosition;
/**
* Constructs a new CircleOverlay.
*
* @param fillPaint
* the paint object which will be used to fill the overlay.
* @param outlinePaint
* the paint object which will be used to draw the outline of the
* overlay.
*/
public CirclesOverlay(Paint fillPaint, Paint outlinePaint) {
this.path = new Path();
this.center = new ArrayList();
this.radius = new ArrayList();
this.cachedCenterPosition = new ArrayList();
setPaint(fillPaint, outlinePaint);
}
public synchronized void reset() {
this.center = new ArrayList();
this.radius = new ArrayList();
this.cachedCenterPosition = new ArrayList();
path.reset();
super.requestRedraw();
}
/**
* Sets the parameters of the circle.
*
* @param center
* the geographical coordinates of the centre point.
* @param radius
* the radius of the circle in meters.
*/
public synchronized void addCircleData(GeoPoint center, float radius) {
this.center.add(center);
this.radius.add(radius);
this.cachedCenterPosition.add(new Point());
this.cachedZoomLevel = Byte.MIN_VALUE;
super.requestRedraw();
}
/**
* Sets the paint objects which will be used to draw the overlay.
*
* @param fillPaint
* the paint object which will be used to fill the overlay.
* @param outlinePaint
* the paint object which will be used to draw the outline of the
* overlay.
*/
public synchronized void setPaint(Paint fillPaint, Paint outlinePaint) {
this.fillPaint = fillPaint;
this.outlinePaint = outlinePaint;
}
@Override
protected synchronized void drawOverlayBitmap(Canvas canvas,
Point drawPosition, Projection projection, byte drawZoomLevel) {
if (this.center.size() == 0 || this.radius.size() == 0) {
// no valid parameters to draw the circle
return;
} else if (this.fillPaint == null && this.outlinePaint == null) {
// no paint to draw
return;
}
// make sure that the cached centre position is valid
if (drawZoomLevel != this.cachedZoomLevel) {
for (int i = 0; i < center.size(); i++) {
Point cachedPoint = projection.toPoint(this.center.get(i),
this.cachedCenterPosition.get(i), drawZoomLevel);
this.cachedCenterPosition.set(i, cachedPoint);
}
this.cachedZoomLevel = drawZoomLevel;
}
// assemble the path
this.path.reset();
for (int i = 0; i < cachedCenterPosition.size(); i++) {
float radius_meters = projection.metersToPixels(this.radius.get(i),
drawZoomLevel);
this.path.addCircle(this.cachedCenterPosition.get(i).x
- drawPosition.x, this.cachedCenterPosition.get(i).y
- drawPosition.y, radius_meters, Path.Direction.CCW);
}
// draw the path on the canvas
if (this.fillPaint != null) {
canvas.drawPath(this.path, this.fillPaint);
}
if (this.outlinePaint != null) {
canvas.drawPath(this.path, this.outlinePaint);
}
}
@Override
protected String getThreadName() {
return THREAD_NAME;
}
}