-1

now i am getting latitude and longitude n time, if i move with my phone the marker also moving according latitude and longitude, but i need to draw a route line if phone change the position. example i have T1, T2, T4, T5 time latitude longitude points i need to draw route line from T1 to T2 and T2 to T3 and T3 to T4 So on in real time, i am unable draw the lines.

MainActivity

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 5445;

private GoogleMap googleMap;
private FusedLocationProviderClient fusedLocationProviderClient;
private Marker currentLocationMarker;
private Location currentLocation;
private boolean firstTimeFlag = true;

private final View.OnClickListener clickListener = view -> {
    if (view.getId() == R.id.currentLocationImageButton && googleMap != null && currentLocation != null)
        animateCamera(currentLocation);
};

private final LocationCallback mLocationCallback = new LocationCallback() {

    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
        if (locationResult.getLastLocation() == null)
            return;
        currentLocation = locationResult.getLastLocation();
        if (firstTimeFlag && googleMap != null) {
            animateCamera(currentLocation);
            firstTimeFlag = false;
        }
        showMarker(currentLocation);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapFragment);
    supportMapFragment.getMapAsync(this);
    findViewById(R.id.currentLocationImageButton).setOnClickListener(clickListener);
    mydb = new DatabaseHelper(this);

}

@Override
public void onMapReady(GoogleMap googleMap) {
    this.googleMap = googleMap;

}


private void startCurrentLocationUpdates() {
    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(3000);
//locationRequest.setFastestInterval(1000);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(this, 
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && 
ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != 
PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
            return;
        }
    }
    fusedLocationProviderClient.requestLocationUpdates(locationRequest, mLocationCallback, 
Looper.myLooper());
}

private boolean isGooglePlayServicesAvailable() {
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
    int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
    if (ConnectionResult.SUCCESS == status)
        return true;
    else {
        if (googleApiAvailability.isUserResolvableError(status))
            Toast.makeText(this, "Please Install google play services to use this application", Toast.LENGTH_LONG).show();
    }
    return false;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION) {
        if (grantResults[0] == PackageManager.PERMISSION_DENIED)
            Toast.makeText(this, "Permission denied by uses", Toast.LENGTH_SHORT).show();
        else if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            startCurrentLocationUpdates();
    }
}

private void animateCamera(@NonNull Location location) {
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(getCameraPositionWithBearing(latLng)));
    addLines(latLng);

    AddData(location);
}

@NonNull
private CameraPosition getCameraPositionWithBearing(LatLng latLng) {
    addLines(latLng);
    return new CameraPosition.Builder().target(latLng).zoom(16).build();
}

private void showMarker(@NonNull Location currentLocation) {
    LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
    BitmapDescriptor icon = 
BitmapDescriptorFactory.fromResource(R.drawable.ic_person_pin_circle_black_24dp);
    addLines(latLng);
    viewAll();
    if (currentLocationMarker == null)

        currentLocationMarker = googleMap.addMarker(new 
MarkerOptions().icon(BitmapDescriptorFactory.defaultMarker()).flat(true).position(latLng));
    else
        MarkerAnimation.animateMarkerToGB(currentLocationMarker, latLng, new LatLngInterpolator.Spherical());
}


@Override
protected void onStop() {
    super.onStop();
    if (fusedLocationProviderClient != null)
        fusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
}

@Override
protected void onResume() {
    super.onResume();
    if (isGooglePlayServicesAvailable()) {
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        startCurrentLocationUpdates();

    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    fusedLocationProviderClient = null;
    googleMap = null;
}

private void addLines(LatLng latLng) {

    LatLng TIMES_SQUARE = new LatLng(latLng.latitude, latLng.longitude);
    LatLng BROOKLYN_BRIDGE = new LatLng(latLng.latitude, latLng.longitude);
    LatLng LOWER_MANHATTAN = new LatLng(latLng.latitude, latLng.longitude);
    Log.i("===Lat", String.valueOf(latLng.latitude));
    Log.i("===Longt", String.valueOf(latLng.longitude));
    String polyLine = "q`epCakwfP_@EMvBEv@iSmBq@GeGg@}C]mBS{@KTiDRyCiBS";
    List<LatLng> polyLineList = Collections.singletonList(TIMES_SQUARE);

    LatLngBounds.Builder builder = new LatLngBounds.Builder();

    for (LatLng latLng1 : polyLineList) {
        builder.include(latLng1);


        googleMap.addPolyline((new PolylineOptions())
//.add(TIMES_SQUARE, LOWER_MANHATTAN,TIMES_SQUARE).width(5).color(Color.RED)
//.add( new LatLng(14.2354843, 76.2484165), new LatLng(14.2251, 76.3980)).width(5).color(Color.RED)
                .add(new LatLng(latLng.latitude, latLng.longitude), new LatLng(latLng.latitude, latLng.longitude)).addAll(polyLineList).width(5).color(Color.BLUE)
                .geodesic(true));

        PolylineOptions polylineOptions = new PolylineOptions();
        polylineOptions.color(Color.BLACK);
        polylineOptions.width(5);
        polylineOptions.startCap(new SquareCap());
        polylineOptions.endCap(new SquareCap());
        polylineOptions.jointType(ROUND);
        polylineOptions.addAll(polyLineList);
        Polyline greyPolyLine = googleMap.addPolyline(polylineOptions);
    }
    ;
    // move camera to zoom on map
    // googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LOWER_MANHATTAN,13));
}
}

