Skip to content

Commit 3d3ff75

Browse files
authored
Map matching v5 (#310)
* update testing fixtures * update rx bindings to map matching v5 * update rx bindings tests to map matching v5 * update and simplify MapMatchingActivity to support v5 * include new models for v5 * reformat fixture for easier reading * update tests to v5 * delete v5 and update client to v5 * remove unused import
1 parent 455d795 commit 3d3ff75

25 files changed

Lines changed: 1072 additions & 1080 deletions

File tree

Makefile

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Used for Map Matching
2+
MAP_MATCHING_COORDINATES = 13.418946862220764,52.50055852688439;13.419011235237122,52.50113000479732;13.419756889343262,52.50171780290061;13.419885635375975,52.50237416816131;13.420631289482117,52.50294888790448
3+
14
checkstyle:
25
cd mapbox; ./gradlew checkstyle
36

@@ -88,16 +91,9 @@ directions-traffic-fixtures:
8891
-o mapbox/libjava-services/src/test/fixtures/directions_v5_traffic.json
8992

9093
mapmatching-fixtures:
91-
# Geometry polyline
92-
curl -X POST --header "Content-Type:application/json" -d @mapbox/libjava-services/src/test/fixtures/mapmatching_trace.json \
93-
"https://api.mapbox.com/matching/v4/mapbox.driving.json?geometry=polyline&access_token=$(MAPBOX_ACCESS_TOKEN)" \
94+
curl "https://api.mapbox.com/matching/v5/mapbox/driving/$(MAP_MATCHING_COORDINATES)?geometries=polyline&access_token=$(MAPBOX_ACCESS_TOKEN)" \
9495
-o mapbox/libjava-services/src/test/fixtures/mapmatching_v5_polyline.json
9596

96-
# No geometry
97-
curl -X POST --header "Content-Type:application/json" -d @mapbox/libjava-services/src/test/fixtures/mapmatching_trace.json \
98-
"https://api.mapbox.com/matching/v4/mapbox.driving.json?geometry=false&access_token=$(MAPBOX_ACCESS_TOKEN)" \
99-
-o mapbox/libjava-services/src/test/fixtures/mapmatching_v5_no_geometry.json
100-
10197
distance-fixtures:
10298
# Retrieve a duration matrix
10399
curl -X POST --header "Content-Type:application/json" -d @mapbox/libjava-services/src/test/fixtures/distance_coordinates.json \

mapbox/app/src/main/java/com/mapbox/services/android/testapp/utils/MapMatchingActivity.java

Lines changed: 19 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,25 @@
55
import android.os.Bundle;
66
import android.support.v7.app.AppCompatActivity;
77
import android.support.v7.widget.Toolbar;
8-
import android.text.TextUtils;
98
import android.util.Log;
10-
import android.widget.SeekBar;
11-
import android.widget.TextView;
129

1310
import com.mapbox.mapboxsdk.annotations.Polyline;
1411
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
1512
import com.mapbox.mapboxsdk.geometry.LatLng;
1613
import com.mapbox.mapboxsdk.maps.MapView;
1714
import com.mapbox.mapboxsdk.maps.MapboxMap;
1815
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
16+
import com.mapbox.services.Constants;
1917
import com.mapbox.services.android.testapp.R;
2018
import com.mapbox.services.android.testapp.Utils;
2119
import com.mapbox.services.api.ServicesException;
20+
import com.mapbox.services.api.mapmatching.v5.MapMatchingCriteria;
21+
import com.mapbox.services.api.mapmatching.v5.MapboxMapMatching;
22+
import com.mapbox.services.api.mapmatching.v5.models.MapMatchingResponse;
23+
import com.mapbox.services.commons.geojson.FeatureCollection;
2224
import com.mapbox.services.commons.geojson.LineString;
2325
import com.mapbox.services.commons.models.Position;
24-
import com.mapbox.services.api.mapmatching.v4.MapMatchingCriteria;
25-
import com.mapbox.services.api.mapmatching.v4.MapboxMapMatching;
26-
import com.mapbox.services.api.mapmatching.v4.models.MapMatchingResponse;
27-
28-
import org.json.JSONArray;
29-
import org.json.JSONObject;
26+
import com.mapbox.services.commons.utils.PolylineUtils;
3027

3128
import java.io.BufferedReader;
3229
import java.io.InputStream;
@@ -45,7 +42,6 @@ public class MapMatchingActivity extends AppCompatActivity {
4542

4643
private MapView mapView;
4744
private MapboxMap map;
48-
private LineString lineString;
4945
private Polyline mapMatchedRoute;
5046

5147
@Override
@@ -58,42 +54,13 @@ protected void onCreate(Bundle savedInstanceState) {
5854

5955
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
6056

61-
final SeekBar precisionSeekBar = (SeekBar) findViewById(R.id.seekbar_precision);
62-
final TextView precisionTextView = (TextView) findViewById(R.id.precision_value);
63-
if (precisionSeekBar != null) {
64-
precisionSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
65-
@Override
66-
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
67-
if (lineString != null) {
68-
if (precisionTextView != null) {
69-
precisionTextView.setText(String.valueOf(progress));
70-
}
71-
drawMapMatched(lineString, progress);
72-
}
73-
}
74-
75-
@Override
76-
public void onStartTrackingTouch(SeekBar seekBar) {
77-
78-
}
79-
80-
@Override
81-
public void onStopTrackingTouch(SeekBar seekBar) {
82-
83-
}
84-
});
85-
}
86-
8757
mapView = (MapView) findViewById(R.id.mapView);
8858
mapView.onCreate(savedInstanceState);
8959
mapView.getMapAsync(new OnMapReadyCallback() {
9060
@Override
9161
public void onMapReady(MapboxMap mapboxMap) {
92-
9362
map = mapboxMap;
94-
9563
new DrawGeoJson().execute();
96-
9764
}
9865
});
9966
}
@@ -157,27 +124,9 @@ protected List<Position> doInBackground(Void... voids) {
157124
}
158125

