在 Android MapView 上画一个圆
这是我的解决方案:
编辑:更新以反映 robguinness 答案。
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 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);
if(shadow) return; // Ignore the shadow layer
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) * (1/ FloatMath.cos((float) Math.toRadians(mLat)));
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);
}
}
要“绘制”,需要将其添加到地图叠加层
mMapView.getOverlays().add(new CircleOverlay(context, loc.getLatitude(),loc.getLongitude()));
希望这会有所帮助。
Got it fixed here is my solution:
Edit: updated to reflect robguinness answer.
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 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);
if(shadow) return; // Ignore the shadow layer
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) * (1/ FloatMath.cos((float) Math.toRadians(mLat)));
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);
}
}
To "Draw" it needs to be added to the maps overlays
mMapView.getOverlays().add(new CircleOverlay(context, loc.getLatitude(),loc.getLongitude()));
Hope this helps.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
接受的答案有错误。我试图纠正它,但我的编辑由于某种奇怪的原因被拒绝。无论如何,这里是一个正确的答案:
Scott 答案中的问题是,circleRadius 是使用一种将赤道处的点从米转换为像素的方法来计算的。但是,如果您想要的点不在赤道上,则半径将太小,因为转换没有考虑经线在两极汇聚的事实。不过,这可以通过乘以
(1/ FloatMath.cos((float) Math.toRadians(mLat)))
来纠正,这是我对 Scott 原始答案所做的唯一更改。我希望这对某人有帮助,因为我以艰难的方式发现了这个问题。我住在芬兰,在那里使用原始方法,画出的圆圈比应有的小约两倍!
The accepted answer has an error. I attempted to correct it, but my edit was rejected for some strange reason. In any case, here is a corrected answer:
The problem in Scott's answer is that the circleRadius was calculated using a method that converts from meters to pixels for points at the equator. If, however, your desired point is not on the equator, the radius will be too small because the conversion does not account for the fact that meridians come together at the poles. This can be corrected, however, by multiplying by
(1/ FloatMath.cos((float) Math.toRadians(mLat)))
, which is the only change that I made to Scott's original answer.I hope this helps someone because I discovered the problem the hard way. I live in Finland, where using the original method, the circles were drawn ~2 times smaller than they should have been!
我采用了上面的示例并将其扩展为考虑到需要根据地图缩放级别进行缩放的圆圈(即:相对于地面距离的圆圈)。
有些人可能会发现它很有用。
I've taken the above sample and expanded it to take into account circles which need to be scaled with the map zoom level (ie: circles relative to ground distance).
Some people might find it useful.
您要显示的地理点是(0.1275、51.507222)吗?这是索马里海岸附近的某个地方。
super.draw(..)
应该是draw()
方法中的第一个语句。Is the geo point you are trying to show (0.1275, 51.507222)? This is somewhere off the coast of Somalia.
super.draw(..)
should be the first statement in yourdraw()
method.