In my app Draw paint in free hand on Map view but searching lot of information finally got from rectangle shape draw on mapview but i want in place of rectangle draw free hand like zigzag how to change my code Any help please..
MapOverlay.java
public class MapOverlay extends Overlay {
private float x1,y1,x2,y2;
private GeoPoint p1=null,p2=null;
private MapExampleActivity mv = null;
private Paint paint = new Paint();
private Path path = new Path();
private boolean isUp = false;
//constructor receiving the initial point
public MapOverlay(MapExampleActivity mapV,float x,float y){
paint.setStrokeWidth(2.0f);
x1 = x;
y1 = y;
mv = mapV;
p1 = mapV.getMapView().getProjection().fromPixels((int)x1,(int)y1);
}
//override draw method to add our custom drawings
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
if(p1 != null && p2 != null){
//get the 2 geopoints defining the area and transform them to pixels
//this way if we move or zoom the map rectangle will follow accordingly
Point screenPts1 = new Point();
mapView.getProjection().toPixels(p1, screenPts1);
Point screenPts2 = new Point();
mapView.getProjection().toPixels(p2, screenPts2);
//draw inner rectangle
paint.setColor(Color.BLUE);
// paint.setStyle(Style.FILL);
canvas.drawPath(path, paint);
canvas.drawRect(screenPts1.x, screenPts1.y, screenPts2.x, screenPts2.y, paint);
//draw outline rectangle
// paint.setColor(Color.YELLOW);
paint.setStyle(Style.STROKE);
// canvas.drawRect(screenPts1.x, screenPts1.y, screenPts2.x, screenPts2.y, paint);
canvas.drawPath(path, paint);
}
return true;
}
#Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
if(mv.isEditMode() && !isUp){
if(e.getAction() == MotionEvent.ACTION_DOWN){
x1 = y1 = 0;
x1 = e.getX();
y1 = e.getY();
p1 = mapView.getProjection().fromPixels((int)x1,(int)y1);
}
//here we constantly change geopoint p2 as we move out finger
if(e.getAction() == MotionEvent.ACTION_MOVE){
x2 = e.getX();
y2 = e.getY();
p2 = mapView.getProjection().fromPixels((int)x2,(int)y2);
}
//---when user lifts his finger---
if (e.getAction() == MotionEvent.ACTION_UP) {
isUp = true;
}
return true;
}
return false;
}
}
using this i able to draw like this rectangle shapes and draw up to again you click the toggle button(possible to draw multiple times)
i want draw lines instead of rectangle like below image(draw multiple times).
finally i found this link this link provide rectangle shape draw http://n3vrax.wordpress.com/2011/08/13/drawing-overlays-on-android-map-view/
just change rectangle to free draw any idea please....
You can free hand draw a line using the code bellow:
Code
public class HandDrawOverlay extends Overlay {
private boolean editMode = false;
private boolean isTouched = false;
private Paint paint = new Paint();
private Point screenPt1 = new Point();
private Point screenPt2 = new Point();
private ArrayList<GeoPoint> points = null;
public HandDrawOverlay(){
paint.setStrokeWidth(2.0f);
paint.setStyle(Style.STROKE);
paint.setColor(Color.BLUE);
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if(points != null && points.size() > 1){
mapView.getProjection().toPixels(points.get(0), screenPt1);
for(int i=1; i<points.size();i++){
mapView.getProjection().toPixels(points.get(i), screenPt2);
canvas.drawLine(screenPt1.x, screenPt1.y, screenPt2.x, screenPt2.y, paint);
screenPt1.set(screenPt2.x, screenPt2.y);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
if(editMode){
int x = (int)e.getX();
int y = (int)e.getY();
GeoPoint geoP = mapView.getProjection().fromPixels(x,y);
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
isTouched = true;
points = new ArrayList<GeoPoint>();
points.add(geoP);
break;
case MotionEvent.ACTION_MOVE:
if(isTouched)
points.add(geoP);
break;
case MotionEvent.ACTION_UP:
if(isTouched)
points.add(geoP);
isTouched = false;
break;
}
mapView.invalidate();
return true;
}
return false;
}
/**
* #return the editMode
*/
public boolean isEditMode() {
return editMode;
}
/**
* #param editMode the editMode to set
*/
public void setEditMode(boolean editMode) {
this.editMode = editMode;
}
}
to use
HandDrawOverlay handDrawOverlay;
handDrawOverlay = new HandDrawOverlay();
mapView.getOverlays().add(handDrawOverlay);
//Set edit mode to true to start drwaing
handDrawOverlay.setEditMode(true);
//Set edit mode to true to stop drwaing
handDrawOverlay.setEditMode(false);
Note
This is a full functioning example to help you starting. However, you should optimize the code to make it more efficient (i.e. using Path to store the drawing path in onDraw(), reducing the number of points recorded in onTouch(), etc.).
Enjoy it.
Related
I am creating an app to draw free shapes on the surface screen but i could only draw separated points my problem is . i want the points to be connected to each other when i draw them not lifting my finger from the screen . i mean as long as i am touching the screen draw.here's my code so far.
public class SurfaceViewActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new DrawingView(this));
}
class DrawingView extends SurfaceView {
private final SurfaceHolder surfaceHolder;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private List<Point> pointsList = new ArrayList<Point>();
public DrawingView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (surfaceHolder.getSurface().isValid()) {
// Add current touch position to the list of points
pointsList.add(new Point((int)event.getX(), (int)event.getY()));
// Get canvas from surface
Canvas canvas = surfaceHolder.lockCanvas();
// Clear screen
canvas.drawColor(Color.BLACK);
// Iterate on the list
for(int i=0; i<pointsList.size(); i++) {
Point current = pointsList.get(i);
// Draw points
canvas.drawPoint(current.x, current.y, paint);
}
// Release canvas
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
return false;
}
}
}
you can use this function to draw smooth lines
public void drawBrzierLine(Canvas mCanvas, float xi, float yi, float xd, float yd) {
Point start = new Point((int) xi, (int) yi);
Point end = new Point((int) xd, (int) yd);
Path mPath = new Path();
mPath.reset();
mPath.moveTo(start.x, start.y);
mPath.quadTo(start.x, start.y, end.x, end.y);
mCanvas.drawPath(mPath, mPaint);
}
In onTouchEvent(MotionEvent event) you only handle ACTION_DOWN. So this code will only run when you press down on the screen. Use ACTION_MOVE instead.
http://developer.android.com/reference/android/view/MotionEvent.html
Hi I am beginner in android development. I am developing a paint like application. I have already drawn some points on the canvas. Now I want to draw line between these points through fingure.I dont konw how i can do this. I am not using google maps.
package com.example.point;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
List<Point> points = new ArrayList<Point>();
List<Point> points1 = new ArrayList<Point>();
List<Point> points2 = new ArrayList<Point>();
Paint paint = new Paint();
PointF firstpoint=new PointF(100,100);
PointF secondpoint=new PointF(200,200);
Path path=new Path();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
paint.setStrokeWidth(3);
canvas.drawPoint(100, 100, paint);
canvas.drawPoint(200, 200, paint);
canvas.drawPoint(200, 400, paint);
Point p=new Point();
Point p1=new Point();
//p1=points.get(1);
for(int i=points.size()-2;i<points.size();i++)
{
p=points.get(i);
//if(p1.x==100 && p1.y==100)
//canvas.drawLine(100, 100, p.x, p.y, paint);
// path.moveTo(100, 100);
//path.lineTo(200, 200);
//canvas.drawPath(path, paint);
}
}
public boolean onTouch(View view, MotionEvent event) {
/*if(event.getAction()==MotionEvent.ACTION_MOVE)
{
Point point1 = new Point();
point1.x = event.getX();
point1.y = event.getY();
points.add(point1);
invalidate();
Log.d(TAG, "point: " + point1);
}*/
//if(event.getX()==100 && event.getY()==100)
//{
if(event.getAction()==MotionEvent.ACTION_MOVE)
{
Point point1 = new Point();
point1.x = event.getX();
point1.y = event.getY();
points.add(point1);
invalidate();
Log.d(TAG, "point: " + point1);
//}
}
//return false;
return true;
/*switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d(TAG, "point: " + point);
return true;
case MotionEvent.ACTION_MOVE:
Point point1 = new Point();
point1.x = event.getX();
point1.y = event.getY();
points1.add(point1);
invalidate();
Log.d(TAG, "point: " + point1);
return true;
case MotionEvent.ACTION_UP:
Point point2 = new Point();
point2.x = event.getX();
point2.y = event.getY();
points2.add(point2);
invalidate();
Log.d(TAG, "point: " + point2);
return true;
}
return false;
// return true;*/
}
}
class Point {
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
I want to just draw a straight line between these points with fingure. If my fingure move far from that particular point after that i move back my fingure than the line drawn will be erased. i.e. the line only drawn between these particular points.
Just a heads up here in SO, It is usually best if you'd come and ask here only after you've tried something and didn't succeed. this way you want get comments such as "What have you tried..?" and stuff like that.
Regarding your question. http://developer.android.com/reference/android/graphics/Canvas.html is a good place to start. the Android documentation is very helpful.
As you can see you have a drawLine() method. which should do what you asked.
Good luck!
public class HelloGoogleMaps extends MapActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapController mMapController;
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mMapController = mapView.getController();
mMapController.setZoom(18);
// Two points in Mexico about 1km apart
GeoPoint point1 = new GeoPoint(19240000,-99120000);
GeoPoint point2 = new GeoPoint(19241000,-99121000);
mMapController.setCenter(point2);
// Pass the geopoints to the overlay class
MapOverlay mapOvlay = new MapOverlay(point1, point2);
mapView.getOverlays().add(mapOvlay);
}
public class MapOverlay extends com.google.android.maps.Overlay {
private GeoPoint mGpt1;
private GeoPoint mGpt2;
protected MapOverlay(GeoPoint gp1, GeoPoint gp2 ) {
mGpt1 = gp1;
mGpt2 = gp2;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
super.draw(canvas, mapView, shadow);
Paint paint;
paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
Point pt1 = new Point();
Point pt2 = new Point();
Projection projection = mapView.getProjection();
projection.toPixels(mGpt1, pt1);
projection.toPixels(mGpt2, pt2);
canvas.drawLine(pt1.x, pt1.y, pt2.x, pt2.y, paint);
return true;
}
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
Its Runnnig Code In My Apps..All The Best
Is your canvas sitting inside a View? If so, here is a starting point assuming you are asking about using finger movements to draw lines between points...
Look up the following method for help:
public boolean onTouchEvent(MotionEvent event)
to detect finger movements. You will need to distinguish between the type of motion action that has just happened, and the motion action "index". Then if the motion is a moving motion (e.g. fingers moving between points), then you can call drawPath or drawLine to draw your lines.
I'm trying to develop a simple "draw-on-touch" and I want to draw the different paths that the user places in an onTouch listener.
I've got a simple problem. When I draw the paths I obtain a single path drawn in the points of the last onTouch entry.
I think the paths are all drawn over the last path because I use a Paint with a 150 alpha and it looks more solid in the second and succesive onTouch entries.
How could I solve that? Thanks!
public class PaintView extends View implements OnTouchListener {
List<List<Point>> paths = new ArrayList<List<Point>>();
List<Point> points = new ArrayList<Point>();
Paint paintLine = new Paint();
Paint paintCircle = new Paint();
public PaintView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paintLine = new Paint(Paint.ANTI_ALIAS_FLAG);
paintLine.setStyle(Paint.Style.STROKE);
paintLine.setStrokeWidth(10);
paintLine.setColor(Color.GREEN);
paintLine.setAlpha(150);
}
public void onDraw(Canvas canvas) {
Path path = new Path();
List<Point> pointsList;
List<Path> pathList = new ArrayList<Path>();
Point point = new Point();
for (int i = 0; i < paths.size(); i++) {
pointsList = paths.get(i);
path.reset();
boolean first = true;
for (int j = 0; j < points.size(); j+=2 ) {
point = pointsList.get(j);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (j < pointsList.size() - 1 ) {
Point nextPoint = pointsList.get(j+1);
path.quadTo(point.x, point.y, nextPoint.x, nextPoint.y);
} else {
path.lineTo(point.x, point.y);
}
}
pathList.add(path);
}
for (Path pathDraw : pathList) {
canvas.drawPath(pathDraw, paintLine);
}
}
public boolean onTouch(View view, final MotionEvent event) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// DO SOMETHING
points.clear();
points.add(point);
break;
case MotionEvent.ACTION_MOVE:
points.add(point);
break;
case MotionEvent.ACTION_UP:
points.add(point);
paths.add(points);
break;
default:
return false;
}
invalidate();
return true;
}
}
The problem is that you are drawing paths constructed with the points in the points list repeatedly.
Note that invalidate() call in onTouch, each of this call will trigger a redraw event, which causes onDraw to be called, everything looks fine at this point. The problem is you only did points.clear() on ACTION_DOWN event, but you also should have cleared them on ACTION_MOVE and ACTION_UP events. Instead, you keep all the points collected previously and draw the paths constructed with all those points in onDraw. So you are effectively drawing repeatedly some of the paths constructed with the points collected previously.
Note in a drag motion, there will be 1 ACTION_DOWN, N ACTION_MOVE, 0 or 1 ACTION_UP events.
I am creating a custom control as below in the image. It is a semicircle with places 1, 2 etc.
When user click on one place (1, 2 etc), it changes color (for example user click on place 3, image 2).
I try to use canvas and methods draws. But I don't think that is correct. Can you help me with a better solution and how to set up an event for user clicking on the place?
You can do it with the canvas, bellow is a small example of a View with 2 oval shapes that change color(to red) on a touch event:
class ExtraView extends View {
private boolean flag1, flag2;
private Paint p1, p2;
private RectF oval1, oval2;
public ExtraView(Context context) {
super(context);
flag1 = false;
flag2 = false;
// bigger oval paint
oval1 = new RectF(50, 50, 460, 360);
p1 = new Paint();
p1.setStrokeWidth(2.0f);
// smaller oval paint
oval2 = new RectF(140, 140, 360, 260);
p2 = new Paint();
p2.setStrokeWidth(2.0f);
}
#Override
public void draw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
// bigger oval
if (flag1) {
p1.setColor(Color.RED);
} else {
p1.setColor(Color.WHITE);
}
p1.setStyle(Paint.Style.FILL);
canvas.drawOval(oval1, p1);
p1.setColor(Color.BLACK);
p1.setStyle(Paint.Style.STROKE);
canvas.drawOval(oval1, p1);
// smaller oval
if (flag2) {
p2.setColor(Color.RED);
} else {
p2.setColor(Color.WHITE);
}
p2.setStyle(Paint.Style.FILL);
canvas.drawOval(oval2, p2);
p2.setColor(Color.BLACK);
p2.setStyle(Paint.Style.STROKE);
canvas.drawOval(oval2, p2);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (oval2.contains(event.getX(), event.getY())) {
flag2 = !flag2;
invalidate();
} else if (oval1.contains(event.getX(), event.getY())) {
flag1 = !flag1;
invalidate();
}
}
return true;
}
}
I have a problem with mapview and Overlay.
I must to draw a circle on the map everytime that change GPS position.
I used the method draw in my overlay class that extend overlay.
The problem is that I must draw these circles with transparency, but when the circles overlap each other in the intersection point the color it's different because there is a sum of alpha.
How I can fix it?
This is my overlay class:
public class ImpactOverlay extends Overlay {
private static int CIRCLERADIUS = 0;
private GeoPoint geopoint;
private int myCircleRadius;
Point point = new Point();
Paint circle = new Paint(Paint.ANTI_ALIAS_FLAG);
private long systemTime= -1 ;
public ImpactOverlay(GeoPoint point, int myRadius) {
geopoint = point;
CIRCLERADIUS = myRadius; // assegna raggio del cerchio
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
// Transfrom geoposition to Point on canvas
Projection projection = mapView.getProjection();
projection.toPixels(geopoint, point);
// the circle to mark the spot
circle.setColor(Color.parseColor("#88ff0000"));
circle.setAlpha(122); // trasparenza
myCircleRadius = metersToRadius(CIRCLERADIUS, mapView,
(double) geopoint.getLatitudeE6() / 1000000);
canvas.drawCircle(point.x, point.y, myCircleRadius, circle);
}
public static int metersToRadius(float meters, MapView map, double latitude) {
return (int) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math
.cos(Math.toRadians(latitude))));
}
#Override
/* Implementa il doppio tap per eseguire zoom sulla mappa */
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if ((System.currentTimeMillis() - systemTime) < 250) {
mapView.getController().zoomIn();
}
systemTime = System.currentTimeMillis();
break;
}
return false;
}
}
CircleOptions circle = new CircleOptions();
circle.center(new LatLng(latitude, longitude))
.radius(1500)//in meters
.strokeColor(Color.BLUE)//border color
.strokeWidth(3.0f)//border width
.fillColor(0x200000ff);//inside circle
googleMap.addCircle(circle);//GoogleMap googleMap(initialize accordingly)
Well one possibility is to clip the area away which is intersecting the second circle like that, pseudo code:
canvas.clipPath(circle2.toPath())
canvas.draw(circle1)
canvas.removeClip()
canvas.draw(circle2)
You need to take account of the intersection when you clip, something like this:
.
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
Paint paint = new Paint();
paint.setColor(Color.parseColor("#88ff0000"));
paint.setAlpha(16); // quite transparent
Point point = new Point();
Point point2 = new Point();
float radius = 50.0f;
Projection projection = mapView.getProjection();
projection.toPixels(mGpt, point); // 1st GeoPoint
projection.toPixels(mGpt2, point2); // 2nd GeoPoint
Path path1 = new Path();
Path path2 = new Path();
path1.addCircle(point.x, point.y, radius, Direction.CW); // 1st circle
path2.addCircle(point2.x, point2.y, radius, Direction.CW); // 2nd circle
canvas.save(); // save canvas without the clip region
canvas.clipPath(path2, Region.Op.DIFFERENCE); // clip the region
// to the whole view less where circle2 will be when it's drawn
canvas.drawPath(path1, paint); // draw 1st circle minus where it overlaps
canvas.restore(); // clear the clip region
canvas.drawPath(path2, paint); // draw 2nd circle (unclipped)
return false;
}
should work
You don't need to know how many shapes are there beforehand. If you use separate overlays you could just easily draw each and add the corresponding area to the clipping area.
Full code follows:
import java.util.List;
import android.graphics.*;
import android.graphics.Path.Direction;
import android.graphics.Region.Op;
import android.os.Bundle;
import android.view.MotionEvent;
import com.google.android.maps.*;
public class CircleTest extends MapActivity {
private MapView m_map;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_map = (MapView) findViewById(R.id.mapview);
m_map.displayZoomControls(true);
m_map.setBuiltInZoomControls(true);
}
#Override
protected void onStart() {
super.onStart();
// m_map.getOverlays().add(new ); // some other overlays
m_map.getOverlays().add(new ImpactGeneratorOverlay());
// the impact areas are being inserted between these two, see ImpactGeneratorOverlay
m_map.getOverlays().add(new ImpactClipRestoreOverlay());
}
/**
* Restore clipping area to the saved one.
*/
public static class ImpactClipRestoreOverlay extends Overlay {
#Override
public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
super.draw(canvas, mapView, shadow);
canvas.restore();
}
}
/**
* Handles events, on touch down it adds a new Impact area to the map,
* just before the ClipRestore overlay (assume it's the last, if not store position, and insert before).
*/
public static class ImpactGeneratorOverlay extends Overlay {
#Override
public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
super.draw(canvas, mapView, shadow);
canvas.save();
}
#Override
public boolean onTouchEvent(final MotionEvent e, final MapView mapView) {
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
GeoPoint point = mapView.getProjection().fromPixels((int) e.getX(), (int) e.getY());
List<Overlay> overlays = mapView.getOverlays();
overlays.add(overlays.size() - 1, new ImpactOverlay(point, 1000));
break;
}
return super.onTouchEvent(e, mapView);
}
}
/**
* Draw impact and remove the current shape path from the drawable area.
*/
public static class ImpactOverlay extends Overlay {
// shape parameters
private final GeoPoint circleCenter;
private final int circleRadius;
// drawing cache
private final Point circleDrawCenter = new Point();
private final Paint circlePaint = new Paint();
public ImpactOverlay(final GeoPoint circleCenter, final int circleRadius) {
this.circleCenter = circleCenter;
this.circleRadius = circleRadius;
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.argb(64, 255, 0, 0));
}
#Override
public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) {
// Transfrom geoposition to Point on canvas
Projection projection = mapView.getProjection();
projection.toPixels(circleCenter, circleDrawCenter);
// the circle to mark the spot
float circleDrawRadius = ImpactOverlay.metersToRadius(mapView, circleRadius, circleCenter.getLatitudeE6() / 1e6f);
// create circle from path
Path path = new Path();
path.addCircle(circleDrawCenter.x, circleDrawCenter.y, circleDrawRadius, Direction.CW);
// draw circle
canvas.drawPath(path, circlePaint);
// remove circle from further posibble drawing areas
canvas.clipPath(path, Op.DIFFERENCE);
}
public static float metersToRadius(final MapView map, final float meters, final float latitude) {
return (float) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math.cos(Math.toRadians(latitude))));
}
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
This contains a fix for clipping unwanted layers, say the first one, but this can be avoided if you just gather all the circles in one overlay and draw them in one draw method.
The key is to draw and set clipping (even if they exist in different overlays, not advised!):
canvas.save();
canvas.drawPath(path1, paint);
canvas.clipPath(path1, Op.DIFFERENCE);
canvas.drawPath(path2, paint); // do not draw over path1
canvas.clipPath(path2, Op.DIFFERENCE);
canvas.drawPath(path3, paint); // do not draw over path1 + path2
canvas.clipPath(path3, Op.DIFFERENCE);
// do not draw over path1 + path2 + path3
canvas.restore();
canvas.drawPath(path4, paint); // draw over anything