Luko91
Luko91

Reputation: 11

Orientation towards a GPS point and calculation of the distance to it

I wanted to try to create a way to be oriented towards a GPS point that I previously acquired with LOCATION. I would like the navigator cursor to detect where I am moving with respect to the point of arrival and to calculate the distance between me and the point. I've already tried to read and see some tutorials but I couldn't solve anything. I have already acquired my destination GPS position using LocationManager.getLastKnownLocation, but then the cursone does not point to that point but to a random point and when I try to calculate the distance between me and the destination position with distanceTo () gives me values very high since I'm testing in the garden I walk a few meters away and he gives me much higher distances.

Another thing I don't understand is why the acquisition of LocationManager.getLastKnownLocation is not immediate and gives me values ​​of 0 for more than 20 seconds and several clicks on the button to receive the data. Then using onLocationChanged I checked the changes to acquire new GPS points that I use to compare them with the destination GPS to calculate the cursor angle and distance.

Below is the code I've written so far but it doesn't work.

    import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.GeomagneticField;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Objects;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.location.LocationManager.GPS_PROVIDER;
import static com.dooale.testcompass2.R.*;
import static com.dooale.testcompass2.R.layout.*;

public class MainActivity extends AppCompatActivity implements LocationListener {

    // DICHIARE LE MIE VARIABILI E GLI OGGETTI DELLA MIA APP

    public ImageView imageView;
    public Double ULatitude, ULongitude, TargetLat,TargetLong;
    Context context;
    LocationManager locationManager;
    public TextView tvHeading, tvDestPos;
    public Button btDestPos;
    public Boolean Trovato = false;
    private float correntDegree = 0f;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(activity_main);

        Log.d("MyApp", "Sono dentro il mio OnCreate");

        requestPermission();

        // INIZIALIZO GLI OGGETI
        btDestPos = (Button) findViewById(id.BTposdest);
        Log.d("MyApp", "OnCreate: Ho inizializzato btDestPos");
        tvDestPos = (TextView) findViewById(id.TXposdest);
        Log.d("MyApp", "OnCreate: Ho inizializzato tvDestPos");
        tvHeading = (TextView) findViewById(id.TXHeading);
        Log.d("MyApp", "OnCreate: Ho inizializzato tvHeading");
        imageView = (ImageView) findViewById(id.compass);
        Log.d("MyApp", "OnCreate: Ho inizializzato imageView");

        // INIZIALIZZO IL MIO LOCATIONMANAGER

        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        final String bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
        Log.d("MyApp", "OnCreate: Dopo la richiesta di posizione bestProvider : " + bestProvider);


        Log.d("MyApp", "OnCreate: Ho inizializzato locationManager");

