【问题标题】:How to create direction arrows for my polylines in android如何在android中为我的折线创建方向箭头
【发布时间】:2018-11-26 13:07:25
【问题描述】:

我需要添加的内容

PolylineOptions polyline = new PolylineOptions();
polyline.addAll(geom);
polyline.color(defaultStrokeColor).width(defaultWidth);
mapObjects.add(polyline);

这段代码显示箭头?

【问题讨论】:

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


【解决方案1】:

我已经看到其他使用标记并旋转它们的问题/答案。但是有一种更简单的方法可以在 GoogleMap 折线上设置方向箭头。

GoogleMap API v2 通过将“endcap”图标添加到 PolylineOptions 提供了一种巧妙的方法。它采用您输入的位图图标并将其沿折线的方向旋转。箭头不需要标记。并且图标旋转是自动的。只要原来的箭头图标指向“向上”。

坦率地说,我很惊讶没有 ArrowCap 类。这些类确实存在:ButtCapRoundCapSquareCap,但不存在 ArrowCap 类。

所以我们需要用我们自己的箭头图像来解决它。唯一的小问题是折线(和下一个连接的折线)使用图标的中心作为端点。因此,请确保您的收尾图标指向图像的中心。

我在这里制作并上传了一个示例箭头图标图片:>

抱歉,它是白色的,看起来不可见,但它在 符号之间,只需将其拖到桌面即可。

我希望能够以编程方式更改箭头颜色,因此我创建了这个白色 PNG 图像,然后使用滤色器在其上叠加(乘)一种颜色。

图标是一个向上的白色箭头,点在图像的中心。图像的上半部分是空的(透明的)。您将需要使用 Image Asset Studio(或您最喜欢的图像工具)为以下分辨率创建 mipmap 图像:mdpi=24x24、hdpi=36x36、xhdpi=48x48、xxhdpi=72x72、xxxhdpi=96x96。

这里是生成 Polyline/PolylineOptions 所需的 endcap BitmapDescriptor 的代码(R.mipmap.endcap 是我上面包含的图像):

/**
 * Return a BitmapDescriptor of an arrow endcap icon for the passed color.
 * 
 * @param context - a valid context object
 * @param color - the color to make the arrow icon
 * @return BitmapDescriptor - the new endcap icon
 */
public BitmapDescriptor getEndCapIcon(Context context,  int color) {

    // mipmap icon - white arrow, pointing up, with point at center of image
    // you will want to create:  mdpi=24x24, hdpi=36x36, xhdpi=48x48, xxhdpi=72x72, xxxhdpi=96x96
    Drawable drawable = ContextCompat.getDrawable(context, R.mipmap.endcap);

    // set the bounds to the whole image (may not be necessary ...)
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());

    // overlay (multiply) your color over the white icon
    drawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);

    // create a bitmap from the drawable
    android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);

    // render the bitmap on a blank canvas
    Canvas canvas = new Canvas(bitmap);
    drawable.draw(canvas);

    // create a BitmapDescriptor from the new bitmap
    return BitmapDescriptorFactory.fromBitmap(bitmap);
}

下面是创建带有指向折线方向的箭头端盖的折线的代码:

/**
 * Draw a GoogleMap Polyline with an endcap arrow between the 2 locations.
 *
 * @param context - a valid context object
 * @param googleMap - a valid googleMap object
 * @param fromLatLng - the starting position
 * @param toLatLng - the ending position
 * @return Polyline - the new Polyline object
 */
public Polyline drawPolylineWithArrowEndcap(Context context,
                                            GoogleMap googleMap,
                                            LatLng fromLatLng,
                                            LatLng toLatLng) {

    int arrowColor = Color.RED; // change this if you want another color (Color.BLUE)
    int lineColor = Color.RED;

    BitmapDescriptor endCapIcon = getEndCapIcon(context,arrowColor);

    // have googleMap create the line with the arrow endcap
    // NOTE:  the API will rotate the arrow image in the direction of the line
    Polyline polyline = googleMap.addPolyline(new PolylineOptions()
            .geodesic(true)
            .color(lineColor)
            .width(8)
            .startCap(new RoundCap())
            .endCap(new CustomCap(endCapIcon,8))
            .jointType(JointType.ROUND)
            .add(fromLatLng, toLatLng);

    return polyline;
}

【讨论】:

    【解决方案2】:

    我找到了一个解决方案,它对我有用

    PolylineOptions polyline = new PolylineOptions();
    polyline.addAll(geom);
    polyline.color(defaultStrokeColor).width(defaultWidth);
    mapObjects.add(polyline);
    double lat1 = geom.get(0).latitude;
                        double lng1 = geom.get(0).longitude;
    
                        // destination
                        double lat2 = geom.get(1).latitude;
                        double lng2 = geom.get(1).longitude;
    
                        //midpoint 
                        double lat = (lat1 + lat2)/2;
                        double lng = (lng1 + lng2)/2;
    
                        double dLon = (lng2-lng1);
                        double y = Math.sin(dLon) * Math.cos(lat2);
                        double x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
                        double brng = Math.toDegrees((Math.atan2(y, x)));
    

    现在在终点添加一个标记(箭头位图)

    MarkerOptions marker = new MarkerOptions().position(geom.get(0));
                        marker.anchor(0.5f, 0.5f);
                        marker.icon(BitmapDescriptorFactory.fromBitmap(bstyle));
                        marker.rotation((float) brng);
                        marker.flat(true);
    

    【讨论】:

      【解决方案3】:

      以下代码在行尾应用圆顶,并根据折线的类型(即来自可绘制资源文件的箭头图像)应用不同的开始上限,其中类型是存储在数据对象中的任意属性折线。该示例还指定了笔画宽度、笔画颜色和关节类型:

      switch (type) {
          // If no type is given, allow the API to use the default.
          case "A":
              // Use a custom bitmap as the cap at the start of the line.
              polyline.setStartCap(
                      new CustomCap(
                              BitmapDescriptorFactory.fromResource(R.drawable.ic_arrow), 10));
              break;
          case "B":
              // Use a round cap at the start of the line.
              polyline.setStartCap(new RoundCap());
              break;
      }
      
      polyline.setEndCap(new RoundCap());
      polyline.setWidth(POLYLINE_STROKE_WIDTH_PX);
      polyline.setColor(COLOR_BLACK_ARGB);
      polyline.setJointType(JointType.ROUND);
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-18
        • 1970-01-01
        相关资源
        最近更新 更多