如何在谷歌地图上创建折线,就像在图像中显示的线条一样

时间:2017-08-12 08:43:59

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

mern-starter

我还需要创建一个具有阴影和高程的折线。此外,我需要提供多种颜色的线。请建议。

2 个答案:

答案 0 :(得分:2)

目前,Google Maps Android API的折线不支持多种颜色。正如我在以前回答的评论中提到的,Google问题跟踪器中有一项功能请求,要求在Google地图Android API中实现渐变折线。

作为一种解决方法,您可以在地图上实现自己的GroundOverlay,绘制不同颜色的线条。看看StackOverflow上的类似问题,我发现有些人已经实现了这个功能。例如,您可以查看实现渐变折线和多边形的Github项目:

https://github.com/antoniocarlon/richmaps

我从此项目中复制了类并创建了一个示例Google地图活动,该活动显示了与您要查找的折线相似的折线。我的活动的代码段如下

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnCameraIdleListener {

    private GoogleMap mMap;
    private RichLayer richLayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        mMap.getUiSettings().setZoomControlsEnabled(true);

        LatLng ny1 = new LatLng(40.711322,-74.007844);
        LatLng ny2 = new LatLng(40.782493,-73.965424);

        LatLng ny3 = new LatLng(40.75675,-73.98571);

        mMap.setOnCameraIdleListener(this);

        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(ny3, 12f));

        richLayer = new RichLayer.Builder(findViewById(R.id.map), mMap).zIndex(100).build();

        this.showPolylineAndShade(ny1, ny2);
    }

    @Override
    public void onCameraIdle() {
        // Refresh the RichLayer each time the camera changes
        richLayer.refresh();
    }

    private void showPolylineAndShade(LatLng p1, LatLng p2) {
        this.showCurvedLine(p1, p2, 0.1, Color.argb(30, 220,220,220), Color.argb(30, 192,192,192), Color.argb(30, 105,105,105),15);
        this.showCurvedLine(p1, p2, 0.3, Color.argb(255, 0,191,255), Color.argb(255, 26,188,156), Color.argb(255, 40,123,177),6);
    }

    private void showCurvedLine (LatLng p1, LatLng p2, double k, int basecolor, int color1, int color2,  int w) {
        //Calculate distance and heading between two points
        double d = SphericalUtil.computeDistanceBetween(p1,p2);
        double h = SphericalUtil.computeHeading(p1, p2);

        //Midpoint position
        LatLng p = SphericalUtil.computeOffset(p1, d*0.5, h);

        //Apply some mathematics to calculate position of the circle center
        double x = (1-k*k)*d*0.5/(2*k);
        double r = (1+k*k)*d*0.5/(2*k);

        LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0);

        //Calculate heading between circle center and two points
        double h1 = SphericalUtil.computeHeading(c, p1);
        double h2 = SphericalUtil.computeHeading(c, p2);

        //Calculate positions of points on circle border and add them to polyline options
        int numpoints = 1000;
        double step = (h2 -h1) / numpoints;

        RichPolylineOptions polylineOpts = new RichPolylineOptions(null)
                .zIndex(100) // zIndex represents the position of the polyline on the RichLayer
                .strokeWidth(w)
                .strokeColor(basecolor)
                .linearGradient(false);

        Point fromScreenPoint = null;
        Point toScreenPoint = null;
        int[] colors = new int[]{color1, color2};
        Projection projection = mMap.getProjection();

        for (int i=0; i < numpoints; i++) {
            LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step);
            RichPoint rp = new RichPoint(pi);
            polylineOpts.add(rp);
            if (i == 0) {
                fromScreenPoint = projection.toScreenLocation(rp.getPosition());
            }
            if (i == numpoints -1) {
                toScreenPoint = projection.toScreenLocation(rp.getPosition());
            }
        }

        if (fromScreenPoint!=null && toScreenPoint!=null) {
            int fromX = fromScreenPoint.x ;
            int fromY = fromScreenPoint.y;
            int toX = toScreenPoint.x;
            int toY = toScreenPoint.y;

            polylineOpts.strokeShader(new LinearGradient(fromX, fromY, toX, toY,
                    colors, null, Shader.TileMode.CLAMP));
        }

        RichPolyline polyline = polylineOpts.build();
        richLayer.addShape(polyline);
    }
}

此代码将创建折线,如以下screentshot

所示

enter image description here

您可以在Github上找到并下载示例项目

https://github.com/xomena-so/so45648311

我希望这有帮助!

答案 1 :(得分:1)

似乎没有&#34;标准&#34;在Android Google Maps API中执行此操作的方法,但您始终可以使用放置在地图片段上的自定义View手动执行此操作。这样的事情:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/map_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment"
    />

    <your.custom.component.Name
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
    />

</RelativeLayout>

您可以从地图获取曲线坐标,并在具有透明度的自定义视图画布上绘制。