0

I am trying to create a Uber like app. The bus marker is showing on map but I want to move the marker and rotate smoothly when the bus turn left or right on road. I called the rotateBusMarker(dl, false) function. The findDriverLocation() function retrieve the data from firebase and shows the bus marker on map. My code is given below.

private final HashMap<String, Marker> hm = new HashMap<String, Marker>();

    private void findDriverLocation() {
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("DrvUserLocation");
        ValueEventListener listener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot ds: dataSnapshot.getChildren()){
                    if (ds.exists()) {
                        String dNum = ds.child("drvMobN").getValue(String.class);
                        double lat = ds.child("Latitude").getValue(Double.class);
                        double lng = ds.child("Longitude").getValue(Double.class);
                        LatLng dl = new LatLng(lat, lng);
                        if(hm.containsKey(dNum)) {
                            hm.get(dNum).remove();
                        }
                        busMarker = mMap.addMarker(new MarkerOptions().position(dl).title(dNum).icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_icon)));
                        hm.put(dNum, busMarker);
                        rotateBusMarker(dl, false);
                    } else {
                            Toast.makeText(StdMapsActivity.this, "Latitude and Longitude Value Not Found!.", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(StdMapsActivity.this, "Failed to get data.", Toast.LENGTH_SHORT).show();
            }
        };
        ref.addValueEventListener(listener);
    }

    public void rotateBusMarker(final LatLng toPosition, final boolean hideMarker) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        Projection proj = mMap.getProjection();
        Point startPoint = proj.toScreenLocation(busMarker.getPosition());
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);
        final Interpolator interpolator = new LinearInterpolator();

        handler.post(new Runnable() {
            @Override
            public void run() {
                Location prevLoc = new Location("service Provider");
                prevLoc.setLatitude(startLatLng.latitude);
                prevLoc.setLongitude(startLatLng.longitude);

                Location newLoc = new Location("service Provider");
                newLoc.setLatitude(toPosition.latitude);
                newLoc.setLongitude(toPosition.longitude);

                float bearing = prevLoc.bearingTo(newLoc);

                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed / 1000);
                double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude;
                double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude;
                busMarker.setPosition(new LatLng(lat, lng));
                busMarker.setRotation(bearing);

                if (t < 1.0) {
                    // Post again 16ms later.
                    handler.postDelayed(this, 16);
                } else {
                    if (hideMarker) {
                        busMarker.setVisible(false);
                    } else {
                        busMarker.setVisible(true);
                    }
                }
            }
        });
    }

1 Answers1

0

It looks like you will have to create a custom animator class for the marker.

Demo and code sample from previous StackOverflow question here