17

I want to draw a circle on map view. I want the user to input the radius and for that radius I have to show circle on map. After that I have to display markers on some locations on that circle.

I know how to display markers on on map view.

How can I draw circle on map view and to show markers on that circle boundary.

halfer
  • 19,824
  • 17
  • 99
  • 186
Prabhu M
  • 3,534
  • 8
  • 48
  • 87

6 Answers6

35

Just to bring this up to date... they've made it very easy to do on Google Maps API v2.

    mMap.addCircle(new CircleOptions()
        .center(center)
        .radius(radius)
        .strokeWidth(0f)
        .fillColor(0x550000FF));

Where radius is in meters.

As for markers on the boundary, that should be relatively easy to do - just follow the 'Circles' Demo in the Google Maps sample code here: https://developers.google.com/maps/documentation/android/intro#sample_code

warbi
  • 2,725
  • 2
  • 20
  • 26
  • fine, Circle is being drawn. But I want to get the lat,lng points of that circle drawn, because I want to search for some new properties which fall in that circle area drawn. Could any one please help me out how to achieve this!!! – Mahe Jun 14 '13 at 06:02
  • This shall be the accepted answer man.. nice help. @Mahe no idea about it. – Noman Nov 24 '14 at 10:13
  • Studio showing Cannot resolve method radius(double)...:( – Ashish Shukla Dec 10 '17 at 09:53
  • The radius parameter value is a float, not a double. – ByteSlinger Mar 21 '18 at 23:56
10

In case someone was looking for an answer using Google Maps API v2, here's a snippet of what I did. It's really more of a geographical approach.

public class MapDrawer {

private GoogleMap map;
private static int EARTH_RADIUS = 6371000;

public MapDrawer(GoogleMap map) {
    this.map = map;
}

private LatLng getPoint(LatLng center, int radius, double angle) {
    // Get the coordinates of a circle point at the given angle
    double east = radius * Math.cos(angle);
    double north = radius * Math.sin(angle);

    double cLat = center.latitude;
    double cLng = center.longitude;
    double latRadius = EARTH_RADIUS * Math.cos(cLat / 180 * Math.PI);

    double newLat = cLat + (north / EARTH_RADIUS / Math.PI * 180);
    double newLng = cLng + (east / latRadius / Math.PI * 180);

    return new LatLng(newLat, newLng);
}

public Polygon drawCircle(LatLng center, int radius) {
    // Clear the map to remove the previous circle
    map.clear();
    // Generate the points
    List<LatLng> points = new ArrayList<LatLng>();
    int totalPonts = 30; // number of corners of the pseudo-circle
    for (int i = 0; i < totalPonts; i++) {
        points.add(getPoint(center, radius, i*2*Math.PI/totalPonts));
    }
    // Create and return the polygon
    return map.addPolygon(new PolygonOptions().addAll(points).strokeWidth(2).strokeColor(0x700a420b));
}

}

The good thing about this is that you don't have to redraw anything after zooming or panning the map - the circle gets resized and moved accordingly. The downside is that this doesn't work if you want a circle on either north or south pole - it'll all go bezerk, but, hopefully, that's not the case 99% of the time :)

Grisha S
  • 818
  • 1
  • 6
  • 15
  • Hi @Grisha S, i am facing a problem in which i want to make a circle around my marker which grows and shrinks when user zooms in or out, i think this code will work but how can i call this class and what are the parameters to send to the function u have made..... please help if you see this ......... thanks – Salman Khan Jan 16 '13 at 12:59
  • 1
    2 @SalmanKhan: Yes, the code should work in your situation. First, instantiate the class using the GoogleMap object that you want to draw on: MapDrawer mapDrawer = new MapDrawer(map); and then call the drawCircle method giving it: 1) a LatLng object specifying the geographical coordinates of the center of the circle you want to draw, 2) an integer representing the radius of the circle in meters – Grisha S Jan 16 '13 at 14:05
  • first of all thanks for the reply Grisha its working fine for me, but every time when i add the circle to my map all the markers are getting invisible, and when i am commenting the call to the drawCircle method its showing me all the markers again, i don't know what is the problem, can u help me please ..... – Salman Khan Jan 17 '13 at 06:22
  • @SalmanKhan, the problem is the line "map.clear()" in my code - it erases everything that was drawn on the map before. I needed it just because in my case I had to erase the previously drawn circle and replace it with a new one. Just get rid of this line, and it'll be fine :) – Grisha S Jan 17 '13 at 18:38
  • will there be any performance issues if i increase totalPonts to 100? – amithgc Feb 20 '13 at 03:06
  • 1
    @AmithGC, I doubt it, but you can check. I bet you won't see much difference in performance while this number is less than 1000, though I can't be sure of that – Grisha S Feb 20 '13 at 13:27
