committed by
Ivo van Dongen
parent
11dd4afc5b
commit
2591147e25
@@ -90,13 +90,8 @@ dependencies {
|
||||
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
|
||||
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
|
||||
|
||||
// Directions SDK
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
// Geocoder SDK
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0@aar') {
|
||||
// Mapbox Android Services
|
||||
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.1.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
|
||||
@@ -270,6 +270,14 @@
|
||||
android:value="@string/category_annotation" />
|
||||
</activity>
|
||||
|
||||
<activity android:name=".activity.navigation.LocationPickerActivity"
|
||||
android:description="@string/description_location_picker"
|
||||
android:label="@string/activity_location_picker">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_navigation" />
|
||||
</activity>
|
||||
|
||||
<!-- Configuration Settings -->
|
||||
<meta-data
|
||||
android:name="com.mapbox.TestEventsServer"
|
||||
|
||||
@@ -8,12 +8,6 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.mapbox.directions.DirectionsCriteria;
|
||||
import com.mapbox.directions.MapboxDirections;
|
||||
import com.mapbox.directions.service.models.DirectionsResponse;
|
||||
import com.mapbox.directions.service.models.DirectionsRoute;
|
||||
import com.mapbox.directions.service.models.Waypoint;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
@@ -23,12 +17,18 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit.Callback;
|
||||
import retrofit.Response;
|
||||
import retrofit.Retrofit;
|
||||
import com.mapbox.services.Constants;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.geojson.LineString;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.directions.v4.DirectionsCriteria;
|
||||
import com.mapbox.services.directions.v4.MapboxDirections;
|
||||
import com.mapbox.services.directions.v4.models.DirectionsResponse;
|
||||
import com.mapbox.services.directions.v4.models.DirectionsRoute;
|
||||
import com.mapbox.services.directions.v4.models.Waypoint;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class DirectionsActivity extends AppCompatActivity {
|
||||
|
||||
@@ -94,49 +94,55 @@ public class DirectionsActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void getRoute(Waypoint origin, Waypoint destination) {
|
||||
MapboxDirections md = new MapboxDirections.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setOrigin(origin)
|
||||
.setDestination(destination)
|
||||
.setProfile(DirectionsCriteria.PROFILE_WALKING)
|
||||
.build();
|
||||
try {
|
||||
MapboxDirections md = new MapboxDirections.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setOrigin(origin)
|
||||
.setDestination(destination)
|
||||
.setProfile(DirectionsCriteria.PROFILE_WALKING)
|
||||
.build();
|
||||
|
||||
md.enqueue(new Callback<DirectionsResponse>() {
|
||||
@Override
|
||||
public void onResponse(Response<DirectionsResponse> response, Retrofit retrofit) {
|
||||
// You can get generic HTTP info about the response
|
||||
Log.d(LOG_TAG, "Response code: " + response.code());
|
||||
md.enqueueCall(new Callback<DirectionsResponse>() {
|
||||
|
||||
// Print some info about the route
|
||||
DirectionsRoute currentRoute = response.body().getRoutes().get(0);
|
||||
Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
|
||||
@Override
|
||||
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
|
||||
Log.e(LOG_TAG, "Error: " + t.getMessage());
|
||||
}
|
||||
|
||||
// Draw the route on the map
|
||||
drawRoute(currentRoute);
|
||||
}
|
||||
@Override
|
||||
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
|
||||
// You can get generic HTTP info about the response
|
||||
Log.d(LOG_TAG, "Response code: " + response.code());
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
Log.e(LOG_TAG, "Error: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
// Print some info about the route
|
||||
DirectionsRoute currentRoute = response.body().getRoutes().get(0);
|
||||
Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
|
||||
|
||||
// Draw the route on the map
|
||||
drawRoute(currentRoute);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(LOG_TAG, "Error displaying route: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRoute(DirectionsRoute route) {
|
||||
// Convert List<Waypoint> into LatLng[]
|
||||
List<Waypoint> waypoints = route.getGeometry().getWaypoints();
|
||||
LatLng[] point = new LatLng[waypoints.size()];
|
||||
for (int i = 0; i < waypoints.size(); i++) {
|
||||
point[i] = new LatLng(
|
||||
waypoints.get(i).getLatitude(),
|
||||
waypoints.get(i).getLongitude());
|
||||
|
||||
PolylineOptions builder = new PolylineOptions();
|
||||
builder.color(Color.parseColor("#3887be"));
|
||||
builder.alpha(0.5f);
|
||||
builder.width(5);
|
||||
builder.width(5);
|
||||
LineString lineString = route.asLineString(Constants.OSRM_PRECISION_V4);
|
||||
for (Position coordinates : lineString.getCoordinates()) {
|
||||
builder.add(new LatLng(coordinates.getLatitude(), coordinates.getLongitude()));
|
||||
}
|
||||
|
||||
// Draw Points on MapView
|
||||
mMapboxMap.addPolyline(new PolylineOptions()
|
||||
.add(point)
|
||||
.color(Color.parseColor("#3887be"))
|
||||
.width(5));
|
||||
mMapboxMap.addPolyline(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,11 +14,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mapbox.geocoder.GeocoderCriteria;
|
||||
import com.mapbox.geocoder.MapboxGeocoder;
|
||||
import com.mapbox.geocoder.service.models.GeocoderFeature;
|
||||
import com.mapbox.geocoder.service.models.GeocoderResponse;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.constants.Style;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
@@ -27,12 +22,19 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Projection;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.geocoding.v5.GeocodingCriteria;
|
||||
import com.mapbox.services.geocoding.v5.MapboxGeocoding;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingFeature;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit.Callback;
|
||||
import retrofit.Response;
|
||||
import retrofit.Retrofit;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
|
||||
public class GeocoderActivity extends AppCompatActivity {
|
||||
|
||||
@@ -123,40 +125,38 @@ public class GeocoderActivity extends AppCompatActivity {
|
||||
*/
|
||||
|
||||
private void geocode(final LatLng point) {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
MapboxGeocoder client = new MapboxGeocoder.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(point.getLongitude(), point.getLatitude())
|
||||
.setType(GeocoderCriteria.TYPE_POI)
|
||||
.build();
|
||||
try {
|
||||
MapboxGeocoding client = new MapboxGeocoding.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
|
||||
.setType(GeocodingCriteria.TYPE_POI)
|
||||
.build();
|
||||
|
||||
client.enqueue(new Callback<GeocoderResponse>()
|
||||
client.enqueueCall(new Callback<GeocodingResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
|
||||
|
||||
{
|
||||
@Override
|
||||
public void onResponse(Response<GeocoderResponse> response, Retrofit retrofit) {
|
||||
List<GeocoderFeature> results = response.body().getFeatures();
|
||||
if (results.size() > 0) {
|
||||
String placeName = results.get(0).getPlaceName();
|
||||
setSuccess(placeName);
|
||||
} else {
|
||||
setMessage("No results.");
|
||||
}
|
||||
}
|
||||
List<GeocodingFeature> results = response.body().getFeatures();
|
||||
if (results.size() > 0) {
|
||||
String placeName = results.get(0).getPlaceName();
|
||||
setSuccess(placeName);
|
||||
} else {
|
||||
setMessage("No results.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
setError(t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
@Override
|
||||
public void onFailure(Call<GeocodingResponse> call, Throwable t) {
|
||||
setError(t.getMessage());
|
||||
}
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(LOG_TAG, "Error geocoding: " + e.toString());
|
||||
e.printStackTrace();
|
||||
setError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.navigation;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationListener;
|
||||
import com.mapbox.mapboxsdk.location.LocationServices;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerView;
|
||||
import com.mapbox.mapboxsdk.testapp.model.annotations.PulseMarkerViewOptions;
|
||||
import com.mapbox.services.commons.ServicesException;
|
||||
import com.mapbox.services.commons.models.Position;
|
||||
import com.mapbox.services.geocoding.v5.GeocodingCriteria;
|
||||
import com.mapbox.services.geocoding.v5.MapboxGeocoding;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingFeature;
|
||||
import com.mapbox.services.geocoding.v5.models.GeocodingResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* Sample Activity to show a typical location picker use case
|
||||
*/
|
||||
public class LocationPickerActivity extends AppCompatActivity {
|
||||
private static final String TAG = "LocationPickerActivity";
|
||||
private static final int REQUEST_PERMISSIONS = 101;
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private ImageView dropPinView;
|
||||
private Marker addressPin;
|
||||
private ImageButton clearDisplayViewButton;
|
||||
private MarkerView userMarker;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_location_picker);
|
||||
|
||||
setupActionBar();
|
||||
|
||||
//Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
//Create ui elements
|
||||
createDropPin();
|
||||
createSelectLocationButton();
|
||||
createClearSelectionButton();
|
||||
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(MapboxMap map) {
|
||||
//Store for later
|
||||
mapboxMap = map;
|
||||
|
||||
//Add user marker
|
||||
mapboxMap.getMarkerViewManager().addMarkerViewAdapter(new PulseMarkerViewAdapter(LocationPickerActivity.this));
|
||||
userMarker = createCustomUserMarker(new LatLng(0, 0));
|
||||
|
||||
//Fix the focal point to the center of the map
|
||||
PointF focalPoint = new PointF((mapView.getX() + mapView.getWidth() / 2), (mapView.getY() + mapView.getHeight() / 2));
|
||||
mapboxMap.getUiSettings().setFocalPoint(focalPoint);
|
||||
|
||||
//Track camera updates to animate the user location views
|
||||
trackUserLocationView(userMarker);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
|
||||
//Check permissions
|
||||
if (arePermissionsGranted()) {
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
|
||||
@Override
|
||||
public void onMapReady(final MapboxMap mapboxMap) {
|
||||
//Get the user's location
|
||||
final LocationServices locationServices = LocationServices.getLocationServices(getApplicationContext());
|
||||
|
||||
Location location = locationServices.getLastLocation();
|
||||
if (location != null) {
|
||||
zoomInOn(location);
|
||||
userMarker.setPosition(new LatLng(location));
|
||||
} else {
|
||||
final ProgressDialog loadingDialog = ProgressDialog.show(LocationPickerActivity.this, "Loading", "Getting user location", false);
|
||||
locationServices.addLocationListener(new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(@Nullable Location location) {
|
||||
//Move the camera to the user
|
||||
if (location != null) {
|
||||
zoomInOn(location);
|
||||
userMarker.setPosition(new LatLng(location));
|
||||
locationServices.removeLocationListener(this);
|
||||
loadingDialog.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
locationServices.toggleGPS(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomInOn(Location location) {
|
||||
//Move the camera to the user
|
||||
if (location != null) {
|
||||
mapboxMap.setCameraPosition(new CameraPosition.Builder()
|
||||
.target(new LatLng(location))
|
||||
.zoom(16)
|
||||
.bearing(0)
|
||||
.tilt(0)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tracks the camera to animate the marker when overlapping with the picker.
|
||||
* Makes sure the marker actually points to the user's position by tracking it.
|
||||
*/
|
||||
private void trackUserLocationView(final MarkerView markerView) {
|
||||
final float circleDiameterSize = getResources().getDimension(R.dimen.circle_size);
|
||||
|
||||
//Track camera changes to check for overlap
|
||||
mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
|
||||
|
||||
private Animation pulseAnimation;
|
||||
|
||||
@Override
|
||||
public void onCameraChange(CameraPosition position) {
|
||||
if (markerView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Make drop pin visible, if it wasn't already
|
||||
showDropPin();
|
||||
|
||||
//Get the distance from the tip of the location picker to the MarkerView
|
||||
double distance = getLocationPickerLocation().distanceTo(markerView.getPosition());
|
||||
|
||||
//If closeby, animate, otherwise, stop animation
|
||||
View view = mapboxMap.getMarkerViewManager().getView(markerView);
|
||||
if (view != null) {
|
||||
View backgroundView = view.findViewById(R.id.background_imageview);
|
||||
if (pulseAnimation == null && distance < 0.5f * circleDiameterSize) {
|
||||
pulseAnimation = AnimationUtils.loadAnimation(LocationPickerActivity.this, R.anim.pulse);
|
||||
pulseAnimation.setRepeatCount(Animation.INFINITE);
|
||||
pulseAnimation.setRepeatMode(Animation.RESTART);
|
||||
backgroundView.startAnimation(pulseAnimation);
|
||||
} else if (pulseAnimation != null && distance >= 0.5f * circleDiameterSize) {
|
||||
backgroundView.clearAnimation();
|
||||
pulseAnimation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Track location updates to move the user marker
|
||||
LocationServices.getLocationServices(getApplicationContext()).addLocationListener(new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (location != null && markerView != null) {
|
||||
markerView.setPosition(new LatLng(location));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MarkerView createCustomUserMarker(LatLng markerPosition) {
|
||||
return mapboxMap.addMarker(new PulseMarkerViewOptions()
|
||||
.icon(IconFactory.getInstance(getApplicationContext()).fromResource(R.drawable.ic_my_location_24dp))
|
||||
.position(markerPosition)
|
||||
);
|
||||
}
|
||||
|
||||
private void createClearSelectionButton() {
|
||||
clearDisplayViewButton = (ImageButton) findViewById(R.id.clearDisplayViewButton);
|
||||
clearDisplayViewButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
removeAddressPin();
|
||||
hide(clearDisplayViewButton);
|
||||
showDropPin();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createSelectLocationButton() {
|
||||
Button selectLocationButton = (Button) findViewById(R.id.selectLocationButton);
|
||||
//noinspection ConstantConditions
|
||||
selectLocationButton.setOnClickListener(
|
||||
new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Log.i(TAG, "Location Selected!");
|
||||
if (mapboxMap != null) {
|
||||
//Control button's state
|
||||
clearDisplayViewButton.setVisibility(View.VISIBLE);
|
||||
dropPinView.setVisibility(View.INVISIBLE);
|
||||
|
||||
//Get position for the drop pin
|
||||
LatLng position = getLocationPickerLocation();
|
||||
|
||||
//Show the address pin (result)
|
||||
showAddressPin(position);
|
||||
|
||||
//Get the address for that location and update the marker
|
||||
geocode(position, new GeocodeCallbacks() {
|
||||
@Override
|
||||
public void onResult(String result) {
|
||||
updateAddressPin(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable failure) {
|
||||
showFeedbackMessage("Could not retrieve address: " + failure.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void createDropPin() {
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
|
||||
dropPinView = new ImageView(this);
|
||||
dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
|
||||
params.bottomMargin = (int) (12 * density);
|
||||
dropPinView.setLayoutParams(params);
|
||||
|
||||
mapView.addView(dropPinView);
|
||||
}
|
||||
|
||||
private void showDropPin() {
|
||||
if (dropPinView != null && dropPinView.getVisibility() != View.VISIBLE) {
|
||||
dropPinView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void hide(View view) {
|
||||
if (view != null) {
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupActionBar() {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get address for the given location
|
||||
*/
|
||||
private void geocode(LatLng point, final GeocodeCallbacks callbacks) {
|
||||
try {
|
||||
//Create Geocoding client
|
||||
MapboxGeocoding client = new MapboxGeocoding.Builder()
|
||||
.setAccessToken(getString(R.string.mapbox_access_token))
|
||||
.setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
|
||||
.setType(GeocodingCriteria.TYPE_ADDRESS)
|
||||
.build();
|
||||
|
||||
//Place the request
|
||||
client.enqueueCall(new Callback<GeocodingResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
|
||||
|
||||
List<GeocodingFeature> results = response.body().getFeatures();
|
||||
String address = null;
|
||||
if (results.size() > 0) {
|
||||
GeocodingFeature feature = results.get(0);
|
||||
address = feature.getAddress() + " " + feature.getText();
|
||||
Log.i(TAG, "address " + address);
|
||||
} else {
|
||||
showFeedbackMessage("No results for search.");
|
||||
}
|
||||
|
||||
callbacks.onResult(address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<GeocodingResponse> call, Throwable t) {
|
||||
Log.e(TAG, "Geocoding Failure: " + t.getMessage());
|
||||
callbacks.onFailure(t);
|
||||
}
|
||||
});
|
||||
} catch (ServicesException e) {
|
||||
Log.e(TAG, "Error geocoding: " + e.toString());
|
||||
callbacks.onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
private LatLng getLocationPickerLocation() {
|
||||
return mapboxMap.getProjection().fromScreenLocation(
|
||||
new PointF(dropPinView.getLeft() + (dropPinView.getWidth() / 2), dropPinView.getBottom())
|
||||
);
|
||||
}
|
||||
|
||||
private Marker showAddressPin(LatLng position) {
|
||||
if (addressPin != null) {
|
||||
//Remove previous pin
|
||||
removeAddressPin();
|
||||
}
|
||||
|
||||
//Create new one
|
||||
addressPin = mapboxMap.addMarker(new MarkerViewOptions().title("Loading address...").position(position));
|
||||
mapboxMap.selectMarker(addressPin);
|
||||
return addressPin;
|
||||
}
|
||||
|
||||
private void removeAddressPin() {
|
||||
if (mapboxMap != null && addressPin != null) {
|
||||
mapboxMap.removeMarker(addressPin);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAddressPin(@Nullable String address) {
|
||||
if (addressPin != null) {
|
||||
addressPin.setTitle(address == null ? "No address found" : address);
|
||||
}
|
||||
}
|
||||
|
||||
private void showFeedbackMessage(String message) {
|
||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private boolean arePermissionsGranted() {
|
||||
if (Build.VERSION.SDK_INT >= 23 &&
|
||||
checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
|
||||
checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i(TAG, "Requesting permissions");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSIONS);
|
||||
return false;
|
||||
}
|
||||
Log.i(TAG, "Permissions already granted");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom MarkerViewAdapter for the pulsing marker
|
||||
*/
|
||||
private static class PulseMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<PulseMarkerView> {
|
||||
|
||||
private LayoutInflater inflater;
|
||||
|
||||
public PulseMarkerViewAdapter(@NonNull Context context) {
|
||||
super(context);
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View getView(@NonNull PulseMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||
ViewHolder viewHolder;
|
||||
if (convertView == null) {
|
||||
viewHolder = new ViewHolder();
|
||||
convertView = inflater.inflate(R.layout.view_pulse_marker, parent, false);
|
||||
viewHolder.foregroundImageView = (ImageView) convertView.findViewById(R.id.foreground_imageView);
|
||||
viewHolder.backgroundImageView = (ImageView) convertView.findViewById(R.id.background_imageview);
|
||||
convertView.setTag(viewHolder);
|
||||
}
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
ImageView foregroundImageView;
|
||||
ImageView backgroundImageView;
|
||||
}
|
||||
}
|
||||
|
||||
private interface GeocodeCallbacks {
|
||||
void onResult(String result);
|
||||
|
||||
void onFailure(Throwable failure);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mapbox.mapboxsdk.testapp.model.annotations;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerView;
|
||||
|
||||
public class PulseMarkerView extends MarkerView {
|
||||
|
||||
public PulseMarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
|
||||
super(baseMarkerViewOptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.mapbox.mapboxsdk.testapp.model.annotations;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
|
||||
public class PulseMarkerViewOptions extends BaseMarkerViewOptions<PulseMarkerView, PulseMarkerViewOptions> {
|
||||
|
||||
public PulseMarkerViewOptions() {
|
||||
}
|
||||
|
||||
protected PulseMarkerViewOptions(Parcel in) {
|
||||
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
|
||||
snippet(in.readString());
|
||||
title(in.readString());
|
||||
flat(in.readByte() != 0);
|
||||
anchor(in.readFloat(), in.readFloat());
|
||||
selected = in.readByte() != 0;
|
||||
rotation(in.readFloat());
|
||||
if (in.readByte() != 0) {
|
||||
// this means we have an icon
|
||||
String iconId = in.readString();
|
||||
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
|
||||
Icon icon = IconFactory.recreate(iconId, iconBitmap);
|
||||
icon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PulseMarkerViewOptions getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeParcelable(getPosition(), flags);
|
||||
out.writeString(getSnippet());
|
||||
out.writeString(getTitle());
|
||||
out.writeByte((byte) (isFlat() ? 1 : 0));
|
||||
out.writeFloat(getAnchorU());
|
||||
out.writeFloat(getAnchorV());
|
||||
out.writeFloat(getInfoWindowAnchorU());
|
||||
out.writeFloat(getInfoWindowAnchorV());
|
||||
out.writeByte((byte) (selected ? 1 : 0));
|
||||
out.writeFloat(getRotation());
|
||||
Icon icon = getIcon();
|
||||
out.writeByte((byte) (icon != null ? 1 : 0));
|
||||
if (icon != null) {
|
||||
out.writeString(getIcon().getId());
|
||||
out.writeParcelable(getIcon().getBitmap(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PulseMarkerView getMarker() {
|
||||
return new PulseMarkerView(this);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
|
||||
= new Parcelable.Creator<CountryMarkerViewOptions>() {
|
||||
public CountryMarkerViewOptions createFromParcel(Parcel in) {
|
||||
return new CountryMarkerViewOptions(in);
|
||||
}
|
||||
|
||||
public CountryMarkerViewOptions[] newArray(int size) {
|
||||
return new CountryMarkerViewOptions[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
|
||||
<scale
|
||||
android:duration="1000"
|
||||
android:fromXScale="1"
|
||||
android:fromYScale="1"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="50%"
|
||||
android:repeatCount="infinite"
|
||||
android:repeatMode="restart"
|
||||
android:toXScale="1.8"
|
||||
android:toYScale="1.8"/>
|
||||
|
||||
<set android:startOffset="200">
|
||||
<alpha
|
||||
android:duration="800"
|
||||
android:fromAlpha="1.0"
|
||||
android:repeatCount="infinite"
|
||||
android:repeatMode="restart"
|
||||
android:toAlpha="0.0"/>
|
||||
</set>
|
||||
</set>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
|
||||
<solid
|
||||
android:color="@color/mapbox_blue"/>
|
||||
|
||||
<size
|
||||
android:width="@dimen/circle_size"
|
||||
android:height="@dimen/circle_size"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearDisplayViewButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_clear_24dp"
|
||||
android:background="@color/accent"
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="@dimen/full_button_margin"
|
||||
android:layout_above="@+id/selectLocationButton"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/selectLocationButton"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/full_button_margin"
|
||||
android:background="@color/primary"
|
||||
android:text="@string/navigation_select_location_button_text"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/foreground_imageView"
|
||||
android:layout_width="@dimen/circle_size"
|
||||
android:layout_height="@dimen/circle_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_circle"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/background_imageview"
|
||||
android:layout_width="@dimen/circle_size"
|
||||
android:layout_height="@dimen/circle_size"
|
||||
android:layout_gravity="center"
|
||||
android:alpha="0.5"
|
||||
android:src="@drawable/ic_circle"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="circle_size">24dp</dimen>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
<dimen name="full_button_margin">8dp</dimen>
|
||||
<dimen name="attr_margin">10dp</dimen>
|
||||
<dimen name="coordinatebounds_margin">32dp</dimen>
|
||||
<dimen name="map_padding_left">96dp</dimen>
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
<string name="activity_directions">Directions</string>
|
||||
<string name="activity_geocoder">Geocoder</string>
|
||||
|
||||
<!-- Navigation -->
|
||||
<string name="activity_location_picker">Location Picker</string>
|
||||
|
||||
<!-- Other -->
|
||||
<string name="activity_double_map">Double Map Activity</string>
|
||||
<string name="activity_back_to_map">Back to map activity</string>
|
||||
@@ -82,7 +85,7 @@
|
||||
<string name="description_back_to_map">Restart map view after temporarily leaving to another activity</string>
|
||||
<string name="description_view_marker">Use an Android SDK View as marker</string>
|
||||
<string name="description_dynamic_info_window_adapter">Learn how to create a dynamic custom InfoWindow</string>
|
||||
|
||||
<string name="description_location_picker">Use a fixed Marker to select your location</string>
|
||||
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>
|
||||
<string name="menuitem_title_deselect_markers_on_tap">Deselect Markers On Tap</string>
|
||||
<string name="menuitem_title_tracking_mode_dismiss_on_gesture">Dismiss location tracking on gesture</string>
|
||||
@@ -101,6 +104,7 @@
|
||||
<string name="category_maplayout">Map Layout</string>
|
||||
<string name="category_offline">Offline</string>
|
||||
<string name="category_userlocation">User Location</string>
|
||||
<string name="category_navigation">Navigation</string>
|
||||
|
||||
<string name="action_visible_bounds_explanation">Center map around 2 markers</string>
|
||||
<string name="action_remove_polylines">Remove polylines</string>
|
||||
@@ -162,4 +166,6 @@
|
||||
<string name="dynamic_marker_arsenal_title">Arsenal</string>
|
||||
<string name="dynamic_marker_arsenal_snippet">Emirates Stadium</string>
|
||||
|
||||
<string name="navigation_select_location_button_text">Select Location!</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.0'
|
||||
classpath 'com.android.tools.build:gradle:2.1.2'
|
||||
classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a7072df3ed16dc8466fb144f2817070'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
Reference in New Issue
Block a user