画一个圆圈在Android上的MapView圆圈、画一、MapView、Android

2023-09-12 09:03:24 作者:禁忌

把它固定在这里是我的解决方案:

Got it fixed here is my solution:

编辑:更新,以反映robguinness答案

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

}

画,它需要被添加到地图覆盖

mMapView.getOverlays().add(new CircleOverlay(context, loc.getLatitude(),loc.getLongitude()));

希望这有助于。

Hope this helps.

推荐答案

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

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:

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

在Scott的回答的问题是,所述circleRadius使用它把来自米至像素点的在赤道的方法进行了计算。但是,如果你想要的点不在赤道上,在半径过小,因为转换不考虑一个事实,即经络走到一起,在两极。然而,这个可以修正,通过乘以(1 / FloatMath.cos((浮点)Math.toRadians(MLAT))),这就是我所做的唯一的变化斯科特最初的答案。

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.

我希望这可以帮助别人,因为我发现这个问题了艰辛的道路。我住在芬兰,采用原始方法,圆圈绘​​制〜2倍,而比他们本来应该!

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!