159126
inputStream.close();
160-
161-
// Parse JSON
162-
JSONObject json = new JSONObject(sb.toString());
163-
JSONArray features = json.getJSONArray("features");
164-
JSONObject feature = features.getJSONObject(0);
165-
JSONObject geometry = feature.getJSONObject("geometry");
166-
if (geometry != null) {
167-
String type = geometry.getString("type");
168-
169-
// Our GeoJSON only has one feature: a line string
170-
if (!TextUtils.isEmpty(type) && type.equalsIgnoreCase("LineString")) {
171-
172-
// Get the Coordinates
173-
JSONArray coords = geometry.getJSONArray("coordinates");
174-
for (int lc = 0; lc < coords.length(); lc++) {
175-
JSONArray coord = coords.getJSONArray(lc);
176-
Position position = Position.fromCoordinates(coord.getDouble(0), coord.getDouble(1));
177-
points.add(position);
178-
}
179-
}
180-
}
127+
FeatureCollection featureCollection = FeatureCollection.fromJson(sb.toString());
128+
LineString lineString = (LineString) featureCollection.getFeatures().get(0).getGeometry();
129+
points = lineString.getCoordinates();
181130
} catch (Exception exception) {
182131
Log.e(TAG, "Exception Loading GeoJSON: " + exception.toString());
183132
}
@@ -188,18 +137,14 @@ protected List<Position> doInBackground(Void... voids) {
188137
@Override
189138
protected void onPostExecute(List<Position> points) {
190139
super.onPostExecute(points);
191-
192140
drawBeforeMapMatching(points);
193141

194-
// Convert the route to a linestring
195-
lineString = LineString.fromCoordinates(points);
196-
drawMapMatched(lineString, 8);
197-
142+
Position[] coordinates = new Position[points.size()];
143+
drawMapMatched(points.toArray(coordinates));
198144
}
199145
}
200146

