провести линию маршрута между широтой и долготой реального времени - PullRequest
0 голосов
/ 14 апреля 2020

теперь я получаю широту и долготу n раз, если я перемещаюсь с моим телефоном, маркер также перемещается в соответствии с широтой и долготой, но мне нужно нарисовать линию маршрута, если телефон изменит положение. пример У меня есть точки T1, T2, T4, T5, широта и долгота, мне нужно нарисовать линию маршрута от T1 до T2 и от T2 до T3 и от T3 до T4. В режиме реального времени я не могу нарисовать линии .

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

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

1 Ответ

1 голос
/ 14 апреля 2020

Подумайте о замене метода addLines на этот, который сохраняет и повторяет aws ломаную линию при каждом обновлении:

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

Вы addLine просто рисовали одну точку на каждом вызове - одну точку вряд ли будет виден.

Вероятно, нужно вызывать его только в методе showMarker - не уверен, почему вы вызываете addLines в методах камеры.

...