Drawable icons on route not pinned at base

。_饼干妹妹 提交于 2019-12-12 05:07:23

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!