如何在 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
.
我正在尝试使用 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
.