Skip to content
This repository was archived by the owner on Oct 7, 2024. It is now read-only.

Commit 4be4ff9

Browse files
committed
refactored MatrixApiActivity and XML
1 parent e5c1b7b commit 4be4ff9

File tree

3 files changed

+92
-67
lines changed

3 files changed

+92
-67
lines changed

MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/javaservices/MatrixApiActivity.java

Lines changed: 90 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mapbox.mapboxandroiddemo.examples.javaservices;
22

33
import android.content.Context;
4+
import android.graphics.BitmapFactory;
45
import android.os.Bundle;
56
import androidx.annotation.NonNull;
67
import androidx.appcompat.app.AppCompatActivity;
@@ -33,6 +34,8 @@
3334
import com.mapbox.mapboxsdk.maps.MapboxMap;
3435
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
3536
import com.mapbox.mapboxsdk.maps.Style;
37+
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
38+
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
3639
import com.mapbox.turf.TurfConversion;
3740

3841
import java.io.InputStream;
@@ -46,19 +49,26 @@
4649
import retrofit2.Response;
4750
import timber.log.Timber;
4851

52+
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
53+
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
54+
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
55+
4956

5057
/**
51-
* Use the Mapbox Java Services SDK's Matrix API to retrieve travel times between many points.
58+
* Use the Mapbox Java SDK's Matrix API to retrieve travel times between many points.
5259
*/
53-
public class MatrixApiActivity extends AppCompatActivity {
60+
public class MatrixApiActivity extends AppCompatActivity implements MapboxMap.OnMapClickListener {
5461

62+
private static final String ICON_ID = "ICON_ID";
63+
private static final String STATION_NAME_PROPERTY = "Station_Name";
64+
private static final String SOURCE_ID = "SOURCE_ID";
65+
private static final String LAYER_ID = "LAYER_ID";
66+
private List<Point> pointList;
67+
private List<SingleRecyclerViewMatrixLocation> matrixLocationList;
5568
private MapView mapView;
5669
private MapboxMap mapboxMap;
57-
private List<Point> pointList;
5870
private FeatureCollection featureCollection;
59-
private RecyclerView recyclerView;
6071
private MatrixApiLocationRecyclerViewAdapter matrixApiLocationRecyclerViewAdapter;
61-
private ArrayList<SingleRecyclerViewMatrixLocation> matrixLocationList;
6272

6373
@Override
6474
protected void onCreate(Bundle savedInstanceState) {
@@ -71,10 +81,8 @@ protected void onCreate(Bundle savedInstanceState) {
7181
// This contains the MapView in XML and needs to be called after the access token is configured.
7282
setContentView(R.layout.activity_matrix_api);
7383

74-
recyclerView = findViewById(R.id.matrix_api_recyclerview);
75-
76-
// Create list of positions from local GeoJSON file
77-
initPositionListFromGeoJsonFile();
84+
// Create a FeatureCollection via local GeoJSON file
85+
initFeatureCollection();
7886

7987
mapView = findViewById(R.id.mapView);
8088
mapView.onCreate(savedInstanceState);
@@ -83,29 +91,33 @@ protected void onCreate(Bundle savedInstanceState) {
8391
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
8492
MatrixApiActivity.this.mapboxMap = mapboxMap;
8593

86-
mapboxMap.setStyle(new Style.Builder().fromUri("mapbox://styles/mapbox/cj8gg22et19ot2rnz65958fkn"),
94+
mapboxMap.setStyle(new Style.Builder().fromUri("mapbox://styles/mapbox/cj8gg22et19ot2rnz65958fkn")
95+
// Add the SymbolLayer icon image to the map style
96+
.withImage(ICON_ID, BitmapFactory.decodeResource(
97+
MatrixApiActivity.this.getResources(), R.drawable.lightning_bolt))
98+
99+
// Adding a GeoJson source for the SymbolLayer icons.
100+
.withSource(new GeoJsonSource(SOURCE_ID, featureCollection))
101+
102+
// Adding the actual SymbolLayer to the map style.
103+
.withLayer(new SymbolLayer(LAYER_ID, SOURCE_ID)
104+
.withProperties(
105+
iconImage(ICON_ID),
106+
iconAllowOverlap(true),
107+
iconIgnorePlacement(true))
108+
),
87109
new Style.OnStyleLoaded() {
88110
@Override
89111
public void onStyleLoaded(@NonNull Style style) {
90-
// Add markers to the map
91-
addMarkers();
92112

93113
// Set up list of locations to pass to the recyclerview
94114
initMatrixLocationListForRecyclerView();
95115

96116
// Set up the recyclerview of charging station cards
97117
initRecyclerView();
98118

99-
mapboxMap.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() {
100-
@Override
101-
public boolean onMarkerClick(@NonNull Marker marker) {
119+
mapboxMap.addOnMapClickListener(MatrixApiActivity.this);
102120

103-
// Make a call to the Mapbox Matrix API
104-
makeMapboxMatrixApiCall(getClickedMarkerNumInPositionList(marker), Point.fromLngLat(
105-
marker.getPosition().getLongitude(), marker.getPosition().getLatitude()));
106-
return false;
107-
}
108-
});
109121
Toast.makeText(MatrixApiActivity.this, R.string.click_on_marker_instruction_toast,
110122
Toast.LENGTH_SHORT).show();
111123
}
@@ -114,23 +126,51 @@ public boolean onMarkerClick(@NonNull Marker marker) {
114126
});
115127
}
116128

117-
private int getClickedMarkerNumInPositionList(Marker clickedMarker) {
118-
int clickedMarkerIndexPositionInList = -1;
119-
if (clickedMarker != null) {
120-
for (Marker singleMarker : mapboxMap.getMarkers()) {
121-
if (singleMarker == clickedMarker) {
122-
clickedMarkerIndexPositionInList = mapboxMap.getMarkers().indexOf(singleMarker);
129+
@Override
130+
public boolean onMapClick(@NonNull LatLng point) {
131+
List<Feature> renderedStationFeatures = mapboxMap.queryRenderedFeatures(
132+
mapboxMap.getProjection().toScreenLocation(point), LAYER_ID);
133+
if (!renderedStationFeatures.isEmpty()) {
134+
Point pointOfSelectedStation = (Point) renderedStationFeatures.get(0).geometry();
135+
if (pointOfSelectedStation != null) {
136+
String selectedBoltFeatureName = renderedStationFeatures.get(0).getStringProperty(STATION_NAME_PROPERTY);
137+
List<Feature> featureList = featureCollection.features();
138+
for (int i = 0; i < featureList.size(); i++) {
139+
if (featureList.get(i).getStringProperty(STATION_NAME_PROPERTY).equals(selectedBoltFeatureName)) {
140+
makeMapboxMatrixApiCall(i);
141+
}
123142
}
124143
}
125-
return clickedMarkerIndexPositionInList;
126-
} else {
127-
return 0;
128144
}
145+
return true;
129146
}
130147

148+
/**
149+
* Create a {@link FeatureCollection} from a locally stored asset file.
150+
*/
151+
private void initFeatureCollection() {
152+
// Get GeoJSON features from GeoJSON file in the assets folder
153+
featureCollection = FeatureCollection.fromJson(loadGeoJsonFromAsset("boston_charge_stations.geojson"));
154+
155+
// Initialize List<Position> for eventual use in the Matrix API call
156+
pointList = new ArrayList<>();
157+
158+
// Get the position of each GeoJSON feature and build the list of Position
159+
// objects for eventual use in the Matrix API call
160+
if (featureCollection != null && featureCollection.features() != null) {
161+
for (Feature singleLocation : featureCollection.features()) {
162+
pointList.add((Point) singleLocation.geometry());
163+
}
164+
}
165+
}
166+
167+
/**
168+
* Set up the RecyclerView, which will display the travel distances to each charge station.
169+
*/
131170
private void initRecyclerView() {
132171
matrixApiLocationRecyclerViewAdapter = new MatrixApiLocationRecyclerViewAdapter(this,
133172
matrixLocationList);
173+
RecyclerView recyclerView = findViewById(R.id.matrix_api_recyclerview);
134174
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(),
135175
LinearLayoutManager.HORIZONTAL, true));
136176
recyclerView.setItemAnimator(new DefaultItemAnimator());
@@ -139,7 +179,12 @@ private void initRecyclerView() {
139179
snapHelper.attachToRecyclerView(recyclerView);
140180
}
141181

142-
private void makeMapboxMatrixApiCall(final int markerPositionInList, Point pointOfClickedMarker) {
182+
/**
183+
* Make a call to the Mapbox Matrix API to get the travel distances to each charge station.
184+
*
185+
* @param markerPositionInList the position of the tapped bolt icon {@link Feature} in the FeatureCollection.
186+
*/
187+
private void makeMapboxMatrixApiCall(final int markerPositionInList) {
143188

144189
// Build Mapbox Matrix API parameters
145190
MapboxMatrix directionsMatrixClient = MapboxMatrix.builder()
@@ -157,15 +202,12 @@ public void onResponse(Call<MatrixResponse> call,
157202
List<Double[]> durationsToAllOfTheLocationsFromTheOrigin = response.body().durations();
158203
if (durationsToAllOfTheLocationsFromTheOrigin != null) {
159204
for (int x = 0; x < durationsToAllOfTheLocationsFromTheOrigin.size(); x++) {
160-
String finalConvertedFormattedDistance = String.valueOf(new DecimalFormat("#.##")
161-
.format(TurfConversion.convertLength(
205+
String finalConvertedFormattedDistance = String.valueOf(new DecimalFormat("#.##").format(
206+
TurfConversion.convertLength(
162207
durationsToAllOfTheLocationsFromTheOrigin.get(markerPositionInList)[x],
163208
"meters", "miles")));
164-
if (x == markerPositionInList) {
165-
matrixLocationList.get(x).setDistanceFromOrigin(finalConvertedFormattedDistance);
166-
}
209+
matrixLocationList.get(x).setDistanceFromOrigin(finalConvertedFormattedDistance);
167210
if (x != markerPositionInList) {
168-
matrixLocationList.get(x).setDistanceFromOrigin(finalConvertedFormattedDistance);
169211
matrixApiLocationRecyclerViewAdapter.notifyDataSetChanged();
170212
}
171213
}
@@ -177,7 +219,7 @@ public void onResponse(Call<MatrixResponse> call,
177219
public void onFailure(Call<MatrixResponse> call, Throwable throwable) {
178220
Toast.makeText(MatrixApiActivity.this, R.string.call_error,
179221
Toast.LENGTH_SHORT).show();
180-
Timber.d( "onResponse onFailure");
222+
Timber.d("onResponse onFailure");
181223
}
182224
});
183225
}
@@ -204,40 +246,23 @@ private String loadGeoJsonFromAsset(String filename) {
204246
byte[] buffer = new byte[size];
205247
is.read(buffer);
206248
is.close();
207-
return new String(buffer, Charset.forName("UTF-8"));
249+
return new String(buffer, Charset.forName("UTF-8"));
208250
} catch (Exception exception) {
209251
Timber.d(exception.toString(), "Exception Loading GeoJSON: ");
210252
exception.printStackTrace();
211253
return null;
212254
}
213255
}
214256

215-
private void initPositionListFromGeoJsonFile() {
216-
217-
// Get GeoJSON features from GeoJSON file in the assets folder
218-
featureCollection = FeatureCollection.fromJson(loadGeoJsonFromAsset("boston_charge_stations.geojson"));
219-
220-
// Initialize List<Position> for eventual use in the Matrix API call
221-
pointList = new ArrayList<>();
222-
223-
// Get the position of each GeoJSON feature and build the list of Position
224-
// objects for eventual use in the Matrix API call
225-
if (featureCollection.features() != null) {
226-
for (Feature singleLocation : featureCollection.features()) {
227-
pointList.add((Point) singleLocation.geometry());
228-
}
229-
}
230-
}
231-
257+
/**
258+
* Create a list of {@link SingleRecyclerViewMatrixLocation} objects to eventually use in the RecyclerView.
259+
*/
232260
private void initMatrixLocationListForRecyclerView() {
233261
matrixLocationList = new ArrayList<>();
234-
if (featureCollection.features() != null) {
262+
if (featureCollection != null && featureCollection.features() != null) {
235263
for (Feature feature : featureCollection.features()) {
236264
SingleRecyclerViewMatrixLocation singleRecyclerViewLocation = new SingleRecyclerViewMatrixLocation();
237-
singleRecyclerViewLocation.setName(feature.getStringProperty("Station_Name"));
238-
singleRecyclerViewLocation.setLocationLatLng(new LatLng(((Point)
239-
feature.geometry()).latitude(),
240-
((Point) feature.geometry()).longitude()));
265+
singleRecyclerViewLocation.setName(feature.getStringProperty(STATION_NAME_PROPERTY));
241266
matrixLocationList.add(singleRecyclerViewLocation);
242267
}
243268
}
@@ -310,12 +335,11 @@ public String getDistanceFromOrigin() {
310335
public void setDistanceFromOrigin(String distanceFromOrigin) {
311336
this.distanceFromOrigin = distanceFromOrigin;
312337
}
313-
314-
public void setLocationLatLng(LatLng locationLatLng) {
315-
this.locationLatLng = locationLatLng;
316-
}
317338
}
318339

340+
/**
341+
* The adapter for this example's RecyclerView.
342+
*/
319343
static class MatrixApiLocationRecyclerViewAdapter extends
320344
RecyclerView.Adapter<MatrixApiLocationRecyclerViewAdapter.MyViewHolder> {
321345

@@ -364,4 +388,4 @@ static class MyViewHolder extends RecyclerView.ViewHolder {
364388
}
365389
}
366390
}
367-
}
391+
}

MapboxAndroidDemo/src/main/res/layout/activity_matrix_api.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
mapbox:mapbox_cameraTargetLat="42.3600825"
1212
mapbox:mapbox_cameraTargetLng="-71.0588801"
1313
mapbox:mapbox_cameraZoom="11.193"
14+
mapbox:mapbox_uiCompassMarginTop="79dp"
1415
/>
1516

1617
<androidx.recyclerview.widget.RecyclerView

MapboxAndroidDemo/src/main/res/values/activity_strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@
242242
<!-- Matrix API -->
243243
<string name="call_error">Oh no! The call to the Directions Matrix API failed</string>
244244
<string name="miles_distance">%1$s miles</string>
245-
<string name="click_on_marker_instruction_toast">Click on a bolt marker to get started</string>
245+
<string name="click_on_marker_instruction_toast">Click on a bolt icon to get started</string>
246246

247247
<!-- Geocoding -->
248248
<string name="latitude">latitude</string>

0 commit comments

Comments
 (0)