This repository has been archived by the owner on Oct 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 493
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
298 changes: 298 additions & 0 deletions
298
...ox/mapboxandroiddemo/examples/javaservices/MultipleGeometriesDirectionsRouteActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,298 @@ | ||
package com.mapbox.mapboxandroiddemo.examples.javaservices; | ||
|
||
import android.graphics.Color; | ||
import android.os.Bundle; | ||
import android.widget.Toast; | ||
|
||
import com.mapbox.api.directions.v5.DirectionsCriteria; | ||
import com.mapbox.api.directions.v5.MapboxDirections; | ||
import com.mapbox.api.directions.v5.models.DirectionsResponse; | ||
import com.mapbox.api.directions.v5.models.DirectionsRoute; | ||
import com.mapbox.api.directions.v5.models.LegStep; | ||
import com.mapbox.geojson.Feature; | ||
import com.mapbox.geojson.FeatureCollection; | ||
import com.mapbox.geojson.Geometry; | ||
import com.mapbox.geojson.GeometryCollection; | ||
import com.mapbox.geojson.LineString; | ||
import com.mapbox.geojson.Point; | ||
import com.mapbox.mapboxandroiddemo.R; | ||
import com.mapbox.mapboxsdk.Mapbox; | ||
import com.mapbox.mapboxsdk.geometry.LatLng; | ||
import com.mapbox.mapboxsdk.geometry.LatLngBounds; | ||
import com.mapbox.mapboxsdk.maps.MapView; | ||
import com.mapbox.mapboxsdk.maps.MapboxMap; | ||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; | ||
import com.mapbox.mapboxsdk.maps.Style; | ||
import com.mapbox.mapboxsdk.style.layers.CircleLayer; | ||
import com.mapbox.mapboxsdk.style.layers.LineLayer; | ||
import com.mapbox.mapboxsdk.style.layers.Property; | ||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
import retrofit2.Call; | ||
import retrofit2.Callback; | ||
import retrofit2.Response; | ||
import timber.log.Timber; | ||
|
||
import static com.mapbox.core.constants.Constants.PRECISION_6; | ||
import static com.mapbox.mapboxsdk.camera.CameraUpdateFactory.newLatLngBounds; | ||
import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; | ||
import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; | ||
import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_PITCH_ALIGNMENT_MAP; | ||
import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_PITCH_ALIGNMENT_VIEWPORT; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circlePitchAlignment; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineCap; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor; | ||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth; | ||
|
||
/** | ||
* Use the Mapbox Directions API to request and retrieve a Directions route. Show the route line and | ||
* place a circle where each of the route's waypoints are. | ||
*/ | ||
public class MultipleGeometriesDirectionsRouteActivity extends AppCompatActivity implements OnMapReadyCallback { | ||
|
||
private MapView mapView; | ||
private static final String GEOJSON_SOURCE_ID = "GEOJSON_SOURCE_ID"; | ||
private static final String STEPS_CIRCLE_LAYER_ID = "steps-circle-layer"; | ||
private static final String STEPS_BACKGROUND_CIRCLE_LAYER_ID = "steps-background-circle-layer"; | ||
private static final String DIRECTIONS_ROUTE_LINE_LAYER_ID = "directions-line-layer"; | ||
|
||
// Adjust the following static final variables to style this example's UI | ||
private static final String LINE_COLOR = "#EE2E23"; | ||
private static final float LINE_WIDTH = 8f; | ||
private static final float CIRCLE_RADIUS = 5f; | ||
private static final float RADIUS_DIFFERENCE_BETWEEN_WAYPOINT_CIRCLES_AND_BACKGROUND_CIRCLES = 4f; | ||
private static final int CIRCLE_COLOR = Color.WHITE; | ||
private static final float MAX_ZOOM = 15f; | ||
private static final int BACKGROUND_CIRCLE_COLOR = Color.parseColor(LINE_COLOR); | ||
private static final boolean ALIGN_CIRCLES_WITH_MAP = true; | ||
|
||
private MapboxMap mapboxMap; | ||
private DirectionsRoute currentRoute; | ||
private Point origin = Point.fromLngLat(-122.39648, 37.7914277); | ||
private Point destination = Point.fromLngLat(-88.0430, 30.6944); | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
// Mapbox access token is configured here. This needs to be called either in your application | ||
// object or in the same activity which contains the mapview. | ||
Mapbox.getInstance(this, getString(R.string.access_token)); | ||
|
||
// This contains the MapView in XML and needs to be called after the access token is configured. | ||
setContentView(R.layout.activity_dds_multiple_geometries_from_directions_route); | ||
|
||
mapView = findViewById(R.id.mapView); | ||
mapView.onCreate(savedInstanceState); | ||
mapView.getMapAsync(this); | ||
} | ||
|
||
@Override | ||
public void onMapReady(@NonNull MapboxMap mapboxMap) { | ||
mapboxMap.setStyle(new Style.Builder().fromUri(Style.SATELLITE_STREETS) | ||
.withSource(new GeoJsonSource(GEOJSON_SOURCE_ID)), new Style.OnStyleLoaded() { | ||
@Override | ||
public void onStyleLoaded(@NonNull Style style) { | ||
MultipleGeometriesDirectionsRouteActivity.this.mapboxMap = mapboxMap; | ||
initDirectionsRouteLineLayer(style); | ||
initDirectionStepsCircleLayer(style); | ||
initDirectionStepsBackgroundCircleLayer(style); | ||
getRoute(origin, destination); | ||
} | ||
}); | ||
} | ||
|
||
private void initDirectionsRouteLineLayer(@NonNull Style loadedMapStyle) { | ||
// Create and style a LineLayer that will draw the Mapbox Directions API route line. | ||
LineLayer directionsRouteLineLayer = new LineLayer(DIRECTIONS_ROUTE_LINE_LAYER_ID, GEOJSON_SOURCE_ID); | ||
directionsRouteLineLayer.setProperties( | ||
lineColor(Color.parseColor(LINE_COLOR)), | ||
lineCap(Property.LINE_CAP_ROUND), | ||
lineWidth(LINE_WIDTH) | ||
); | ||
|
||
directionsRouteLineLayer.setFilter(eq(literal("$type"), literal("LineString"))); | ||
|
||
// Add the layer below the "settlement-label" layer (city name labels, etc.) | ||
if (loadedMapStyle.getLayer("settlement-label") != null) { | ||
loadedMapStyle.addLayerBelow(directionsRouteLineLayer, "settlement-label"); | ||
} else { | ||
loadedMapStyle.addLayer(directionsRouteLineLayer); | ||
} | ||
} | ||
|
||
private void initDirectionStepsCircleLayer(@NonNull Style loadedMapStyle) { | ||
// Create and style a CircleLayer that will place circles for each of the Mapbox Directions API route's | ||
// waypoint locations | ||
CircleLayer individualCirclesLayer = new CircleLayer(STEPS_CIRCLE_LAYER_ID, GEOJSON_SOURCE_ID); | ||
individualCirclesLayer.setProperties( | ||
circleColor(CIRCLE_COLOR), | ||
circlePitchAlignment(ALIGN_CIRCLES_WITH_MAP ? CIRCLE_PITCH_ALIGNMENT_MAP : CIRCLE_PITCH_ALIGNMENT_VIEWPORT), | ||
circleRadius(CIRCLE_RADIUS)); | ||
individualCirclesLayer.setFilter(eq(literal("$type"), literal("Point"))); | ||
individualCirclesLayer.setMaxZoom(MAX_ZOOM); | ||
loadedMapStyle.addLayer(individualCirclesLayer); | ||
} | ||
|
||
private void initDirectionStepsBackgroundCircleLayer(@NonNull Style loadedMapStyle) { | ||
// Create and style a CircleLayer that will place circles for each of the Mapbox Directions API route's | ||
// waypoint locations | ||
CircleLayer individualCirclesLayer = new CircleLayer(STEPS_BACKGROUND_CIRCLE_LAYER_ID, GEOJSON_SOURCE_ID); | ||
individualCirclesLayer.setProperties( | ||
circleColor(BACKGROUND_CIRCLE_COLOR), | ||
circlePitchAlignment(ALIGN_CIRCLES_WITH_MAP ? CIRCLE_PITCH_ALIGNMENT_MAP : CIRCLE_PITCH_ALIGNMENT_VIEWPORT), | ||
circleRadius(CIRCLE_RADIUS + RADIUS_DIFFERENCE_BETWEEN_WAYPOINT_CIRCLES_AND_BACKGROUND_CIRCLES)); | ||
individualCirclesLayer.setFilter(eq(literal("$type"), literal("Point"))); | ||
individualCirclesLayer.setMaxZoom(MAX_ZOOM); | ||
loadedMapStyle.addLayerBelow(individualCirclesLayer, STEPS_CIRCLE_LAYER_ID); | ||
} | ||
|
||
/** | ||
* Make a request to the Mapbox Directions API. Once successful, pass the route to the | ||
* route layer. | ||
* | ||
* @param origin the starting point of the route | ||
* @param destination the desired finish point of the route | ||
*/ | ||
private void getRoute(Point origin, Point destination) { | ||
|
||
MapboxDirections directionsApiClient = MapboxDirections.builder() | ||
.origin(origin) | ||
.destination(destination) | ||
.overview(DirectionsCriteria.OVERVIEW_FULL) | ||
.profile(DirectionsCriteria.PROFILE_DRIVING) | ||
.steps(true) | ||
.accessToken(getString(R.string.access_token)) | ||
.build(); | ||
|
||
directionsApiClient.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: " + 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; | ||
} | ||
|
||
if (response.body() != null) { | ||
|
||
// Get the directions route | ||
currentRoute = response.body().routes().get(0); | ||
|
||
mapboxMap.getStyle(new Style.OnStyleLoaded() { | ||
@Override | ||
public void onStyleLoaded(@NonNull Style style) { | ||
// Retrieve and update the source designated for showing the directions route | ||
GeoJsonSource source = style.getSourceAs(GEOJSON_SOURCE_ID); | ||
|
||
// Create a LineString with the directions route's geometry and | ||
// reset the GeoJSON source for the route LineLayer source. | ||
if (source != null && response.body() != null) { | ||
|
||
List<Geometry> geometryList = new ArrayList<>(); | ||
|
||
// Add each step maneuvers to the geometry list. | ||
if (currentRoute.legs().size() > 0) { | ||
for (LegStep singleRouteLeg : currentRoute.legs().get(0).steps()) { | ||
Point stepManeuverLocationPoint = singleRouteLeg.maneuver().location(); | ||
geometryList.add(stepManeuverLocationPoint); | ||
} | ||
} else { | ||
Timber.d("%s", getString(R.string.no_legs_toast)); | ||
} | ||
|
||
// Add the Directions route LineString geometry to the geometry list. | ||
if (currentRoute.geometry() != null) { | ||
geometryList.add(LineString.fromPolyline(currentRoute.geometry(), PRECISION_6)); | ||
} | ||
|
||
// Update the source's GeoJSON with a Feature that is of a GeometryCollection geometry. | ||
// The GeometryCollection has the route LineString and the various step Points. | ||
// The filters applied to the LineLayer and CircleLayer above, will be applied | ||
// to the GeometryCollection. | ||
source.setGeoJson(FeatureCollection.fromFeature( | ||
Feature.fromGeometry( | ||
GeometryCollection.fromGeometries(geometryList) | ||
))); | ||
|
||
// Ease the camera to fit to the Directions route. | ||
easeCameraToShowEntireDirectionsRoute(new LatLng(origin.latitude(), origin.longitude()), | ||
new LatLng(destination.latitude(), destination.longitude())); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
@Override | ||
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) { | ||
Timber.e("Error: " + throwable.getMessage()); | ||
Toast.makeText(MultipleGeometriesDirectionsRouteActivity.this, "Error: " + throwable.getMessage(), | ||
Toast.LENGTH_SHORT).show(); | ||
} | ||
}); | ||
} | ||
|
||
private void easeCameraToShowEntireDirectionsRoute(LatLng origin, LatLng destination) { | ||
mapboxMap.easeCamera(newLatLngBounds(new LatLngBounds.Builder() | ||
.include(origin) | ||
.include(destination) | ||
.build(), 75), 2000); | ||
} | ||
|
||
// Add the mapView lifecycle to the activity's lifecycle methods | ||
@Override | ||
public void onResume() { | ||
super.onResume(); | ||
mapView.onResume(); | ||
} | ||
|
||
@Override | ||
protected void onStart() { | ||
super.onStart(); | ||
mapView.onStart(); | ||
} | ||
|
||
@Override | ||
protected void onStop() { | ||
super.onStop(); | ||
mapView.onStop(); | ||
} | ||
|
||
@Override | ||
public void onPause() { | ||
super.onPause(); | ||
mapView.onPause(); | ||
} | ||
|
||
@Override | ||
public void onLowMemory() { | ||
super.onLowMemory(); | ||
mapView.onLowMemory(); | ||
} | ||
|
||
@Override | ||
protected void onDestroy() { | ||
super.onDestroy(); | ||
mapView.onDestroy(); | ||
} | ||
|
||
@Override | ||
protected void onSaveInstanceState(Bundle outState) { | ||
super.onSaveInstanceState(outState); | ||
mapView.onSaveInstanceState(outState); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
...ndroidDemo/src/main/res/layout/activity_dds_multiple_geometries_from_directions_route.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
tools:context="com.mapbox.mapboxandroiddemo.examples.javaservices.MultipleGeometriesDirectionsRouteActivity"> | ||
|
||
<com.mapbox.mapboxsdk.maps.MapView | ||
android:id="@+id/mapView" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" /> | ||
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters