Having the following code to draw circle (taken from Google Play Services "maps" sample):
PolylineOptions options = new PolylineOptions();
int radius = 5; //What is that?
int numPoints = 100;
double phase = 2 * Math.PI / numPoints;
for (int i = 0; i <= numPoints; i++) {
options.add(new LatLng(SYDNEY.latitude + radius * Math.sin(i * phase),
SYDNEY.longitude + radius * Math.cos(i * phase)));
}
int color = Color.RED;
mMap.addPolyline(options
.color(color)
.width(2));
This is what gets drawn on different part of the world:
As you see circles are not really circles and even second one is ellipse basically.
I guess that "anti-aliasing" of circle depending on number of points in int numPoints
variable.
int radius = 5
variable in example code? I mean what measure it is?canvas.drawCircle()
UPDATE --------------------
OK after improving math I was able to draw "right" circle:
private void addCircle(LatLng latLng, double radius)
{
double R = 6371d; // earth's mean radius in km
double d = radius/R; //radius given in km
double lat1 = Math.toRadians(latLng.latitude);
double lon1 = Math.toRadians(latLng.longitude);
PolylineOptions options = new PolylineOptions();
for (int x = 0; x <= 360; x++)
{
double brng = Math.toRadians(x);
double latitudeRad = Math.asin(Math.sin(lat1)*Math.cos(d) + Math.cos(lat1)*Math.sin(d)*Math.cos(brng));
double longitudeRad = (lon1 + Math.atan2(Math.sin(brng)*Math.sin(d)*Math.cos(lat1), Math.cos(d)-Math.sin(lat1)*Math.sin(latitudeRad)));
options.add(new LatLng(Math.toDegrees(latitudeRad), Math.toDegrees(longitudeRad)));
}
mMap.addPolyline(options.color(Color.BLACK).width(2));
}
However anti-aliasing of circle I guess is somewhat beyond control, and on some zoom levels circle might get ugly:
Draw a circle - Enter a radius then click a point or enter an address to draw a circle on a google map. Elevation Calculator Tool - Works similar to the distance calculator tool, but instead of the distance along the path it shows a graph of elevation points along that path.
Have a street directory and a compass you last used in Year 11? Sweet. Find the map's scale, extend your compass to cover 5km, stick the pin in your home address and give that bad boy a 360 degree twirl. That's your radius.
Google made is simple in maps v2. The snippet below demonstrates both drawing markers and circles along with updating their positions together.
private Circle mCircle;
private Marker mMarker;
private GoogleMap mGoogleMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment)).getMap();
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if(mCircle == null || mMarker == null){
drawMarkerWithCircle(latLng);
}else{
updateMarkerWithCircle(latLng);
}
}
});
}
private void updateMarkerWithCircle(LatLng position) {
mCircle.setCenter(position);
mMarker.setPosition(position);
}
private void drawMarkerWithCircle(LatLng position){
double radiusInMeters = 100.0;
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
mCircle = mGoogleMap.addCircle(circleOptions);
MarkerOptions markerOptions = new MarkerOptions().position(position);
mMarker = mGoogleMap.addMarker(markerOptions);
}
How to draw circle in Google Maps v2 (bitmap)
// 1. some variables:
private static final double EARTH_RADIUS = 6378100.0;
private int offset;
// 2. convert meters to pixels between 2 points in current zoom:
private int convertMetersToPixels(double lat, double lng, double radiusInMeters) {
double lat1 = radiusInMeters / EARTH_RADIUS;
double lng1 = radiusInMeters / (EARTH_RADIUS * Math.cos((Math.PI * lat / 180)));
double lat2 = lat + lat1 * 180 / Math.PI;
double lng2 = lng + lng1 * 180 / Math.PI;
Point p1 = YourActivity.getMap().getProjection().toScreenLocation(new LatLng(lat, lng));
Point p2 = YourActivity.getMap().getProjection().toScreenLocation(new LatLng(lat2, lng2));
return Math.abs(p1.x - p2.x);
}
// 3. bitmap creation:
private Bitmap getBitmap() {
// fill color
Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setColor(0x110000FF);
paint1.setStyle(Style.FILL);
// stroke color
Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint2.setColor(0xFF0000FF);
paint2.setStyle(Style.STROKE);
// icon
Bitmap icon = BitmapFactory.decodeResource(YourActivity.getResources(), R.drawable.blue);
// circle radius - 200 meters
int radius = offset = convertMetersToPixels(lat, lng, 200);
// if zoom too small
if (radius < icon.getWidth() / 2) {
radius = icon.getWidth() / 2;
}
// create empty bitmap
Bitmap b = Bitmap.createBitmap(radius * 2, radius * 2, Config.ARGB_8888);
Canvas c = new Canvas(b);
// draw blue area if area > icon size
if (radius != icon.getWidth() / 2) {
c.drawCircle(radius, radius, radius, paint1);
c.drawCircle(radius, radius, radius, paint2);
}
// draw icon
c.drawBitmap(icon, radius - icon.getWidth() / 2, radius - icon.getHeight() / 2, new Paint());
return b;
}
// 4. calculate image offset:
private LatLng getCoords(double lat, double lng) {
LatLng latLng = new LatLng(lat, lng);
Projection proj = YourActivity.getMap().getProjection();
Point p = proj.toScreenLocation(latLng);
p.set(p.x, p.y + offset);
return proj.fromScreenLocation(p);
}
// 5. draw:
MarkerOptions options = new MarkerOptions();
options.position(getCoords(lat, lng));
options.icon(BitmapDescriptorFactory.fromBitmap(getBitmap()));
marker = YourActivity.getMap().addMarker(options);
and result:
Android 2.0 API you can use CircleOption to draw a circle, works really well, no messy conversions of pixels to meters.
public CircleOptions getCircleOptions() {
CircleOptions co = new CircleOptions();
co.center(latlng);
co.radius(getCircleSize());
co.fillColor(getCircleColor());
co.strokeColor(getStrokeColor());
co.strokeWidth(2.0f);
return co;
}
Circle circle = mapView.getMap().addCircle(munzeeMarker.getCircleOptions());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With