使用gps数据使用纬度和经度计算距离。

时间:2013-09-16 07:47:49

标签: android

我正在尝试使用gps lat和长数据计算距离。

但我无法得到准确的结果。当我获得静态数据时,距离公式工作完美,

public class NWDService extends Service implements LocationListener {


    private LocationManager myLocationManager;
    private LocationProvider myLocationProvider;

    NotificationManager myNotificationManager;
    private long frequency;

    private Handler handler;
    private double total_distance = 0;
    private Location currentLocation;
    public void onLocationChanged(Location newLocation) {
        try {
            System.out.println("latitude current :"+currentLocation.getLatitude());
            System.out.println("latitude current :"+currentLocation.getLongitude());
            System.out.println("latitude new  :"+newLocation.getLatitude());
            System.out.println("latitude new  :"+newLocation.getLongitude());
            System.out.println("distance total :"+total_distance);
            //System.out.println(distance(22.306813, 73.180239,22.301016, 73.177986, 'K') + " Kilometers\n");
            double diff = 0.0;
            diff = currentLocation.getLatitude()- newLocation.getLatitude();
            System.out.println("difference ::"+diff);
            if(diff != 0){

                total_distance = total_distance + distance(currentLocation.getLatitude(), currentLocation.getLongitude(), newLocation.getLatitude(), newLocation.getLatitude(), 'K');
                //total_distance =  distance(22.307309,73.181098,23.030000,72.580000,'K');
                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),"Total Distance:"+total_distance, Toast.LENGTH_LONG).show();
                    }
                });
            }

            currentLocation = newLocation;
        } catch (Exception e) {
            currentLocation = newLocation;
            e.printStackTrace();
        }
    }
      private double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
          double theta = lon1 - lon2;
          double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
          dist = Math.acos(dist);
          dist = rad2deg(dist);
          dist = dist * 60 * 1.1515;
          if (unit == 'K') {
            dist = dist * 1.609344;
          } else if (unit == 'N') {
            dist = dist * 0.8684;
            }
          return (dist);
        }

        /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
        /*::  This function converts decimal degrees to radians             :*/
        /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
        private double deg2rad(double deg) {
          return (deg * Math.PI / 180.0);
        }

        /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
        /*::  This function converts radians to decimal degrees             :*/
        /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
        private double rad2deg(double rad) {
          return (rad * 180.0 / Math.PI);
        }

    private void myNotify(String text) {
        Notification notif = new Notification(R.drawable.ic_launcher, text, System
                .currentTimeMillis());
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, Home.class), 0);
        notif.setLatestEventInfo(this, "NotWhileDriving", text, contentIntent);
        // notif.defaults = Notification.DEFAULT_VIBRATE;
        myNotificationManager.notify((int) System.currentTimeMillis(), notif);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        handler = new Handler();

        android.util.Log.d("NWD", "creating");

        myLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        System.out.println("location manager:"+myLocationManager.getAllProviders());
        myLocationProvider = myLocationManager.getProvider("gps");
        myNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        updatePreferences();
    }
    public void updatePreferences() {
        // sync local variables with preferences
        android.util.Log.d("NWD", "updating preferences");
        frequency = 10;
        // update the LM with the new frequency
        myLocationManager.removeUpdates(this);
        myLocationManager.requestLocationUpdates(myLocationProvider.getName(),frequency, 0, this);

    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        android.util.Log.d("NWD", "destroying");
        myLocationManager.removeUpdates(this);
        myNotify("stopping");
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        android.util.Log.d("NWD", "starting");

        currentLocation = myLocationManager
                .getLastKnownLocation(myLocationProvider.getName());

        myNotify("starting"); 
    }

    public void onProviderDisabled(String arg0) {

    }

    public void onProviderEnabled(String arg0) {

    }

    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {

    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null; // this is for heavy IPC, not used
    }
}

请帮我解决我的代码中的问题...

3 个答案:

答案 0 :(得分:6)

只需使用Location.distanceTo(Location),它就会在两个不同的Location之间提供真正的距离。

答案 1 :(得分:0)

首先,我不相信这段代码适用于地球的不同部分。我没有看到WGS 84参数,只有

中的一些幻数
 dist = dist * 60 * 1.1515;
 if (unit == 'K') {
     dist = dist * 1.609344;
 } else if (unit == 'N') {
     dist = dist * 0.8684;
 }

你从哪里得到的?你明白吗?

其次,如果你的数据有噪音,你可以通过总计totalDistance来加总这个噪音。您可能想要检查距离是否超过某个阈值,并且只有在超出距离阈值时才添加totalDistance。

答案 2 :(得分:0)

您可以使用Google距离矩阵API查找两个地方之间距离的准确结果。

您可以参考详细研究:

https://developers.google.com/maps/documentation/distancematrix/