Draw circle of certain radius on map view in Android

后端 未结 6 777
一向
一向 2020-12-08 11:55

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

相关标签:
6条回答
  • 2020-12-08 12:20

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

    0 讨论(0)
  • 2020-12-08 12:21

    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

    0 讨论(0)
  • 2020-12-08 12:28

    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

    0 讨论(0)
  • 2020-12-08 12:29

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-08 12:32

    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

    0 讨论(0)
  • 2020-12-08 12:33

    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));
        }
    }
    
    0 讨论(0)
提交回复
热议问题