gpt4 book ai didi

android - 如何在 Google map 上绘制静态目标圆圈?

转载 作者:行者123 更新时间:2023-11-29 15:07:20 25 4
gpt4 key购买 nike

我一直在研究在 Google map 上绘制一个静态半径的圆,我遇到的所有答案都描述了绘制标记和与经纬度坐标相关的圆。

我需要的是:

enter image description here

这个圆圈和标记漂浮在 Google map fragment 上方,即:当您平移和缩放时,它保持静止。这是棘手的部分:我希望能够在 map 中获取覆盖区域以进行处理(例如:中心标记的纬度、经度和圆的半径,具体取决于放大 map )。

我怎样才能做到这一点?提前致谢。

最佳答案

您可以创建自定义View 来绘制圆。我的示例基于 Draw transparent circle filled outside

Here您可以找到有关如何创建自定义 View 的教程。

在我的示例中,我创建了一个自定义 RadarOverlayView,其中包含一个用于计算面积的 radius 参数。

我的自定义 View 代码:

public class RadarOverlayView extends LinearLayout {
private Bitmap windowFrame;
private float radius = 0f;
private int centerX = 0;
private int centerY = 0;

public RadarOverlayView(Context context) {
super(context);
}

public RadarOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.RadarOverlayView, 0, 0);

try {
radius = a.getDimension(R.styleable.RadarOverlayView_radius, 0f);
} finally {
a.recycle();
}
}

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);

if (windowFrame == null) {
createWindowFrame();
}
canvas.drawBitmap(windowFrame, 0, 0, null);
}

@Override
public boolean isEnabled() {
return false;
}

@Override
public boolean isClickable() {
return false;
}

protected void createWindowFrame() {
windowFrame = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas osCanvas = new Canvas(windowFrame);

centerX = getWidth() / 2;
centerY = getHeight() / 2;

if (radius > 0) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

// Draw the circunference
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setAlpha(200);
paint.setStrokeWidth(5);
osCanvas.drawCircle(centerX, centerY, radius, paint);

// Draw the circle
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setAlpha(100);
osCanvas.drawCircle(centerX, centerY, radius, paint);

// Draw the center icon
paint.setAlpha(255);
Bitmap centerBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
osCanvas.drawBitmap(centerBitmap, centerX - centerBitmap.getWidth() / 2,
centerY - centerBitmap.getHeight() / 2,
paint);
}
}

@Override
public boolean isInEditMode() {
return true;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
windowFrame = null;
}

public float getRadius() {
return radius;
}

public int getCenterX() {
return centerX;
}

public int getCenterY() {
return centerY;
}
}

我的 attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RadarOverlayView">
<attr name="radius" format="dimension" />
</declare-styleable>
</resources>

我的 activity_maps.xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/map"
android:name="myPackage.MySupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity"/>
<myPackage.RadarOverlayView
android:id="@+id/radar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
app:radius="150dp" />
</RelativeLayout>

我的 Activity :

public class MapsActivity extends FragmentActivity implements GoogleMap.OnCameraChangeListener {
private GoogleMap mMap;
private RadarOverlayView radarView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
radarView = (RadarOverlayView) findViewById(R.id.radar);
setUpMapIfNeeded();
}

@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}

private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
setUpMap();
}
}
}

private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setAllGesturesEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);

mMap.setOnCameraChangeListener(this);
}

@Override
public void onCameraChange(final CameraPosition cameraPosition) {
// Compute the area of the circle each time the camera changes

LatLng center = mMap.getProjection().fromScreenLocation(
new Point(radarView.getCenterX(), radarView.getCenterY()));
LatLng right = mMap.getProjection().fromScreenLocation(
new Point(radarView.getCenterX() + Math.round(radarView.getRadius()),
radarView.getCenterY()));

Location locationCenter = new Location("center");
locationCenter.setLatitude(center.latitude);
locationCenter.setLongitude(center.longitude);

Location locationRight = new Location("right");
locationRight.setLatitude(right.latitude);
locationRight.setLongitude(right.longitude);

double geoRadius = locationCenter.distanceTo(locationRight);
double geoArea = Math.PI * Math.pow(geoRadius, 2);

// Uncomment to inspect the difference between
// RadarOverlayView circle and geographic circle:
// mMap.clear();
// Circle circle = mMap.addCircle(new CircleOptions()
// .center(cameraPosition.target)
// .radius(geoRadius)
// .strokeColor(Color.GREEN)
// .fillColor(Color.BLUE));

Toast.makeText(this, "Area: " + geoArea, Toast.LENGTH_SHORT).show();
}
}

结果看起来像这样,并显示一个 Toast,每次相机改变时圆圈覆盖的区域:

enter image description here

限制:

该示例在 View 中绘制了一个完美的圆,但根据缩放级别,不能保证该圆在地理上是准确的。

您可以看到,在高缩放级别,如果您取消注释 mMap.addCircle,则自定义 View 绘制的圆与地理上准确的圆(基于相机目标和半径)之间存在巨大差异 onCameraChange 方法的代码:

enter image description here

这种由 map 投影 (WGS84) 引起的差异在高缩放级别时非常大,而在低缩放级别时会减小:

enter image description here

关于android - 如何在 Google map 上绘制静态目标圆圈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35737054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com