GoogleMaps API (Android) – 在缩放标记的边缘之间绘制多段线
GoogleMaps API (Android) – Draw PolyLine between the edges of Markers adjusting with Zoom
在 Android 上使用 GoogleMaps API,我将一系列标记添加到 MapOverlay。
当用户缩放地图时,这些标记在屏幕上保持相同大小。
我有一条连接这些标记的折线,它目前从每个标记的中心延伸到下一个标记。
我想更改此设置,使多段线在每个标记的边缘开始和结束。
我的问题是边缘的 Lat/Lng 随着用户缩放而改变。
最好的方法是什么?
我目前添加我的标记和线如下:
markerOptions = new MarkerOptions().position(latLng)
.anchor(0.5F, 0.5F).draggable(false).visible(true)
.icon(BitmapDescriptorFactory.fromResource(markerId));
this.googleMap.addMarker(markerOptions);
PolylineOptions options = new PolylineOptions();
options.add(new LatLng(controlPointEnd1.getLatitude(),controlPointEnd1.getLongitude()));
…
this.googleMap.addPolyline(options.width(4).color(Color.MAGENTA).geodesic(false));
Screen shot showing: Ground overlay, a couple of markers and the PolyLine
提前致谢。
目标
我看到您正在使用圆圈形式的图标,并且想创建一条连接圆圈边界而不是圆心的多段线。
这里我们要解决以下问题:
计算以屏幕像素为单位的圆形标记的半径。由于图标不会改变大小,它将是一个常量值。
计算圆边界坐标的偏移位置,并在这些点之间绘制折线
解决方案
计算屏幕像素圆半径的相关代码如下
//Let's calculate what is a radius in screen pixels for our icon
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Drawable m_icon = ResourcesCompat.getDrawableForDensity(getResources(),R.drawable.ic_circle,dm.densityDpi,null);
int height = ((BitmapDrawable)m_icon).getBitmap().getHeight();
int width = ((BitmapDrawable)m_icon).getBitmap().getWidth();
iconRadiusPixels = width / 2;
我想您有圆形图标的可绘制资源 R.drawable.ic_circle。此代码可位于 onCreate() 方法中。
接下来是计算边界点偏移位置的函数。我们将需要具有 SphericalUtil class 的 Google Maps Android API Utility Library,我们可以使用它来计算点之间的航向和圆半径的偏移量。您必须将实用程序库包含在您的 gradle 中作为 compile 'com.google.maps.android:android-maps-utils:0.4'
。代码的相关部分如下
private void showCustomPolyline () {
//Get projection
Projection proj = mMap.getProjection();
//Get a point on the screen that corresponds to first marker
Point p = proj.toScreenLocation(sydney1);
//Lets create another point that is shifted on number of pixels iqual to icon radius
//This point is located on circle border
Point b = new Point(p.x + iconRadiusPixels, p.y);
//Get the LatLng for a point on the circle border
LatLng l = proj.fromScreenLocation(b);
//Calculate the radius of the icon (distance between center and point on the circle border)
double r = SphericalUtil.computeDistanceBetween(sydney1,l);
//Calculate heading from point 1 to point 2 and from point 2 to point 1
double heading1 = SphericalUtil.computeHeading(sydney1, sydney2);
double heading2 = SphericalUtil.computeHeading(sydney2, sydney1);
//Calculate real position where the polyline starts and ends taking into account radius and heading
LatLng pos1 = SphericalUtil.computeOffset(sydney1, r, heading1);
LatLng pos2 = SphericalUtil.computeOffset(sydney2, r, heading2);
//Create polyline
PolylineOptions options = new PolylineOptions();
options.add(pos1);
options.add(pos2);
poly = mMap.addPolyline(options.width(4).color(Color.RED).geodesic(false));
}
最后,您可以监听 GoogleMap.OnCameraMoveListener 或 GoogleMap.OnCameraIdleListener 等相机事件,并在相机移动时重新绘制多段线。为简单起见,让我们在相机完成移动后重新绘制多段线
@Override
public void onCameraIdle() {
if (this.poly != null) {
this.poly.remove();
this.poly = null;
}
this.showCustomPolyline();
}
结论
您可以从 GitHub
下载包含完整代码的示例项目
https://github.com/xomena-so/so43303695
只需在 app/src/debug/res/values/google_maps_api.xml
中用你的替换我的 API 密钥
在 Android 上使用 GoogleMaps API,我将一系列标记添加到 MapOverlay。
当用户缩放地图时,这些标记在屏幕上保持相同大小。
我有一条连接这些标记的折线,它目前从每个标记的中心延伸到下一个标记。
我想更改此设置,使多段线在每个标记的边缘开始和结束。
我的问题是边缘的 Lat/Lng 随着用户缩放而改变。
最好的方法是什么?
我目前添加我的标记和线如下:
markerOptions = new MarkerOptions().position(latLng)
.anchor(0.5F, 0.5F).draggable(false).visible(true)
.icon(BitmapDescriptorFactory.fromResource(markerId));
this.googleMap.addMarker(markerOptions);
PolylineOptions options = new PolylineOptions();
options.add(new LatLng(controlPointEnd1.getLatitude(),controlPointEnd1.getLongitude()));
…
this.googleMap.addPolyline(options.width(4).color(Color.MAGENTA).geodesic(false));
Screen shot showing: Ground overlay, a couple of markers and the PolyLine 提前致谢。
目标
我看到您正在使用圆圈形式的图标,并且想创建一条连接圆圈边界而不是圆心的多段线。
这里我们要解决以下问题:
计算以屏幕像素为单位的圆形标记的半径。由于图标不会改变大小,它将是一个常量值。
计算圆边界坐标的偏移位置,并在这些点之间绘制折线
解决方案
计算屏幕像素圆半径的相关代码如下
//Let's calculate what is a radius in screen pixels for our icon
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
Drawable m_icon = ResourcesCompat.getDrawableForDensity(getResources(),R.drawable.ic_circle,dm.densityDpi,null);
int height = ((BitmapDrawable)m_icon).getBitmap().getHeight();
int width = ((BitmapDrawable)m_icon).getBitmap().getWidth();
iconRadiusPixels = width / 2;
我想您有圆形图标的可绘制资源 R.drawable.ic_circle。此代码可位于 onCreate() 方法中。
接下来是计算边界点偏移位置的函数。我们将需要具有 SphericalUtil class 的 Google Maps Android API Utility Library,我们可以使用它来计算点之间的航向和圆半径的偏移量。您必须将实用程序库包含在您的 gradle 中作为 compile 'com.google.maps.android:android-maps-utils:0.4'
。代码的相关部分如下
private void showCustomPolyline () {
//Get projection
Projection proj = mMap.getProjection();
//Get a point on the screen that corresponds to first marker
Point p = proj.toScreenLocation(sydney1);
//Lets create another point that is shifted on number of pixels iqual to icon radius
//This point is located on circle border
Point b = new Point(p.x + iconRadiusPixels, p.y);
//Get the LatLng for a point on the circle border
LatLng l = proj.fromScreenLocation(b);
//Calculate the radius of the icon (distance between center and point on the circle border)
double r = SphericalUtil.computeDistanceBetween(sydney1,l);
//Calculate heading from point 1 to point 2 and from point 2 to point 1
double heading1 = SphericalUtil.computeHeading(sydney1, sydney2);
double heading2 = SphericalUtil.computeHeading(sydney2, sydney1);
//Calculate real position where the polyline starts and ends taking into account radius and heading
LatLng pos1 = SphericalUtil.computeOffset(sydney1, r, heading1);
LatLng pos2 = SphericalUtil.computeOffset(sydney2, r, heading2);
//Create polyline
PolylineOptions options = new PolylineOptions();
options.add(pos1);
options.add(pos2);
poly = mMap.addPolyline(options.width(4).color(Color.RED).geodesic(false));
}
最后,您可以监听 GoogleMap.OnCameraMoveListener 或 GoogleMap.OnCameraIdleListener 等相机事件,并在相机移动时重新绘制多段线。为简单起见,让我们在相机完成移动后重新绘制多段线
@Override
public void onCameraIdle() {
if (this.poly != null) {
this.poly.remove();
this.poly = null;
}
this.showCustomPolyline();
}
结论
您可以从 GitHub
下载包含完整代码的示例项目https://github.com/xomena-so/so43303695
只需在 app/src/debug/res/values/google_maps_api.xml