Chr*_*nie 6 android google-maps-android-api-2
我正在使用 Gooogle Maps API v2 开发 Android 应用程序。我的地图上有标记,我想圈出其中一个。通过使用 Circle 和 Circle Options 类,我设法轻松地做到了这一点。但我也希望我的圆圈在缩放或取消缩放时在屏幕上保持相同的大小,就像标记一样。这意味着圆必须具有以像素为单位的恒定半径。遗憾的是,我们无法在 API v2 中以像素为单位设置半径。
我尝试了几种解决方案,但我并不满意。
在第一个中,我只是乘以或除以半径:
@Override
public void onCameraChange(CameraPosition position)
{
if(previousZoom > position.zoom) {
mSelectionCircle.setRadius(Math.abs(position.zoom - previousZoom)*2*mSelectionCircle.getRadius());
}
else if(previousZoom < position.zoom) {
mSelectionCircle.setRadius(Math.abs(position.zoom - previousZoom)*mSelectionCircle.getRadius()/2);
}
previousZoom = position.zoom;
}
Run Code Online (Sandbox Code Playgroud)
起初它似乎有效,但在快速缩放或用手指缩放时会产生错误的结果。此外,缩放比例在屏幕上清晰可见。
我的第二个解决方案使用像素-米转换。这个想法是在缩放/取消缩放时以米为单位重新计算半径,因此圆圈在屏幕上具有恒定的大小。为此,我获取了 Circle 在屏幕上的当前位置:
Point p1 = mMap.getProjection().toScreenLocation(mSelectionCircle.getCenter());
Run Code Online (Sandbox Code Playgroud)
然后我在圆的边缘创建另一个点:
Point p2 = new Point(p1.x + radiusInPixels, p1.y);
Run Code Online (Sandbox Code Playgroud)
在哪里
int radiusInPixels = 40;
Run Code Online (Sandbox Code Playgroud)
之后,我使用一个函数返回这两个点之间的距离(以米为单位)。
private double convertPixelsToMeters(Point point1, Point point2) {
double angle = Math.acos(Math.sin(point1.x) * Math.sin(point2.x)
+ Math.cos(point1.x) * Math.cos(point2.x) * Math.cos(point1.y- point2.y));
return angle * Math.PI * 6378100.0; // distance in meters
}
Run Code Online (Sandbox Code Playgroud)
6378100 是平均地球半径。最后,我设置了 Circle 的新半径:
mSelectionCircle.setRadius(convertPixelsToMeters(p1, p2));
Run Code Online (Sandbox Code Playgroud)
它理论上应该有效,但我得到了荒谬的半径值(10^7 m!)。可能是转换函数有问题?
那么有没有更简单的方法来做到这一点,或者如果没有,您能帮我理解为什么我的第二个解决方案不起作用吗?
谢谢!
您可能并不真正关心确切的像素大小,只是关心所有缩放级别和设备旋转时它看起来都相同。
这是一个相当简单的方法来做到这一点。绘制(如果缩放更改则重新绘制)一个半径为可见屏幕对角线一定百分比的圆。
Google Maps API v2 有一个getProjection()函数可以返回可见屏幕 4 个角的纬度/经度坐标。然后使用超级方便的Location类,您可以计算屏幕上可见的对角线的距离,并使用该对角线的百分比作为圆的半径。无论缩放比例是多少或设备以何种方式旋转,您的圆圈都将具有相同的大小。
这是 Java 中的代码:
public Circle drawMapCircle(GoogleMap googleMap,LatLng latLng,Circle currentCircle) {
// get 2 of the visible diagonal corners of the map (could also use farRight and nearLeft)
LatLng topLeft = googleMap.getProjection().getVisibleRegion().farLeft;
LatLng bottomRight = googleMap.getProjection().getVisibleRegion().nearRight;
// use the Location class to calculate the distance between the 2 diagonal map points
float results[] = new float[4]; // probably only need 3
Location.distanceBetween(topLeft.latitude,topLeft.longitude,bottomRight.latitude,bottomRight.longitude,results);
float diagonal = results[0];
// use 5% of the diagonal for the radius (gives a 10% circle diameter)
float radius = diagonal / 20;
Circle circle = null;
if (currentCircle != null) {
// change the radius if the circle already exists (result of a zoom change)
circle = currentCircle;
circle.setRadius(radius);
} else {
// draw a new circle
circle = googleMap.addCircle(new CircleOptions()
.center(latLng)
.radius(radius)
.strokeColor(Color.BLACK)
.strokeWidth(2)
.fillColor(Color.LTGRAY));
}
return circle;
}
Run Code Online (Sandbox Code Playgroud)
使用自定义图标Marker代替。您可以创建Bitmap和Canvas,在后者上绘制并将其用作图标Marker:
new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(bitmap))...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5034 次 |
| 最近记录: |