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 locat
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 :)
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
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
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);
}
}
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
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));
}
}