Android Maps API v2 绘制圆圈 [英] Android Maps API v2 draw circle
问题描述
使用以下代码绘制圆圈(取自 Google Play 服务地图"示例):
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.
我猜圆的抗锯齿"取决于 int numPoints
变量中的点数.
I guess that "anti-aliasing" of circle depending on number of points in int numPoints
variable.
- 示例代码中的
int radius = 5
变量是什么?我的意思是它是什么衡量标准? - 主要问题是,以米为单位绘制具有给定半径的漂亮圆的正确方法是什么?类似于我们在 api v1 中使用
canvas.drawCircle()
的东西
- What is
int radius = 5
variable in example code? I mean what measure it is? - And main question what would be correct way of drawing nice circle with given radius in meters? Something smiliar to what we had in api v1 with
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:
推荐答案
如何在 Google Maps v2 (bitmap) 中绘制圆圈
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);
和结果:
这篇关于Android Maps API v2 绘制圆圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!