Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to rotate marker(bus) according to direction?

From Below Code I am adding marker on map and every 15 seconds its refreshing and getting new latitude and longitude from database. Marker(Bus Image) are successfully adding on map and moving smoothly from one position to another position like car goes on road. Now what I want that I want to rotate bus marker according to direction. How can I achieve this? I am not getting what is the value of toRotation and st ?

public Runnable runLocation = new Runnable() {
        @Override
        public void run() {
            gps = new GPSTracker(MapActivity.this);
            MyLocation1.clear();
            if (gps.CanGetLocation()) {
                double latitude = gps.getLatitude();
                double longitude = gps.getLongitude();
                LatLng mylocation = new LatLng(latitude, longitude);
                if (marker != null) {
                    marker.remove();
                }
                if (circle != null) {
                    circle.remove();
                }
                if (busMarker != null){
                    lastBusPos = busMarker.getPosition();
                }

                marker = mMap.addMarker(new MarkerOptions()
                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.location))
                        .title("My Location")
                        .position(mylocation));

                circle = mMap.addCircle(new CircleOptions()
                        .center(mylocation)
                        .radius(1000)
                        .strokeColor(0x10000000)
                        .fillColor(0x10000000));
            } else {
                // gps.showSettingsAlert();
            }

            String tag_json_obj = "json_obj_req";
            String url = AppConfig.RouteData + "i=1&" + "y=1";

            JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    try {

                        JSONObject jObj = new JSONObject(String.valueOf(response));
                        JSONArray json_user = jObj.getJSONArray("Message");
                        for (int i = 0; i < json_user.length(); i++) {

                            try {

                                JSONObject obj = json_user.getJSONObject(i);

                                final Double currLat = obj.getDouble("actual_lat");
                                final Double currLong = obj.getDouble("actual_long");
                                final LatLng hcmus = new LatLng(currLat, currLong);


                                List<LatLng> latList = new ArrayList<LatLng>();
                                latList.add(hcmus);

                                if (mMarkers.size() != json_user.length()) {
                                    busMarker = mMap.addMarker(new MarkerOptions()
                                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus))
                                            .title("Bus No" + obj.getString("bus_id"))
                                            .position(hcmus));
                                    mMarkers.add(busMarker);
                                } else {
                                    //busMarker.setPosition(hcmus);
                                    animateMarker(hcmus, false);
                                    rotateMarker(busMarker, 45.0f, 45.0f);
                                }

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(MapActivity.this, "Sorry something went wrong..Try again", Toast.LENGTH_SHORT).show();
                }
            });

            // Adding request to request queue
            AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

            MapActivity.this.handler.postDelayed(MapActivity.this.runLocation, 15000);
        }

    };

    /*-------------------------------Animation----------------------------*/
    public void rotateMarker(final Marker marker, final float toRotation, final float st) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        final float startRotation = st;
        final long duration = 1555;

        final Interpolator interpolator = new LinearInterpolator();

        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 16ms later.
                    handler.postDelayed(this, 16);
                }
            }
        });
    }

    public void animateMarker(final LatLng toPosition,final boolean hideMarke) {
        final Handler handler = new Handler();
        final long start = SystemClock.uptimeMillis();
        Projection proj = mMap.getProjection();
        Point startPoint = proj.toScreenLocation(lastBusPos);
        final LatLng startLatLng = proj.fromScreenLocation(startPoint);
        final long duration = 5000;

        final Interpolator interpolator = new LinearInterpolator();

        handler.post(new Runnable() {
            @Override
            public void run() {
                long elapsed = SystemClock.uptimeMillis() - start;
                float t = interpolator.getInterpolation((float) elapsed
                        / duration);
                double lng = t * toPosition.longitude + (1 - t)
                        * startLatLng.longitude;
                double lat = t * toPosition.latitude + (1 - t)
                        * startLatLng.latitude;
                busMarker.setPosition(new LatLng(lat, lng));

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

    /*--------------------------------------------------------------------*/
like image 320
Moin Khan Avatar asked Apr 05 '17 07:04

Moin Khan


2 Answers

You may refer with this related thread. Use bearing of the Location object then set it to the CameraPosition.

If you use GPS for locating the user then the Location object you get in onLocationChanged contains the bearing.

If you only have the two coordinates (e.g. you only have coordinates from network location provider), you can use Location.bearingTo() to calculate the bearing of two coordinates:

Location prevLoc = ... ;
Location newLoc = ... ;
float bearing = prevLoc.bearingTo(newLoc) ;

If you have a bearing, you can set the rotation of the marker using MarkerOptions.rotation():

mMap.addMarker(new MarkerOptions()
                    .position(markerLatLng)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker))
                    .anchor(0.5f, 0.5f)
                    .rotation(bearing)
                    .flat(true));

You have to set the anchor to the point you want to rotate around, and it's also the point you want to be at the position you set to the marker. (0.5, 0.5) is the center of the image.

Here are some posts which might also help:

  • Change Google map marker orientation according path direction
  • Rotate marker as per user direction on Google Maps V2 Android
like image 161
abielita Avatar answered Oct 16 '22 01:10

abielita


Try below code. It's very easy to implement.

Here latLng1=old your location & latLng2=your new location.

Step=1

 private double getBearingBetweenTwoPoints1(LatLng latLng1, LatLng latLng2) {

        double lat1 = degreesToRadians(latLng1.latitude);
        double long1 = degreesToRadians(latLng1.longitude);
        double lat2 = degreesToRadians(latLng2.latitude);
        double long2 = degreesToRadians(latLng2.longitude);


        double dLon = (long2 - long1);


        double y = Math.sin(dLon) * Math.cos(lat2);
        double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
                * Math.cos(lat2) * Math.cos(dLon);

        double radiansBearing = Math.atan2(y, x);


        return radiansToDegrees(radiansBearing);
    }

Step=2

private double degreesToRadians(double degrees) {
        return degrees * Math.PI / 180.0;
    }

Step=3

private double radiansToDegrees(double radians) {
    return radians * 180.0 / Math.PI;
}

Step=4 Set your marker rotation.

 mPositionMarker.setRotation((float) getBearingBetweenTwoPoints1(new LatLng(lastLocLati, lastLocLongi), new LatLng(lati, longi)));
like image 1
Jiks Avatar answered Oct 16 '22 01:10

Jiks