Retrieve elevation data

activity_javaservices_elevation_query
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".examples.javaservices.TilequeryActivity">
<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="0dp"
android:layout_height="0dp"
mapbox:layout_constraintBottom_toBottomOf="parent"
mapbox:layout_constraintEnd_toEndOf="parent"
mapbox:layout_constraintStart_toStartOf="parent"
mapbox:layout_constraintTop_toTopOf="parent"
mapbox:mapbox_cameraTargetLat="40.73581"
mapbox:mapbox_cameraTargetLng="-73.99155"
mapbox:mapbox_cameraZoom="11" />
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="28dp"
mapbox:layout_constraintBottom_toBottomOf="@+id/mapView"
mapbox:layout_constraintEnd_toEndOf="parent"
mapbox:layout_constraintStart_toStartOf="parent"
mapbox:layout_constraintTop_toTopOf="@+id/guideline8">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/elevation_api_response_textview"
android:textColor="@color/black_semi_transparent"
android:textStyle="bold" />
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/elevation_api_response_ten_meter_textview"
android:textColor="@color/black_semi_transparent"
android:textSize="12sp" />
<TextView
android:id="@+id/elevation_query_api_response_elevation_numbers_only"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/mapboxRedDark"
android:textSize="12sp"
tools:text="4 Features in the API response: 20, 30, 80, 90" />
<ScrollView
android:id="@+id/scrollView3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/elevation_query_api_response_json_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
</androidx.cardview.widget.CardView>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
mapbox:layout_constraintGuide_percent="0.7" />
</androidx.constraintlayout.widget.ConstraintLayout>
HillShadeActivity
package com.mapbox.mapboxandroiddemo.examples.javaservices;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.api.tilequery.MapboxTilequery;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxandroiddemo.R;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
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.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
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.mapboxsdk.style.expressions.Expression.get;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloBlur;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;
/**
* Use the Mapbox Tilequery API to access global elevation data. More info about
* elevation data can be found at
* https://docs.mapbox.com/help/troubleshooting/access-elevation-data/
*/
public class ElevationQueryActivity extends AppCompatActivity implements
OnMapReadyCallback, PermissionsListener, MapboxMap.OnMapClickListener {
private static final String RESULT_GEOJSON_SOURCE_ID = "RESULT_GEOJSON_SOURCE_ID";
private static final String LAYER_ID = "LAYER_ID";
private PermissionsManager permissionsManager;
private MapboxMap mapboxMap;
private MapView mapView;
private TextView elevationQueryNumbersOnlyResponseTextView;
private TextView elevationQueryJsonResponseTextView;
@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_javaservices_elevation_query);
elevationQueryJsonResponseTextView = findViewById(R.id.elevation_query_api_response_json_textview);
elevationQueryNumbersOnlyResponseTextView = findViewById(R.id.elevation_query_api_response_elevation_numbers_only);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}
@SuppressWarnings( {"MissingPermission"})
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
ElevationQueryActivity.this.mapboxMap = mapboxMap;
mapboxMap.setStyle(Style.OUTDOORS, new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
addResultLayer(style);
displayDeviceLocation(style);
mapboxMap.addOnMapClickListener(ElevationQueryActivity.this);
Toast.makeText(ElevationQueryActivity.this, R.string.click_on_map_instruction, Toast.LENGTH_SHORT).show();
}
});
}
/**
* Add a map layer which will show a text number of the highest or lowest elevation number returned
* by the Tilequery API.
*/
private void addResultLayer(@NonNull Style loadedMapStyle) {
loadedMapStyle.addSource(new GeoJsonSource(RESULT_GEOJSON_SOURCE_ID));
loadedMapStyle.addLayer(new SymbolLayer(LAYER_ID, RESULT_GEOJSON_SOURCE_ID).withProperties(
textField(get("ele")),
textColor(Color.BLUE),
textSize(23f),
textHaloBlur(10f),
textIgnorePlacement(true),
textAllowOverlap(true)
));
}
@Override
public boolean onMapClick(@NonNull LatLng point) {
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
// Use the map click location to make a request to the Tilequery API for elevation data.
makeElevationRequestToTilequeryApi(style, point);
}
});
return true;
}
/**
* Use the Java SDK's MapboxTilequery class to build a API request and use the API response
*
* @param point where the Tilequery API should query Mapbox's "mapbox.mapbox-terrain-v2" tileset
* for elevation data.
*/
private void makeElevationRequestToTilequeryApi(@NonNull final Style style, @NonNull LatLng point) {
MapboxTilequery elevationQuery = MapboxTilequery.builder()
.accessToken(getString(R.string.access_token))
.mapIds("mapbox.mapbox-terrain-v2")
.query(Point.fromLngLat(point.getLongitude(), point.getLatitude()))
.geometry("polygon")
.layers("contour")
.build();
elevationQuery.enqueueCall(new Callback<FeatureCollection>() {
@Override
public void onResponse(Call<FeatureCollection> call, Response<FeatureCollection> response) {
if (response.body().features() != null) {
List<Feature> featureList = response.body().features();
String listOfElevationNumbers = "";
// Build a list of the elevation numbers in the response.
for (Feature singleFeature : featureList) {
listOfElevationNumbers = listOfElevationNumbers + singleFeature.getStringProperty("ele") + ", ";
}
// Set this TextViews with the response info/JSON.
elevationQueryNumbersOnlyResponseTextView.setText(String.format(getString(
R.string.elevation_numbers_only_textview), featureList.size(), listOfElevationNumbers));
elevationQueryJsonResponseTextView.setText(response.body().toJson());
// Update the SymbolLayer that's responsible for showing the number text with the highest/lowest
// elevation number
if (featureList.size() > 0) {
GeoJsonSource resultSource = style.getSourceAs(RESULT_GEOJSON_SOURCE_ID);
if (resultSource != null) {
resultSource.setGeoJson(featureList.get(featureList.size() - 1));
}
}
} else {
String noFeaturesString = getString(R.string.elevation_tilequery_no_features);
Timber.d(noFeaturesString);
Toast.makeText(ElevationQueryActivity.this, noFeaturesString, Toast.LENGTH_SHORT).show();
elevationQueryNumbersOnlyResponseTextView.setText(noFeaturesString);
elevationQueryJsonResponseTextView.setText(noFeaturesString);
}
}
@Override
public void onFailure(Call<FeatureCollection> call, Throwable throwable) {
Timber.d("Request failed: %s", throwable.getMessage());
Toast.makeText(ElevationQueryActivity.this,
R.string.elevation_tilequery_api_response_error, Toast.LENGTH_SHORT).show();
}
});
}
/**
* Use the Maps SDK's LocationComponent to display the device location on the map
*/
@SuppressWarnings( {"MissingPermission"})
private void displayDeviceLocation(@NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();
// Activate with options
locationComponent.activateLocationComponent(
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());
// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
locationComponent.setRenderMode(RenderMode.COMPASS);
// Zoom the camera into the device's current location
mapboxMap.animateCamera(CameraUpdateFactory
.newCameraPosition(new CameraPosition.Builder()
.zoom(10)
.build()), 2000);
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
// The following three methods are related to showing the device's location via the LocationComponent
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}
@Override
public void onPermissionResult(boolean granted) {
mapboxMap.getStyle(new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
if (granted) {
displayDeviceLocation(style);
} else {
Toast.makeText(ElevationQueryActivity.this,
R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
finish();
}
}
});
}
// 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();
if (mapboxMap != null) {
mapboxMap.removeOnMapClickListener(this);
}
mapView.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
Was this page helpful?