MarkerAnimation

public class MarkerAnimation {
public static void animateMarkerToGB(final Marker marker, final LatLng finalPosition, final LatLngInterpolator latLngInterpolator) {
    final LatLng startPosition = marker.getPosition();
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final Interpolator interpolator = new AccelerateDecelerateInterpolator();
    final float durationInMs = 3000;

    handler.post(new Runnable() {
        long elapsed;
        float t;
        float v;

        @Override
        public void run() {
            // Calculate progress using interpolator
            elapsed = SystemClock.uptimeMillis() - start;
            t = elapsed / durationInMs;
            v = interpolator.getInterpolation(t);

            marker.setPosition(latLngInterpolator.interpolate(v, startPosition, finalPosition));

            // Repeat till progress is complete.
            if (t < 1) {

                // Post again 16ms later.
//handler.postDelayed(this, 16);
                handler.postDelayed(this, 16);
            }
        }
    });
}
}

LatLngInterpolator Interface

public interface LatLngInterpolator {

LatLng interpolate(float fraction, LatLng a, LatLng b);

class Spherical implements LatLngInterpolator {

    /* From github.com/googlemaps/android-maps-utils */
    @Override
    public LatLng interpolate(float fraction, LatLng from, LatLng to) {
        // http://en.wikipedia.org/wiki/Slerp
        double fromLat = toRadians(from.latitude);
        double fromLng = toRadians(from.longitude);
        double toLat = toRadians(to.latitude);
        double toLng = toRadians(to.longitude);
        double cosFromLat = cos(fromLat);
        double cosToLat = cos(toLat);

        // Computes Spherical interpolation coefficients.
        double angle = computeAngleBetween(fromLat, fromLng, toLat, toLng);
        double sinAngle = sin(angle);
        if (sinAngle < 1E-6) {
            return from;
        }
        double a = sin((1 - fraction) * angle) / sinAngle;
        double b = sin(fraction * angle) / sinAngle;

        // Converts from polar to vector and interpolate.
        double x = a * cosFromLat * cos(fromLng) + b * cosToLat * cos(toLng);
        double y = a * cosFromLat * sin(fromLng) + b * cosToLat * sin(toLng);
        double z = a * sin(fromLat) + b * sin(toLat);

        // Converts interpolated vector back to polar.
        double lat = atan2(z, sqrt(x * x + y * y));
        double lng = atan2(y, x);
        return new LatLng(toDegrees(lat), toDegrees(lng));
    }

    private double computeAngleBetween(double fromLat, double fromLng, double toLat, double toLng) {
        // Haversine's formula
        double dLat = fromLat - toLat;
        double dLng = fromLng - toLng;
        return 2 * asin(sqrt(pow(sin(dLat / 2), 2) +
                cos(fromLat) * cos(toLat) * pow(sin(dLng / 2), 2)));
    }
}
}
Lokesh GP Loki
  • 101
  • 2
  • 15
  • _"help me to find solution."_ What's currently the problem? You seem to have code to watch the devices location changes and you seem to have code to draw PolyLines on the Google Map, so most of it seems to be covered. What do you need help with? It can be difficult to tell just by looking at the pre-existing code. – Markus Kauppinen Apr 14 '20 at 11:17
  • @Markus Kauppinen lines are not drawing, unable to draw the line – Lokesh GP Loki Apr 14 '20 at 11:20
  • Your `addLines` loop seems to use only the `latLng` point for all points which does not a line make. –  Apr 14 '20 at 11:34
  • @Andy what i need to add – Lokesh GP Loki Apr 14 '20 at 11:36
  • You need to build a list - remove() and redraw as a point is added - there is no way I know of to keep adding to a previously drawn polyline. –  Apr 14 '20 at 11:39
  • @Andy how to draw line in real time, device moves i need to draw line – Lokesh GP Loki Apr 14 '20 at 11:43

1 Answers1

1

Consider replacing your addLines method with this which maintains and redraws polyline on every update:

private List<LatLng> polyLineList = new ArrayList<>();
private Polyline greyPolyLine;

private void addToLine(LatLng pt)
{
    polyLineList.add(pt);

    if (greyPolyLine != null)
    {
        greyPolyLine.remove();
    }
    PolylineOptions polylineOptions = new PolylineOptions();
    polylineOptions.color(Color.BLACK);
    polylineOptions.width(5);
    polylineOptions.startCap(new SquareCap());
    polylineOptions.endCap(new SquareCap());
    polylineOptions.jointType(ROUND);
    polylineOptions.addAll(polyLineList);
    greyPolyLine = googleMap.addPolyline(polylineOptions);
}

You addLine was simply drawing a single point on every invocation - a single point is unlikely to be visible.

Probably only need to call it in the showMarker method - not sure why you're calling addLines in the camera methods.