问题
I am using drawable images for marker icons on a route. The base of the image does not appear at the point but rather more in the middle.
Can this be addressed?
Double latitude = new Double(getString(R.string.sagrada_latitude));
Double longitude = new Double(getString(R.string.sagrada_longitude));
final Position origin = Position.fromCoordinates(longitude, latitude);
latitude = new Double(getString(R.string.mataro_latitude));
longitude = new Double(getString(R.string.mataro_longitude));
final Position destination = Position.fromCoordinates(longitude, latitude);
// Create an Icon object for the marker to use
IconFactory iconFactory = IconFactory.getInstance(this);
Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.green_pin);
final Icon greenPinIcon = iconFactory.fromDrawable(iconDrawable);
iconDrawable = ContextCompat.getDrawable(this, R.drawable.red_pin);
final Icon redPinIcon = iconFactory.fromDrawable(iconDrawable);
// Setup the MapView
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(MapboxMap mapboxMap) {
map = mapboxMap;
// Add origin and destination to the map
LatLng originLatLng = (new LatLng(origin.getLatitude(), origin.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(originLatLng)
.title("Origin")
.snippet("current location: (" + origin.getLatitude() + ", " + origin.getLongitude() + ")")
.icon(greenPinIcon));
Log.d(TAG, "getMapAsync(): destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")");
LatLng destinationLatLng = (new LatLng(destination.getLatitude(), destination.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 5000);
// Get route from API
try {
getRoute(origin, destination);
}
catch (ServicesException servicesException) {
Log.e(TAG, servicesException.toString());
servicesException.printStackTrace();
}
}
});
}
private void getRoute(Position origin, Position destination) throws ServicesException {
client = new MapboxDirections.Builder()
.setOrigin(origin)
.setDestination(destination)
.setProfile(DirectionsCriteria.PROFILE_CYCLING)
.setAccessToken(MapboxAccountManager.getInstance().getAccessToken())
.build();
client.enqueueCall(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().getRoutes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
// Print some info about the route
currentRoute = response.body().getRoutes().get(0);
Log.d(TAG, "Distance: " + currentRoute.getDistance());
Double km = currentRoute.getDistance() / 1000;
// there are 4 digits to the right of the decimal, make it 2
String kilometers = km.toString();
int index = kilometers.lastIndexOf(".");
kilometers = kilometers.substring(0, index + 3);
Toast.makeText(
DirectionsActivity.this,
"Route is " + kilometers + " kilometers",
Toast.LENGTH_SHORT).show();
// Draw the route on the map
drawRoute(currentRoute);
}
@Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
Toast.makeText(DirectionsActivity.this, "Error: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
A side question ... the Position.fromCoordinates method:
private Position(double longitude, double latitude, double altitude)
takes the arguments in order of longitude then latitude, not latitude then longitude as one might expect. Why?
Edit:
Changed MarkerOptions to MarkerViewOptions and the icons moved even further away. Also tried .anchor(0,0) which had no effect.
Also, with default Icons (which are off):
Icon:
// Mapbox dependencies
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:4.1.1@aar') {
transitive = true
}
compile ('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar'){
transitive=true
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.3.1@aar') {
transitive = true
}
回答1:
You either need to add padding to the bottom of the marker icon png or a better option would be using MarkerViewOptions() instead. They give more options then the GL markers your currently using including anchor. By default the anchoring is center bottom. So one of you markers would look like this:
mapboxMap.addMarker(new MarkerViewOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
To answer your other question, why position takes in longitude, latitude in that order, many of the Mapbox APIs consume coordinates in that order. The bigger question is why does the Position object exist when LatLng is found already in the Map SDK? This is because the objects would conflict since they are found in separate SDKs yet are typically used together. It is something we look forward to changing in the near future.
EDIT: first you need to remove the mapbox-android-directions, this is an old, non supported, SDK we have deprecated. Mapbox Android Services (MAS) is it's replacement and uses Mapbox Directions V5. Use this example which shows how to properly make a directions call using MAS and add the markers to the map. Using the coordinates found in your question, the result looks like this:
来源:https://stackoverflow.com/questions/40351003/drawable-icons-on-route-not-pinned-at-base