1+ package com .mapbox .services .android .testapp .optimizedtrip ;
2+
3+ import android .animation .ValueAnimator ;
4+ import android .graphics .Color ;
5+ import android .os .Bundle ;
6+ import android .support .v7 .app .AppCompatActivity ;
7+
8+ import com .mapbox .mapboxsdk .Mapbox ;
9+ import com .mapbox .mapboxsdk .annotations .MarkerOptions ;
10+ import com .mapbox .mapboxsdk .camera .CameraUpdateFactory ;
11+ import com .mapbox .mapboxsdk .geometry .LatLng ;
12+ import com .mapbox .mapboxsdk .geometry .LatLngBounds ;
13+ import com .mapbox .mapboxsdk .maps .MapView ;
14+ import com .mapbox .mapboxsdk .maps .MapboxMap ;
15+ import com .mapbox .mapboxsdk .maps .OnMapReadyCallback ;
16+ import com .mapbox .mapboxsdk .style .layers .LineLayer ;
17+ import com .mapbox .mapboxsdk .style .layers .PropertyFactory ;
18+ import com .mapbox .mapboxsdk .style .sources .GeoJsonSource ;
19+ import com .mapbox .services .Constants ;
20+ import com .mapbox .services .android .testapp .R ;
21+ import com .mapbox .services .api .directions .v5 .DirectionsCriteria ;
22+ import com .mapbox .services .api .optimizedtrips .v1 .MapboxOptimizedTrips ;
23+ import com .mapbox .services .api .optimizedtrips .v1 .models .OptimizedTripsResponse ;
24+ import com .mapbox .services .api .utils .turf .TurfConstants ;
25+ import com .mapbox .services .api .utils .turf .TurfMeasurement ;
26+ import com .mapbox .services .api .utils .turf .TurfMisc ;
27+ import com .mapbox .services .commons .geojson .Feature ;
28+ import com .mapbox .services .commons .geojson .FeatureCollection ;
29+ import com .mapbox .services .commons .geojson .LineString ;
30+ import com .mapbox .services .commons .geojson .Point ;
31+ import com .mapbox .services .commons .models .Position ;
32+
33+ import java .util .ArrayList ;
34+ import java .util .List ;
35+
36+ import retrofit2 .Call ;
37+ import retrofit2 .Callback ;
38+ import retrofit2 .Response ;
39+ import timber .log .Timber ;
40+
41+ public class OptimizedTripActivity extends AppCompatActivity implements OnMapReadyCallback {
42+
43+ private static final String LINE_SOURCE = "line-source" ;
44+ private static final String LINE_LAYER = "line-layer" ;
45+
46+ private MapView mapView ;
47+ private MapboxMap mapboxMap ;
48+ private List <MarkerOptions > tripStops ;
49+ private ValueAnimator valueAnimator ;
50+
51+ @ Override
52+ protected void onCreate (Bundle savedInstanceState ) {
53+ super .onCreate (savedInstanceState );
54+ setContentView (R .layout .activity_optimized_trip );
55+
56+ tripStops = new ArrayList <>();
57+ tripStops .add (new MarkerOptions ().position (new LatLng (40.74302 , -73.99322 )));
58+ tripStops .add (new MarkerOptions ().position (new LatLng (40.74451 , -73.97920 )));
59+ tripStops .add (new MarkerOptions ().position (new LatLng (40.75979 , -73.99179 )));
60+ tripStops .add (new MarkerOptions ().position (new LatLng (40.76369 , -73.97144 )));
61+ tripStops .add (new MarkerOptions ().position (new LatLng (40.75906 , -73.98812 )));
62+
63+ mapView = (MapView ) findViewById (R .id .mapView );
64+ mapView .onCreate (savedInstanceState );
65+ mapView .getMapAsync (this );
66+
67+ }
68+
69+ @ Override
70+ public void onMapReady (MapboxMap mapboxMap ) {
71+ this .mapboxMap = mapboxMap ;
72+ mapboxMap .addMarkers (tripStops );
73+
74+ MapboxOptimizedTrips .Builder builder = new MapboxOptimizedTrips .Builder ()
75+ .setAccessToken (Mapbox .getAccessToken ())
76+ .setProfile (DirectionsCriteria .PROFILE_DRIVING )
77+ // .setRoundTrip(false)
78+ .setSource (DirectionsCriteria .SOURCE_FIRST )
79+ // .setDestination(DirectionsCriteria.SOURCE_LAST)
80+ .setOverview (DirectionsCriteria .OVERVIEW_FULL );
81+
82+ List <Position > coords = new ArrayList <>();
83+ LatLngBounds .Builder boundsBuilder = new LatLngBounds .Builder ();
84+ for (MarkerOptions markerOptions : tripStops ) {
85+ coords .add (Position .fromCoordinates (
86+ markerOptions .getPosition ().getLongitude (),
87+ markerOptions .getPosition ().getLatitude ())
88+ );
89+
90+ boundsBuilder .include (markerOptions .getPosition ());
91+ }
92+
93+ mapboxMap .moveCamera (CameraUpdateFactory .newLatLngBounds (boundsBuilder .build (), 150 ));
94+
95+ MapboxOptimizedTrips client = builder .setCoordinates (coords ).build ();
96+ client .enqueueCall (new Callback <OptimizedTripsResponse >() {
97+ @ Override
98+ public void onResponse (Call <OptimizedTripsResponse > call , Response <OptimizedTripsResponse > response ) {
99+ Timber .v ("Call Url: %s" , call .request ().url ().toString ());
100+
101+ drawLine (response .body ().getTrips ().get (0 ).getGeometry ());
102+ }
103+
104+ @ Override
105+ public void onFailure (Call <OptimizedTripsResponse > call , Throwable throwable ) {
106+ Timber .e ("Calling optimize trips failed: " , throwable );
107+ }
108+ });
109+ }
110+
111+ private void drawLine (String geometry ) {
112+
113+ LineString linestring = LineString .fromPolyline (geometry , Constants .PRECISION_6 );
114+ FeatureCollection featureCollection
115+ = FeatureCollection .fromFeatures (new Feature [] {Feature .fromGeometry (linestring )});
116+
117+ GeoJsonSource source = new GeoJsonSource (LINE_SOURCE , featureCollection );
118+ mapboxMap .addSource (source );
119+
120+ LineLayer layer = new LineLayer (LINE_LAYER , LINE_SOURCE ).withProperties (
121+ PropertyFactory .lineWidth (5f ),
122+ PropertyFactory .lineColor (Color .parseColor ("#009DF9" ))
123+ );
124+
125+ mapboxMap .addLayerBelow (layer , "poi-parks-scalerank2" );
126+
127+ startAnimation (
128+ Position .fromCoordinates (
129+ tripStops .get (0 ).getPosition ().getLongitude (),
130+ tripStops .get (0 ).getPosition ().getLatitude ()),
131+ linestring );
132+
133+ }
134+
135+ private void startAnimation (final Position startPosition , final LineString route ) {
136+
137+ final double routeDistance = TurfMeasurement .lineDistance (route , TurfConstants .UNIT_METERS );
138+
139+ valueAnimator = ValueAnimator .ofFloat (0 , 1 );
140+ valueAnimator .setDuration (30000 );
141+ valueAnimator .addUpdateListener (new ValueAnimator .AnimatorUpdateListener () {
142+ @ Override
143+ public void onAnimationUpdate (ValueAnimator animation ) {
144+ Point currentPoint = TurfMeasurement .along (
145+ route ,
146+ routeDistance * (double ) animation .getAnimatedFraction (),
147+ TurfConstants .UNIT_METERS
148+ );
149+ LineString newLine = TurfMisc .lineSlice (Point .fromCoordinates (startPosition ), currentPoint , route );
150+
151+ GeoJsonSource source = mapboxMap .getSourceAs (LINE_SOURCE );
152+ if (source != null ) {
153+ FeatureCollection newRouteFeature
154+ = FeatureCollection .fromFeatures (new Feature [] {Feature .fromGeometry (newLine )});
155+ source .setGeoJson (newRouteFeature );
156+
157+ }
158+ }
159+ });
160+ valueAnimator .start ();
161+ }
162+
163+ @ Override
164+ public void onResume () {
165+ super .onResume ();
166+ mapView .onResume ();
167+ }
168+
169+ @ Override
170+ protected void onStart () {
171+ super .onStart ();
172+ mapView .onStart ();
173+ }
174+
175+ @ Override
176+ protected void onStop () {
177+ super .onStop ();
178+ mapView .onStop ();
179+ if (valueAnimator != null ) {
180+ valueAnimator .removeAllUpdateListeners ();
181+ }
182+ }
183+
184+ @ Override
185+ public void onPause () {
186+ super .onPause ();
187+ mapView .onPause ();
188+ }
189+
190+ @ Override
191+ public void onLowMemory () {
192+ super .onLowMemory ();
193+ mapView .onLowMemory ();
194+ }
195+
196+ @ Override
197+ protected void onDestroy () {
198+ super .onDestroy ();
199+ mapView .onDestroy ();
200+ }
201+
202+ @ Override
203+ protected void onSaveInstanceState (Bundle outState ) {
204+ super .onSaveInstanceState (outState );
205+ mapView .onSaveInstanceState (outState );
206+ }
207+ }
0 commit comments