        Log.d("MyApp", "OnCreate: Gestisco il click sul bottone");
        btDestPos.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                if (!Objects.requireNonNull(locationManager).isProviderEnabled(GPS_PROVIDER)) {

                   Toast.makeText(getApplicationContext(), "NON FUNZIONA IL LOCATIONMANAGER", Toast.LENGTH_LONG).show();
                    Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:if(!Objects.requireNonNull(locationManager).isProviderEnabled(GPS_PROVIDER)) è negativo :");

                } else if (locationManager.isProviderEnabled(GPS_PROVIDER)) {

                    Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER) è positivo ");
                    Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER) lancio il metodo  getLocationProdoct();");

                    getLocationProdoct();
                    Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER)esco dal metodo  getLocationProdoct();");

                    if (Trovato) {
                        if (ULongitude == null || ULongitude == null) {

                            Toast.makeText(getApplicationContext(), "Riprova la posizione non è stata Trovata", Toast.LENGTH_LONG).show();
                            Log.v("MyApp", "OkRes_Activity:(ULongitude == 0 || ULongitude == 0): Recupero i campi Latitude e Longitude..." + " \n" +
                                    "Latitude :     " + ULatitude + "\n" +
                                    "Longitude  :    " + ULongitude);


                        }
                    }else {

                        Log.v("MyApp", "OkRes_Activity:(Trovato == true):(ULongitude == 0 || ULongitude == 0):Il valore è stato trovato Recupero i campi Latitude e Longitude..." + " \n" +
                                "Latitude :     " + ULatitude + "\n" +
                                "Longitude  :    " + ULongitude);
                    }
                }

            }
        });


    }

    private void getLocationProdoct() {
        Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Sono al interno del metodo getLocationProdoct...");


        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Lancio il getLastKnownLocation ...");
        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        locationManager.requestLocationUpdates(GPS_PROVIDER, 1000, 1, locationListener);


        Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Verifico che il campo Location non sia nullo ...");

        if (Trovato == true) {
            if (ULatitude != null || ULongitude != null) {

                //VERIFICO CHE IL I VALORI LATITUDINE E LONGITUDINE SIANO COMPILATI
                Log.v("MyApp", "OkRes_Activity:getLocationProdoct:if (Trovato == true):ULatitude != null || ULongitude != null): " + "\n" +
                        "Il valore è stato trovato Recupero i campi Latitude e Longitude..." + " \n" +
                        "Latitude :     " + ULatitude + "\n" +
                        "Longitude  :    " + ULongitude);

                String Testo = String.valueOf(ULatitude);
                Testo = Testo + " - " + String.valueOf(ULongitude);
                tvDestPos.setText(Testo);


            } else {
                Log.v("MyApp", "OkRes_Activity:getLocationProdoct:Il valore è negativo Recupero i campi Latitude e Longitude..." + " \n" +
                        "Latitude :     " + ULatitude + "\n" +
                        "Longitude  :    " + ULongitude);

            }
        } else{

            Log.v("MyApp", "OkRes_Activity:getLocationProdoct: if (Trovato == true) :"  + " \n" +
                    "NOn è ancora stato trovato il GPS Latitude e Longitude..." + " \n" +
                    "Latitude :     " + ULatitude + "\n" +
                    "Longitude  :    " + ULongitude);


        }
    }

    // METODO PER GESTIRE L'ACQUISIZIONE GPS LOCATIO
    //TODO:METODO LOCATIONLISTENER

    private final LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged: Sono al interno del metodo LocationListener...");

            //Double TargetLat = null,TargetLong= null;


            ULatitude =  location.getLatitude();
            ULongitude=  location.getLongitude();
            Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged: Il valore è negativo Recupero i campi Latitude e Longitude..." + " \n" +
                    "Latitude :     " + ULatitude + "\n" +
                    "Longitude  :    " + ULongitude);

            if (ULatitude != null || ULongitude != null){
                Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null: " +
                                         "Sono entrato nella condizione perchè ha trovato il punto GPS ");
                if (Trovato == false) {
                    Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null " + "\n" +
                            "Ma non fermo il  LocationListener...");
                    TargetLat = ULatitude;
                    TargetLong = ULongitude;
                    String Testo = String.valueOf(ULatitude);
                    Testo = Testo + " - " + String.valueOf(ULongitude);
                    tvDestPos.setText(Testo);
                    //locationManager.removeUpdates(this);
                    Trovato = true;
                    Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:if (ULatitude != null || ULongitude != null):" +
                                              "IF(Trovato == false)Chiamo la Funzione RotationCompass  ");
                    //new RotationCompass(context,TargetLat,TargetLong,ULongitude,ULatitude,imageView,tvHeading);
                    Rotation();
                } else {
                    Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null: " +
                                              "Trovato = TRUE  quindi attivo la frunzione TRAKER e aggiorno costantemente il puntatore GPS e chiamo  RotationCompass ");
                    //new RotationCompass(context, TargetLat, TargetLong, ULongitude,ULatitude,imageView,tvHeading);
                    Rotation();

                }

            }

        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }
        @Override
        public void onProviderDisabled(String s) {
}

};

    private void Rotation() {

        Log.v("MyApp", "OkRes_Activity:Rotation(): Sono al interno del metodo Rotation()...");
        Log.v("MyApp", "OkRes_Activity:Rotation(): Inizilizzo le 2 Location...");

        Location UserLoc = new Location("service Provider");
        Location DestinLoc =new Location("service Provider");

        UserLoc.setLatitude(ULatitude);
        UserLoc.setLongitude(ULongitude);

        DestinLoc.setLatitude(TargetLat);
        DestinLoc.setLongitude(TargetLong);

        Log.v("MyApp", "OkRes_Activity:Rotation():Inizializzo bearTO...");

        Float bearTO=UserLoc.bearingTo(DestinLoc);

        Log.v("MyApp", "OkRes_Activity:Rotation(): bearTO è ..." + bearTO);

        Log.v("MyApp", "OkRes_Activity:Rotation(): Calocolo la distanza con destinatioTo ...");

        Float DestinTO= UserLoc.distanceTo(DestinLoc);

        Log.v("MyApp", "OkRes_Activity:Rotation(): destinatioTo ..." + DestinTO);
Log.v("MyApp", "OkRes_Activity:Rotation():Inizializzo il GeomagneticFieald...");


        GeomagneticField geoField= new GeomagneticField(Double.valueOf(UserLoc.getLatitude()).floatValue(),
                Double.valueOf(UserLoc.getLongitude()).floatValue(),
                Double.valueOf(UserLoc.getAltitude()).floatValue(),
                System.currentTimeMillis());

         Float head =+ geoField.getDeclination();

        Log.v("MyApp", "OkRes_Activity:Rotation(): head è ..." + head);

        if (bearTO<0){
            bearTO=bearTO+360;
            Log.v("MyApp", "OkRes_Activity:Rotation():if (bearTO<0): bearTO è ..." + bearTO);
        }

        float direction= bearTO - head;

        Log.v("MyApp", "OkRes_Activity:Rotation(): direction è ..." + direction);


        if (direction<0){
            direction = direction +360;
            Log.v("MyApp", "OkRes_Activity:Rotation():if (direction<0): direction è ..." + direction);


        }

        tvHeading.setText("Heading :  " + Float.toString(correntDegree));
        RotateAnimation rotateAnimation = new RotateAnimation(correntDegree,direction, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        rotateAnimation.setDuration(210);
        rotateAnimation.setRepeatCount(0);
        rotateAnimation.setFillAfter(true);

        imageView.startAnimation(rotateAnimation);
        correntDegree = direction;
        Log.v("MyApp", "OkRes_Activity:Rotation(): correntDegree è ..." + correntDegree);

    }

public void requestPermission() {
      Log.d("MyApp", "Sono dentro in requestPermission");
      ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);


    }


    @Override
    public void onLocationChanged(Location location) {

   Log.d("MyApp", "OnCreate:onLocationChanged: Sono dentro il onLocationChanged :");

        ULatitude=  location.getLatitude();
        ULongitude= location.getLongitude();

        Log.d("MyApp", "OnCreate:onLocationChanged:Ho acquisito i valori di  ULatitude : " + ULatitude + "\n"+
                                  "e il valore di ULongitude : " + ULongitude);


    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

What I ask is to help me understand where I'm wrong and give me a guide line to follow !!! I was thinking of using the ACCELEROMETER sensors to solve the problem of pointing the compass but I haven't understood yet how to use it! I thank you in advance because I have been stuck for months Thank you

Upvotes: 1

Views: 183

Answers (0)

Related Questions