如何在 MapBox Android Studio 中绘制多个标记之间的优化路线

How to plot an optimized route between multiple markers in MapBox Android Studio

我正在尝试使用 MapBox 实现一个 Android Studio 应用程序,它允许用户在地图上 select 多个 waypoints 然后绘制经过每个的优化路线用户 selected waypoints 和 returns 回到起点。

我的代码中有两个函数用于放置标记和绘制路线。

标记函数:

@Override
public void onMapClick(@NonNull LatLng point) {
    // Drop a marker wherever the user taps
        
    destinationMarker = map.addMarker(new MarkerOptions().position(point));

    destinationPosition = Point.fromLngLat(point.getLongitude(), point.getLatitude());
    originPosition = Point.fromLngLat(originLocation.getLongitude(), originLocation.getLatitude());

    startButton.setEnabled(true);
    startButton.setBackgroundResource(R.color.mapboxBlue);

    getRoute(originPosition, destinationPosition);
}

路由函数:

private void getRoute(Point origin, Point destination) { // Route creation function
    NavigationRoute.builder()
            .accessToken(Mapbox.getAccessToken())
            .origin(origin)
            .destination(destination)
            .build()
            .getRoute(new Callback<DirectionsResponse>() {
                @Override
                public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                    // Make sure that we got a response
                    if (response.body() == null) { // If there is no response
                        Log.e(TAG, "No routes found, check user and access token");
                        return;
                    }
                    else if (response.body().routes().size() == 0) { // If there is a response but there is no route
                        Log.e(TAG, "No routes found");
                        return;
                    }

                    // Now we have at least 1 route
                    DirectionsRoute currentRoute = response.body().routes().get(0); // Getting the best route

                    if (navigationMapRoute != null) { // If there is already a route, remove it
                        navigationMapRoute.removeRoute();
                    }
                    else { // If there is no route, create one
                        navigationMapRoute = new NavigationMapRoute(null, mapView, map);
                    }

                    navigationMapRoute.addRoute(currentRoute);
                }

                @Override
                public void onFailure(Call<DirectionsResponse> call, Throwable t) {
                    // If route creation is unsuccessful
                    Log.e(TAG, "Error:" + t.getMessage()); // Logging the error message
                }
            });
}

目前,该应用设法将所有标记放在用户的屏幕点击上,但是,路线创建仅发生在最后一个标记和用户的原始位置之间。如何绘制从起始位置开始的优化路线,经过用户放下的每个标记并 returns 回到起始位置?

Current Behavior of the App

编辑:

我试图将所有标记的位置存储在列表中(列表 waypoints)我编辑了我的路线创建和标记加法器函数。以下是更新版本:

标记函数

public void onMapClick(@NonNull LatLng point) {
    // Drop a marker wherever the user taps

    destinationMarker = map.addMarker(new MarkerOptions().position(point));

    destinationPosition = Point.fromLngLat(point.getLongitude(), point.getLatitude());
    originPosition = Point.fromLngLat(originLocation.getLongitude(), originLocation.getLatitude());

    if (waypoints.size() == 0) { // If the list is empty, add the current location
        waypoints.add(originPosition);
    }

    waypoints.add(destinationPosition); // Adding the marker location to the list

    startButton.setEnabled(true);
    startButton.setBackgroundResource(R.color.mapboxBlue);

    routeButton.setEnabled(true);
    routeButton.setBackgroundResource(R.color.mapboxBlue);

    getListRoute(waypoints);
}

路由函数:

private void getListRoute(List<Point> list) {
    for (int i = 0; i < list.size(); i+=2) {
        NavigationRoute.builder()
                .accessToken(Mapbox.getAccessToken())
                .origin(list.get(i))
                .destination(list.get(i+1))
                .build()
                .getRoute(new Callback<DirectionsResponse>() {
                    @Override
                    public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                        // Make sure that we got a response
                        if (response.body() == null) { // If there is no response
                            Log.e(TAG, "No routes found, check user and access token");
                            return;
                        }
                        else if (response.body().routes().size() == 0) { // If there is a response but there is no route
                            Log.e(TAG, "No routes found");
                            return;
                        }

                        // Now we have at least 1 route
                        DirectionsRoute currentRoute = response.body().routes().get(0); // Getting the best route

                        if (navigationMapRoute == null) { // If there is no route, create one
                            navigationMapRoute = new NavigationMapRoute(null, mapView, map);
                        }

                        navigationMapRoute.addRoute(currentRoute);
                    }

                    @Override
                    public void onFailure(Call<DirectionsResponse> call, Throwable t) {
                        // If route creation is unsuccessful
                        Log.e(TAG, "Error:" + t.getMessage()); // Logging the error message
                    }
                });

    }
}

我试图在单击按钮时从列表中获取所有标记位置。然后绘制它们之间的路线(未优化)但是,应用程序的行为没有改变。它仍然在最后两个标记之间绘制路线。

为 David Wasser 编辑 再次感谢您的回答。我通过创建一个变量来保留路由构建器来解决这个问题。这是函数的更新版本: (更改是在代码的前 9 行完成的)

private void getRoute(List<Point> list) {
    NavigationRoute.Builder builder = NavigationRoute.builder()  // Initializing the route builder
            .accessToken(Mapbox.getAccessToken())
            .origin(list.get(0)) // Since we are creating a route with the same start and end points
            .destination(list.get(0)) // Both origin and destination is user's current location
            .profile(DirectionsCriteria.PROFILE_DRIVING); // Default profile allows up to 3 waypoints, thus updating the profile to allow up to 23 waypoints

    for (int i = 1; i < list.size(); i++) { // Adding all the waypoints as pitstops to the route
        builder.addWaypoint(list.get(i));
    }

    builder.build() // Building the route
            .getRoute(new Callback<DirectionsResponse>() {
                @Override
                public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                    // Make sure that we got a response
                    if (response.body() == null) { // If there is no response
                        Log.e(TAG, "No routes found, check user and access token");
                        return;
                    }
                    else if (response.body().routes().size() == 0) { // If there is a response but there is no route
                        Log.e(TAG, "No routes found");
                        return;
                    }

                    // Now we have at least 1 route
                    DirectionsRoute currentRoute = response.body().routes().get(0); // Getting the best route
                    route = currentRoute; // Extracting the route to a variable initialized in MainActivity

                    if (navigationMapRoute != null) { // If there is already a route, remove it
                        navigationMapRoute.removeRoute();
                    }
                    else { // If there is no route, create one
                        navigationMapRoute = new NavigationMapRoute(null, mapView, map);
                    }

                    navigationMapRoute.addRoute(currentRoute);
                }

                @Override
                public void onFailure(Call<DirectionsResponse> call, Throwable t) {
                    // If route creation is unsuccessful
                    Log.e(TAG, "Error:" + t.getMessage()); // Logging the error message
                }
            });
}

我需要的是导航以优化后的路线开始,不知道是不是跟这个有关,如果你按照优化的文档API,你已经有了

您不会循环并多次调用 getRoute()。您应该调用 getRoute() 一次并传递所有分数。您可以像之前那样设置起点和终点(在本例中 destination 应该是列表中的最后一个点)。所有的中间点都是通过调用 addWaypoint().

设置的

如果你想return到起点那么你应该设置destination = origin.