201147
private void drawBeforeMapMatching(List<Position> points) {
202-
203148
LatLng[] pointsArray = new LatLng[points.size()];
204149
for (int i = 0; i < points.size(); i++) {
205150
pointsArray[i] = new LatLng(points.get(i).getLatitude(), points.get(i).getLongitude());
@@ -212,36 +157,35 @@ private void drawBeforeMapMatching(List<Position> points) {
212157
.width(4));
213158
}
214159

215-
private void drawMapMatched(LineString lineString, int precision) {
160+
private void drawMapMatched(Position[] coordinates) {
216161
try {
217162
// Setup the request using a client.
218163
MapboxMapMatching client = new MapboxMapMatching.Builder()
219164
.setAccessToken(Utils.getMapboxAccessToken(MapMatchingActivity.this))
220165
.setProfile(MapMatchingCriteria.PROFILE_DRIVING)
221-
.setGpsPrecison(precision)
222-
.setTrace(lineString)
166+
.setCoordinates(coordinates)
223167
.build();
224168

225169
// Execute the API call and handle the response.
226170
client.enqueueCall(new Callback<MapMatchingResponse>() {
227171
@Override
228172
public void onResponse(Call<MapMatchingResponse> call, Response<MapMatchingResponse> response) {
229-
230173
// Create a new list to store the map matched coordinates.
231174
List<LatLng> mapMatchedPoints = new ArrayList<>();
232175

233176
// Check that the map matching API response is "OK".
234177
if (response.code() == 200) {
235178
// Convert the map matched response list from position to latlng coordinates.
236-
Position[] positions = response.body().getMatchedPoints();
179+
String geometry = response.body().getMatchings().get(0).getGeometry();
180+
List<Position> positions = PolylineUtils.decode(geometry, Constants.OSRM_PRECISION_V4);
237181
if (positions == null) {
238182
return;
239183
}
240184

241-
for (int i = 0; i < positions.length; i++) {
185+
for (int i = 0; i < positions.size(); i++) {
242186
mapMatchedPoints.add(new LatLng(
243-
positions[i].getLatitude(),
244-
positions[i].getLongitude()));
187+
positions.get(i).getLatitude(),
188+
positions.get(i).getLongitude()));
245189
}
246190

247191
if (mapMatchedRoute != null) {
@@ -255,7 +199,7 @@ public void onResponse(Call<MapMatchingResponse> call, Response<MapMatchingRespo
255199
.width(4));
256200
} else {
257201
// If the response code does not response "OK" an error has occurred.
258-
Log.e(TAG, "Too many coordinates, Profile not found, invalid input, or no match");
202+
Log.e(TAG, "Too many coordinates, profile not found, invalid input, or no match.");
259203
}
260204
}
261205

mapbox/app/src/main/res/layout/activity_utils_map_matching.xml

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,6 @@
2020
android:background="?attr/colorPrimary"
2121
app:popupTheme="@style/AppTheme.PopupOverlay"/>
2222

23-
<LinearLayout
24-
android:id="@+id/seekbar_container"
25-
android:layout_width="match_parent"
26-
android:layout_height="wrap_content"
27-
android:orientation="horizontal">
28-
29-
<TextView
30-
android:id="@+id/precision_value"
31-
android:layout_width="wrap_content"
32-
android:layout_height="wrap_content"
33-
android:padding="8dp"
34-
android:text="8"/>
35-
36-
<SeekBar
37-
android:id="@+id/seekbar_precision"
38-
android:layout_width="match_parent"
39-
android:layout_height="wrap_content"
40-
android:max="10"
41-
android:paddingBottom="10dp"
42-
android:paddingTop="10dp"
43-
android:progress="8"/>
44-
45-
</LinearLayout>
46-
4723
</android.support.design.widget.AppBarLayout>
4824

4925
<com.mapbox.mapboxsdk.maps.MapView

mapbox/libjava-services-rx/src/main/java/com/mapbox/services/api/rx/mapmatching/v4/MapMatchingServiceRx.java

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.mapbox.services.api.rx.mapmatching.v5;
2+
3+
import com.mapbox.services.api.mapmatching.v5.models.MapMatchingResponse;
4+
5+
import retrofit2.http.GET;
6+
import retrofit2.http.Header;
7+
import retrofit2.http.Path;
8+
import retrofit2.http.Query;
9+
import rx.Observable;
10+
11+
/**
12+
* Interface that defines the map matching service.
13+
*
14+
* @since 2.0.0
15+
*/
16+
public interface MapMatchingServiceRx {
17+
/**
18+
* Observable-based interface
19+
*
20+
* @param userAgent User agent
21+
* @param user User
22+
* @param profile Directions profile ID; either mapbox/driving, mapbox/walking,
23+
* or mapbox/cycling
24+
* @param coordinates Inaccurate traces from a GPS unit or a phone
25+
* @param accessToken Mapbox access token
26+
* @param geometries Format of the returned geometry. Allowed values are: geojson
27+
* (as LineString), polyline with precision 5, polyline6. The default
28+
* value is polyline .
29+
* @param radiuses A list of integers in meters indicating the assumed precision of
30+
* the used tracking device. There must be as many radiuses as there
31+
* are coordinates in the request, each separated by ;. Values can be
32+
* a number between 0 and 30. Use higher numbers (20-30) for noisy
33+
* traces and lower numbers (1-10) for clean traces. The default value
34+
* is 5.
35+
* @param steps Whether to return steps and turn-by-turn instructions. Can be true
36+
* or false. The default is false.
37+
* @param overview Type of returned overview geometry. Can be full (the most detailed
38+
* geometry available), simplified (a simplified version of the full
39+
* geometry), or false (no overview geometry). The default is simplified.
40+
* @param timestamps Timestamps corresponding to each coordinate provided in the request;
41+
* must be numbers in Unix time (seconds since the Unix epoch). There
42+
* must be as many timestamps as there are coordinates in the request,
43+
* each separated by ;.
44+
* @param annotations Whether or not to return additional metadata for each coordinate
45+
* along the match geometry. Can be one or all of 'duration', 'distance',
46+
* or 'nodes', each separated by ,. See the response object for more
47+
* details on what it is included with annotations.
48+
* @return The MapMatchingResponse in an Observable wrapper
49+
* @since 2.0.0
50+
*/
51+
@GET("matching/v5/{user}/{profile}/{coordinates}")
52+
Observable<MapMatchingResponse> getObservable(
53+
@Header("User-Agent") String userAgent,
54+
@Path("user") String user,
55+
@Path("profile") String profile,
56+
@Path("coordinates") String coordinates,
57+
@Query("access_token") String accessToken,
58+
@Query("geometries") String geometries,
59+
@Query("radiuses") String radiuses,
60+
@Query("steps") Boolean steps,
61+
@Query("overview") String overview,
62+
@Query("timestamps") String timestamps,
63+
@Query("annotations") String annotations);
64+
}

mapbox/libjava-services-rx/src/main/java/com/mapbox/services/api/rx/mapmatching/v4/MapboxMapMatchingRx.java renamed to mapbox/libjava-services-rx/src/main/java/com/mapbox/services/api/rx/mapmatching/v5/MapboxMapMatchingRx.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
package com.mapbox.services.api.rx.mapmatching.v4;
1+
package com.mapbox.services.api.rx.mapmatching.v5;
22

33
import com.mapbox.services.api.ServicesException;
4-
import com.mapbox.services.api.mapmatching.v4.MapboxMapMatching;
5-
import com.mapbox.services.api.mapmatching.v4.models.MapMatchingResponse;
4+
import com.mapbox.services.api.mapmatching.v5.MapboxMapMatching;
5+
import com.mapbox.services.api.mapmatching.v5.models.MapMatchingResponse;
66

77
import retrofit2.Retrofit;
88
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
@@ -41,7 +41,7 @@ private MapMatchingServiceRx getServiceRx() {
4141
.client(getOkHttpClient())
4242
.baseUrl(builder.getBaseUrl())
4343
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
44-
.addConverterFactory(GsonConverterFactory.create(getGson()))
44+
.addConverterFactory(GsonConverterFactory.create())
4545
.build();
4646

4747
// MapMatching service
@@ -57,11 +57,16 @@ public Observable<MapMatchingResponse> getObservable() {
5757

5858
observable = getServiceRx().getObservable(
5959
getHeaderUserAgent(builder.getClientAppName()),
60+
builder.getUser(),
6061
builder.getProfile(),
62+
builder.getCoordinates(),
6163
builder.getAccessToken(),
62-
builder.getGeometry(),
63-
builder.getGpsPrecison(),
64-
builder.getTrace()
64+
builder.getGeometries(),
65+
builder.getRadiuses(),
66+
builder.getSteps(),
67+
builder.getOverview(),
68+
builder.getTimestamps(),
69+
builder.getAnnotations()
6570
);
6671

6772
// Done

0 commit comments

Comments
 (0)