Нарисуйте круг определенного радиуса на карте в Android

Я хочу нарисовать круг на карте. Я хочу, чтобы пользователь ввел радиус, и для этого радиуса я должен показать круг на карте. После этого мне нужно отобразить маркеры в некоторых местах этого круга.

Я знаю, как отображать маркеры на карте.

Как нарисовать круг на виде карты и показать маркеры на границе круга?

Ответ 1

В реализации ItemizedOverlay выполните что-то вроде метода drawCircle из метода onDraw

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

Ответ 2

Просто чтобы довести это до сегодняшнего дня... они сделали это очень легко в Google Maps API версии 2.

    mMap.addCircle(new CircleOptions()
        .center(center)
        .radius(radius)
        .strokeWidth(0f)
        .fillColor(0x550000FF));

Где радиус находится в метрах.

Что касается маркеров на границе, это должно быть относительно легко сделать - просто следуйте демонстрации "Круги" в примере кода Google Maps здесь: https://developers.google.com/maps/documentation/android/intro#sample_code

Ответ 3

В случае, если кто-то искал ответ с помощью API Карт Google v2, вот фрагмент того, что я сделал. Это действительно более географический подход.

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

}

Хорошо, что вам не нужно перерисовывать что-либо после масштабирования или панорамирования карты - круг становится соответствующим образом изменен и перемещен. Недостатком является то, что это не сработает, если вам нужен круг на северном или южном полюсе - все это будет bezerk, но, надеюсь, это не тот случай 99% времени:)

Ответ 4

Это не идеально, но вот небольшой код, который я собрал, чтобы поместить круг на карту. Вы можете легко расширить его, чтобы установить цвет круга и т.д. Большинство других образцов кода, которые я видел, не учитывали масштабирование размера круга с уровнем масштабирования, что является общим требованием при создании кругов. Радиус круга находится в метрах.

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

Ответ 5

Если вы поместите следующий код в метод наложения наложения, он нарисует радиус круга 20 px в центре вашего 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();
}

Вы должны быть в состоянии адаптировать его в соответствии с вашими потребностями.

Ответ 6

Для Kotlin, чтобы нарисовать круг в центре карты, вы можете использовать

mMap.setOnCameraIdleListener {
        val midLatLng: LatLng = mMap.cameraPosition.target

        mMap.addCircle(CircleOptions()
                .center(midLatLng)
                .radius(radiusInMeters)
                .strokeWidth(1f)
                .fillColor(0x880000FF))
}

mMap - это GoogleMap