web-dev-qa-db-ja.com

Android)のマップビューに特定の半径の円を描画します

マップビューに円を描きたい。ユーザーに半径を入力してもらい、その半径については地図上に円を表示する必要があります。その後、その円のいくつかの場所にマーカーを表示する必要があります。

マップビューにマーカーを表示する方法を知っています。

マップビューに円を描画し、その円の境界にマーカーを表示するにはどうすればよいですか。

14
Prabhu M

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

これを最新のものにするためだけに... Google Maps APIv2で非常に簡単に実行できるようになりました。

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

半径はメートルです。

境界上のマーカーについては、比較的簡単に実行できるはずです。Googleマップのサンプルコードの「Circles」デモに従ってください。 https://developers.google.com/maps/documentation/Android/ intro#sample_code

30
warbi

誰かがGoogleMaps API 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));
}

}

これの良い点は、マップをズームまたはパンした後に何も再描画する必要がないことです。円はサイズ変更され、それに応じて移動します。欠点は、北極または南極のいずれかに円が必要な場合、これが機能しないことです。すべてがベゼルクになりますが、99%の場合はそうではないことを願っています:)

10
Grisha S

これは完璧ではありませんが、地図上に円を配置するためにまとめた小さなコードを次に示します。簡単に展開して、円の色などを設定できます。私が見た他のコードサンプルのほとんどは、円を作成するときに一般的な要件であるズームレベルで円のサイズをスケーリングすることを考慮していません。円の半径はメートル単位です。

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

Kotlinの場合、マップの中央に円を描くには、次を使用できます。

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

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

mMapGoogleMapです

0

オーバーレイのdrawメソッドに次のコードを入力すると、mapViewの中心に半径20ピクセルの円が描画されます。

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

あなたはあなたのニーズに合うようにそれを適応させることができるはずです

0
NickT