2011-03-14 114 views
16

得到它固定在这里是我的解决方案:画一个圆圈在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())); 

希望这有助于。

+0

谢谢...我怎么能改变不透明度 - 透明度 - 的圆。 – user836026 2012-07-04 20:54:35

+0

你为什么要传递一个上下文? – k0pernikus 2012-08-20 15:31:32

+0

结帐此库在地图上绘制圆圈v2:https://github.com/i-schuetz/map_areas – Ixx 2014-10-14 21:41:40

回答

8

接受的答案有错误。我试图纠正它,但由于某种奇怪的原因,我的编辑被拒绝了。在任何情况下,这里是一个纠正答案:

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

在斯科特的回答的问题是,circleRadius使用,从米转换为点像素赤道的方法计算。但是,如果你所期望的点不在赤道上,那么半径将会太小,因为转换不能解释经线在两极汇合的事实。然而,这可以通过乘以(1/ FloatMath.cos((float) Math.toRadians(mLat)))来纠正,这是我对斯科特原始答案所做的唯一修改。

我希望这可以帮助别人,因为我发现困难的方式。我住在芬兰,在那里使用原来的方法,这些圈子比他们应该得到的小2倍!

0
  1. 是您尝试显示的地理点(0.1275,51.507222)?这是索马里沿海的某个地方。

  2. super.draw(..)应该是您的draw()方法中的第一条语句。

+0

我意识到第一点= P我现在要做第二个,我如何获得对画布的引用主要类使用虽然? – nhunston 2011-03-14 01:37:29

7

我已经采取上述样品和扩大它考虑到这需要将与所述地图的缩放级别来缩放帐户圈(即:圆相对于地面的距离)。

有些人可能会觉得它有用。

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); 

     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); 
    } 
} 
+0

我发现这个答案很有用,但最终发现了一个错误。我试图编辑它,但最终不得不发布一个单独的答案,因为我的编辑被拒绝(仍然不明白为什么......)。 – robguinness 2012-08-22 13:12:16

+0

是的,我认为谁审查它是有点紧。无论如何,我已经添加了您建议的修改。 ;-) – Scott 2012-08-23 23:55:44

+0

很酷,谢谢。并感谢您的原始代码! – robguinness 2012-08-24 07:16:24