GoogleMaps API(Android) - 使用缩放调整标记边缘之间绘制PolyLine

时间:2017-04-09 06:21:59

标签: android google-maps google-maps-android-api-2

在Android上使用GoogleMaps API,我在MapOverlay中添加了一系列标记。

当用户缩放地图时,这些标记在屏幕上保持相同的大小。

我有一个连接这些标记的PolyLine,它目前从每个标记的中心运行到下一个标记。

我想更改此设置,以便PolyLine在每个标记的边缘开始并结束。

我的问题是,当用户缩放时,边缘的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 提前谢谢。

1 个答案:

答案 0 :(得分:0)

目标

我可以看到你正在使用圆圈形式的图标,并希望创建一个连接圆圈边界的折线,而不是它们的中心。

这里我们要解决以下问题:

  1. 以屏幕像素计算圆圈标记的半径。由于图标没有改变大小,因此它将是一个恒定值。

  2. 计算圆边框上坐标的偏移位置,并在这些点之间绘制折线

  3. 解决方案

    以屏幕像素计算圆半径的相关代码如下

    //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类的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密钥即可

    enter image description here