8

In the implementation of the ItemizedOverlay, do something like the method drawCircle from the onDraw method

protected void drawCircle(Canvas canvas, Point curScreenCoords) {
    curScreenCoords = toScreenPoint(curScreenCoords);
    int CIRCLE_RADIUS = 50;
    // Draw inner info window
    canvas.drawCircle((float) curScreenCoords.x, (float) curScreenCoords.y, CIRCLE_RADIUS, getInnerPaint());
    // if needed, draw a border for info window
    canvas.drawCircle(curScreenCoords.x, curScreenCoordsy, CIRCLE_RADIUS, getBorderPaint());
}

private Paint innerPaint, borderPaint;

public Paint getInnerPaint() {
    if (innerPaint == null) {
        innerPaint = new Paint();
        innerPaint.setARGB(225, 68, 89, 82); // gray
        innerPaint.setAntiAlias(true);
    }
    return innerPaint;
}

public Paint getBorderPaint() {
    if (borderPaint == null) {
        borderPaint = new Paint();
        borderPaint.setARGB(255, 68, 89, 82);
        borderPaint.setAntiAlias(true);
        borderPaint.setStyle(Style.STROKE);
        borderPaint.setStrokeWidth(2);
    }
    return borderPaint;
}

@Override
protected void onDraw(Canvas canvas) {
    Point p = new Point();
    for(OverlayItem item : items) {
        drawCircle(canvas, getProjection().toPixels(item.getPoint(), p));
    }
}
Ilya Saunkin
  • 18,934
  • 9
  • 36
  • 50
4

This isn't perfect, but here's a little code I put together to put a circle on a map. You could easily expand on it to set the colour of the circle etc. Most of the other code samples I've seen haven't taken into account scaling the circle size with the zoom level which is a common requirement when creating circles. Circle Radius is in meters.

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
public class CircleOverlay extends Overlay {

    Context context;
    double mLat;
    double mLon;
    float mRadius;

     public CircleOverlay(Context _context, double _lat, double _lon, float radius ) {
            context = _context;
            mLat = _lat;
            mLon = _lon;
            mRadius = radius;
     }

     public void draw(Canvas canvas, MapView mapView, boolean shadow) {

         super.draw(canvas, mapView, shadow); 

         Projection projection = mapView.getProjection();

         Point pt = new Point();

         GeoPoint geo = new GeoPoint((int) (mLat *1e6), (int)(mLon * 1e6));

         projection.toPixels(geo ,pt);
         float circleRadius = projection.metersToEquatorPixels(mRadius);

         Paint innerCirclePaint;

         innerCirclePaint = new Paint();
         innerCirclePaint.setColor(Color.BLUE);
         innerCirclePaint.setAlpha(25);
         innerCirclePaint.setAntiAlias(true);

         innerCirclePaint.setStyle(Paint.Style.FILL);

         canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, innerCirclePaint);
    }
}
Scott
  • 2,593
  • 1
  • 22
  • 23
2

For Kotlin, to draw a circle in the center of the map, you can use

mMap.setOnCameraIdleListener {
        val midLatLng: LatLng = mMap.cameraPosition.target

        mMap.addCircle(CircleOptions()
                .center(midLatLng)
                .radius(radiusInMeters)
                .strokeWidth(1f)
                .fillColor(0x880000FF))
}

mMap is GoogleMap

Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
0

If you put the following code in your overlay's draw method, it will draw a circle radius 20 px in the centre of your mapView

@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
    ....
    ....

    Paint lp4;
    lp4 = new Paint();
    lp4.setColor(Color.RED);
    lp4.setAntiAlias(true);
    lp4.setStyle(Style.STROKE);
    canvas.drawCircle(mapView.getWidth()/2, mapView.getHeight()/2, 20, lp4);

    ....
    ....
    mapView.invalidate();
}

You should be able to adapt it to suit your needs

NickT
  • 23,844
  • 11
  • 78
  • 121
  • I assume you have an class MapOverlay which extends com.google.android.maps.Overlay to draw your markers. This will have a superclass method 'draw' with parameters of mapView and canvas. Override this method's draw as described, then draw the circle on the canvas. – NickT May 17 '11 at 11:05