5

I am trying to crate a app like ola/uber. I want to move the icon and rotate when road turn left or right. I am using following code.

private void rotateMarker(final Marker marker, final float toRotation) {
        if(!isMarkerRotating) {
            final Handler handler = new Handler();
            final long start = SystemClock.uptimeMillis();
            final float startRotation = marker.getRotation();
            final long duration = 1000;

            final Interpolator interpolator = new LinearInterpolator();

            handler.post(new Runnable() {
                @Override
                public void run() {
                    isMarkerRotating = true;

                    long elapsed = SystemClock.uptimeMillis() - start;
                    float t = interpolator.getInterpolation((float) elapsed / duration);

                    float rot = t * toRotation + (1 - t) * startRotation;

                    marker.setRotation(-rot > 180 ? rot / 2 : rot);
                    if (t < 1.0) {
                        // Post again 16ms later.
                        handler.postDelayed(this, 16);
                    } else {
                        isMarkerRotating = false;
                    }
                }
            });
        }
    }

To calculate bearing:

        currentLocation = location;
        if(previousLocaton!=null){
            previousLocaton = tempLocation;
            tempLocation = currentLocation;

            Log.d("previousLocaton=====> ",""+previousLocaton);
            Log.d("currentLocation=====> ",""+currentLocation);

            bearing = previousLocaton.bearingTo(currentLocation) ;
        }else{
            previousLocaton = location;
            tempLocation = location;
        }

To set the bearing:

CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(latLng).zoom(14).bearing(bearing).build();

To rotate the marker I call roateMarker method in onLocationChanged changed method:

        currLocationMarker = mMap.addMarker(markerOptions);
        rotateMarker(currLocationMarker,bearing);

Now my icon is rotating. But google map also get rotating. I want rotate icon alone. I refer the following link for animate and move the marker. Link 1. Please let me any idea to solve my issue.

Community
  • 1
  • 1
Vijay
  • 3,152
  • 3
  • 24
  • 33

4 Answers4

6

there is simple method available for marker

marker.rotation(float value)

Sets the rotation of the marker in degrees clockwise about the marker's anchor point. The axis of rotation is perpendicular to the marker. A rotation of 0 corresponds to the default position of the marker. When the marker is flat on the map, the default position is North aligned and the rotation is such that the marker always remains flat on the map. When the marker is a billboard, the default position is pointing up and the rotation is such that the marker is always facing the camera. The default value is 0.

raj
  • 2,088
  • 14
  • 23
  • Hi.. Sorry for long break.. this too working fine. But I am facing another issue. I replace the marker for every 5 second. When I replace the marker, the marker position is start with it's real position. For ex my marker is arrow mark default it indicate top angel. When I move from one place to another place my marker rotates and suddenly it start with top angel. Please let me any idea to resolve this issue. – Vijay Jan 30 '17 at 10:15
  • Hi! I use the thread for that. I track the mark location and store it in my data base. On Google maps fragment, I fetch the mark last location from my data base and use it as position 2 (what means for the next fetch this will be position 1) – ilidiocn Nov 24 '21 at 06:03
1

To rotate only the marker set rotation to marker using setRotation(float) method.

static public void rotateMarker(final Marker marker, final float toRotation) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final float startRotation = marker.getRotation();
        final long duration = 1000;

        final Interpolator interpolator = new LinearInterpolator();
        L.d("Bearing: "+toRotation);

        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed / duration);

                float rot = t * toRotation + (1 - t) * startRotation;
                marker.setRotation(-rot > 180 ? rot / 2 : rot);
                if (t < 1.0) {
                    // Post again 10ms later.
                    handler.postDelayed(this, 10);
                }
            }
        });
    }
Suresh Kumar
  • 2,014
  • 3
  • 19
  • 32
  • Yes, just remove this code CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(14).bearing(bearing).build(); – Suresh Kumar Jan 04 '17 at 10:34
  • If you dont want to rotate map but update the location, then use this code instead CameraPosition cameraPosition = new CameraPosition.Builder() .target(latLng).zoom(14).build(); – Suresh Kumar Jan 04 '17 at 10:36
  • Hi.. Sorry for long break.. It's working fine. But I am facing another issue. I replace the marker for every 5 second. When I replace the marker, the marker position is start with it's real position. For ex my marker is arrow mark default it indicate top angel. When I move from one place to another place my marker rotates and suddenly it start with top angel. Please let me any idea to resolve this issue. – Vijay Jan 30 '17 at 10:15
  • You can set anchor to your marker. Try setting like this marker.setAnchor(0.5f, 0.5f); – Suresh Kumar Jan 30 '17 at 12:56
1

Try this :

public void animateMarker(final LatLng toPosition, final LatLng startLatLng,
                          final boolean hideMarker) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    Projection proj = map.getProjection();
    Point startPoint = proj.toScreenLocation(d_marker.getPosition());
    final LatLng startLatLng = proj.fromScreenLocation(startPoint);
    //   final CameraPosition newcameraPosition = null;

    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);

            System.out.println("Locations ---- " + prevLoc + "-" + newLoc);

            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;
            d_marker.setPosition(new LatLng(lat, lng));
            d_marker.setRotation(bearing);
            d_marker.setFlat(true);
            //   googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(newcameraPosition));


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


}
Bhavin Sorathiya
  • 141
  • 1
  • 12
1

Try Below method:

 public void animateMarker(final LatLng toPosition,
                          final boolean hideMarker) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    Projection proj = googleMap.getProjection();
    Point startPoint = proj.toScreenLocation(cabMarker.getPosition());
    final LatLng startLatLng = proj.fromScreenLocation(startPoint);
 //   final CameraPosition newcameraPosition = null;

    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);

            System.out.println("Locations ---- " + prevLoc + "-" + newLoc);

            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;
            cabMarker.setPosition(new LatLng(lat, lng));


            cabMarker.setRotation(bearing);
         //   googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(newcameraPosition));


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


}