Здравствуйте, я создаю приложение для навигации, используя Mapbox, в котором, если пользователь перемещает объект, и линия будет двигаться вместе. Прямо сейчас я передаю статический лат в длину, и я сослался на https://docs.mapbox.com/android/maps/examples/moving-icon-with-trailing-line/ для анимации, но ничего не работает. Приложение работает должным образом. но полилиния не создает. Проверьте ниже, я вставляю код, который я пробовал до сих пор
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="StartNavigactionBtnClick"
android:text="Start Navigation">
</Button>
<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/Mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/btn_start">
</com.mapbox.mapboxsdk.maps.MapView>
</RelativeLayout>
MainActivity.java
public class test2 extends AppCompatActivity implements PermissionsListener,MapboxMap.OnMapClickListener,OnMapReadyCallback{
private static final String DOT_SOURCE_ID = "dot-source-id";
private static final String LINE_SOURCE_ID = "line-source-id";
private GeoJsonSource pointSource;
private GeoJsonSource lineSource;
private List<Point> routeCoordinateList;
private List<Point> markerLinePointList = new ArrayList<>();
private int routeIndex;
private Animator currentAnimator;
private MapView mapView;
private MapboxMap mapboxMap;
LocationComponent locationComponent;
PermissionsManager permissionsManager;
DirectionsRoute currentRoute;
NavigationMapRoute navigationMapRoute;
Button start;
private Point originPoint = Point.fromLngLat(38.7508, 9.0309);
private Point destinationPpoint = Point.fromLngLat(38.795902, 8.984467);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
start = findViewById(R.id.btn_start);
getSupportActionBar().setTitle("Navegação");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mapView = findViewById(R.id.Mapview);
//mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
start.setEnabled(false);
// mapView.getMapAsync(new OnMapReadyCallback() {
// @Override
// public void onMapReady(MapboxMap mapboxMap) {
// test2.this.mapboxMap = mapboxMap;
// mapboxMap.setStyle(Style.LIGHT, new Style.OnStyleLoaded() {
// @Override
// public void onStyleLoaded(@NonNull Style style) {
//// Use the Mapbox Directions API to get a directions route
// getRoute(originPoint, destinationPpoint);
//
// }
// });
// }
// });
getRoute(originPoint, destinationPpoint);
}
public void StartNavigactionBtnClick(View view) {
boolean simulateRoute = true;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute).build();
NavigationLauncher.startNavigation(test2.this, options);
}
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
this.mapboxMap.setMinZoomPreference(15);
mapboxMap.setStyle(getString(R.string.navigation_guidance_day), new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
enableLocationComponent(style);
addDestinationIconSymbolLayer(style);
mapboxMap.addOnMapClickListener(test2.this);
}
});
}
private void addDestinationIconSymbolLayer(@NonNull Style loadedMapStyle) {
loadedMapStyle.addImage("destination-icon-id",
BitmapFactory.decodeResource(this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("destination-source-id");
loadedMapStyle.addSource(geoJsonSource);
SymbolLayer destinationSymbolLayer = new SymbolLayer("destination-symbol-layer-id", "destination-source-id");
destinationSymbolLayer.withProperties(
iconImage("destination-icon-id"),
iconAllowOverlap(true),
iconIgnorePlacement(true)
);
loadedMapStyle.addLayer(destinationSymbolLayer);
}
@SuppressWarnings({"MissingPermission"})
@Override
public boolean onMapClick(@NonNull LatLng point) {
// Point destinationPoint = Point.fromLngLat(point.getLongitude(), point.getLatitude());
// Point originPoint = Point.fromLngLat(locationComponent.getLastKnownLocation().getLongitude(),
// locationComponent.getLastKnownLocation().getLatitude());
//
// GeoJsonSource source = mapboxMap.getStyle().getSourceAs("destination-source-id");
// if (source != null) {
// source.setGeoJson(Feature.fromGeometry(destinationPpoint));
// }
//getRoute(originPoint, destinationPoint);
//start.setEnabled(true);
return true;
}
private void getRoute(Point origin, Point destination) {
NavigationRoute.builder(this).accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
if (response.body() != null && response.body().routes().size() > 0) {
currentRoute = response.body().routes().get(0);
if (navigationMapRoute != null) {
navigationMapRoute.removeRoute();
} else {
navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap, R.style.NavigationLocationLayerStyle);
}
if (currentRoute != null) {
navigationMapRoute.addRoute(currentRoute);
}
}
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(
new LatLngBounds.Builder()
.include(new LatLng(origin.latitude(), origin.longitude()))
.include(new LatLng(destination.latitude(), destination.longitude()))
.build(), 50), 5000);
initData(style, FeatureCollection.fromFeature(
Feature.fromGeometry(LineString.fromPolyline(currentRoute.geometry(), PRECISION_6))));
}
});
}
@Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
// MapboxDirections client = MapboxDirections.builder()
// .origin(origin)
// .destination(destination)
// .profile(DirectionsCriteria.PROFILE_WALKING)
// .accessToken(getString(R.string.access_token))
// .build();
//
// client.enqueueCall(new Callback<DirectionsResponse>() {
// @Override
// public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// System.out.println(call.request().url().toString());
//
//// You can get the generic HTTP info about the response
// Timber.d("Response code: %s", response.code());
// if (response.body() == null) {
// Timber.e("No routes found, make sure you set the right user and access token.");
// return;
// } else if (response.body().routes().size() < 1) {
// Timber.e("No routes found");
// return;
// }
//
//// Get the directions route
// DirectionsRoute currentRoute = response.body().routes().get(0);
// mapboxMap.getStyle(new Style.OnStyleLoaded() {
// @Override
// public void onStyleLoaded(@NonNull Style style) {
//
// style.removeLayer("symbol-layer-id");
// style.removeLayer("line-layer-id");
//// Layer layerAs = style.getLayerAs("line-layer-id");
////
//// assert layerAs != null;
////
//// if (layerAs.getId().isEmpty()){
////
//// }else {
//// style.removeLayer("line-layer-id");
//// }
//
// mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(
// new LatLngBounds.Builder()
// .include(new LatLng(origin.latitude(), origin.longitude()))
// .include(new LatLng(destination.latitude(), destination.longitude()))
// .build(), 50), 5000);
//
// initData(style, FeatureCollection.fromFeature(
// Feature.fromGeometry(LineString.fromPolyline(currentRoute.geometry(), PRECISION_6))));
//
//
// }
// });
// }
//
// @Override
// public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
// Timber.e("Error: %s", throwable.getMessage());
// Toast.makeText(test2.this, "Error: " + throwable.getMessage(),
// Toast.LENGTH_SHORT).show();
// }
// });
start.setEnabled(true);
}
@SuppressWarnings({"MissingPermission"})
private void enableLocationComponent(@NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Activate the MapboxMap LocationComponent to show user location
// Adding in LocationComponentOptions is also an optional parameter
locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(this, loadedMapStyle);
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
private void initData(Style fullyLoadedStyle, @NonNull FeatureCollection featureCollection) {
if (featureCollection.features() != null) {
LineString lineString = ((LineString) featureCollection.features().get(0).geometry());
if (lineString != null) {
routeCoordinateList = lineString.coordinates();
initSources(fullyLoadedStyle, featureCollection);
initSymbolLayer(fullyLoadedStyle);
initDotLinePath(fullyLoadedStyle);
animate();
}
}
}
private void animate() {
// Check if we are at the end of the points list
if ((routeCoordinateList.size() - 1 > routeIndex)) {
Point indexPoint = routeCoordinateList.get(routeIndex);
Point newPoint = Point.fromLngLat(indexPoint.longitude(), indexPoint.latitude());
currentAnimator = createLatLngAnimator(indexPoint, newPoint);
currentAnimator.start();
routeIndex++;
}
}
private static class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
return Point.fromLngLat(
startValue.longitude() + ((endValue.longitude() - startValue.longitude()) * fraction),
startValue.latitude() + ((endValue.latitude() - startValue.latitude()) * fraction)
);
}
}
private Animator createLatLngAnimator(Point currentPosition, Point targetPosition) {
ValueAnimator latLngAnimator = ValueAnimator.ofObject(new PointEvaluator(), currentPosition, targetPosition);
latLngAnimator.setDuration((long) TurfMeasurement.distance(currentPosition, targetPosition, "meters"));
latLngAnimator.setInterpolator(new LinearInterpolator());
latLngAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animate();
}
});
latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Point point = (Point) animation.getAnimatedValue();
pointSource.setGeoJson(point);
markerLinePointList.add(point);
lineSource.setGeoJson(Feature.fromGeometry(LineString.fromLngLats(markerLinePointList)));
}
});
return latLngAnimator;
}
private void initSources(@NonNull Style loadedMapStyle, @NonNull FeatureCollection featureCollection) {
// if (layerAs.getId().equals("line-layer-id")) {
// loadedMapStyle.removeLayer("line-layer-id");
// }
if (pointSource==null) {
loadedMapStyle.addSource(pointSource = new GeoJsonSource(DOT_SOURCE_ID, featureCollection));
}
if (lineSource==null) {
loadedMapStyle.addSource(lineSource = new GeoJsonSource(LINE_SOURCE_ID));
}
}
private void initSymbolLayer(@NonNull Style loadedMapStyle) {
loadedMapStyle.addImage("moving-red-marker", BitmapFactory.decodeResource(
getResources(), R.drawable.mapbox_marker_icon_default));
loadedMapStyle.addLayer(new SymbolLayer("symbol-layer-id", DOT_SOURCE_ID).withProperties(
iconImage("moving-red-marker"),
iconSize(1f),
iconOffset(new Float[] {5f, 0f}),
iconIgnorePlacement(true),
iconAllowOverlap(true)
));
}
private void initDotLinePath(@NonNull Style loadedMapStyle) {
loadedMapStyle.addLayerBelow(new LineLayer("line-layer-id", LINE_SOURCE_ID).withProperties(
lineColor(Color.parseColor("#F13C6E")),
lineCap(Property.LINE_CAP_ROUND),
lineJoin(Property.LINE_JOIN_ROUND),
lineWidth(4f)), "road-label");
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
}
@Override
public void onPermissionResult(boolean granted) {
if (granted) {
enableLocationComponent(mapboxMap.getStyle());
} else {
Toast.makeText(getApplicationContext(), "Permission not granted", Toast.LENGTH_SHORT).show();
finish();
}
}
@Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}