计算两点之间的距离

时间:2013-05-10 12:23:13

标签: java android google-maps

我知道之前有人问过这个问题,但是我对这些问题的看法不一致,而且没有,

我正在尝试使用两个按钮“开始和停止”来计算我的应用中两点之间的距离。

我认为这很简单,在按下开始时获取lat和long的位置,然后在按下stop时再次获取它们,计算两者并瞧。然而,它不打算计划。

我点击停止按钮时设置了一个对话框,以便反馈,目前我只返回(大概)一个纬度或经度。

我的代码如下::

 public class MapRun extends FragmentActivity implements LocationListener,
            LocationSource {
        private OnLocationChangedListener mListener;
        private LocationManager locationManager;

        private GoogleMap mMap;
        double lat, lng;
        static double startLat;
        double startLong;
        double stopLat;
        double stopLong;
        public static Location l;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.maprun);

            locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
            // Creating a criteria object to retrieve provider
            Criteria criteria = new Criteria();

            // Getting the name of the best provider
            String provider = locationManager.getBestProvider(criteria, true);

            // Getting Current Location
            Location location = locationManager.getLastKnownLocation(provider);

            l = location;
            lat = l.getLatitude();
            lng = l.getLongitude();

            onLocationChanged(location);
            locationManager.requestLocationUpdates(provider, 20000, 0, this);

            setUpMapIfNeeded();
        }

        @Override
        public void onPause() {
            if (locationManager != null) {
                locationManager.removeUpdates(this);
            }

            super.onPause();
        }

        @Override
        public void onResume() {
            super.onResume();

            setUpMapIfNeeded();

            if (locationManager != null) {
                mMap.setMyLocationEnabled(true);
            }
        }

        /**
         * Sets up the map if it is possible to do so (i.e., the Google Play
         * services APK is correctly installed) and the map has not already been
         * instantiated.. This will ensure that we only ever call
         * {@link #setUpMap()} once when {@link #mMap} is not null.
         * <p>
         * If it isn't installed {@link SupportMapFragment} (and
         * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt
         * for the user to install/update the Google Play services APK on their
         * device.
         * <p>
         * A user can return to this Activity after following the prompt and
         * correctly installing/updating/enabling the Google Play services. Since
         * the Activity may not have been completely destroyed during this process
         * (it is likely that it would only be stopped or paused),
         * {@link #onCreate(Bundle)} may not be called again so we should call this
         * method in {@link #onResume()} to guarantee that it will be called.
         */
        private void setUpMapIfNeeded() {
            // Do a null check to confirm that we have not already instantiated the
            // map.
            if (mMap == null) {
                // Try to obtain the map from the SupportMapFragment.
                mMap = ((SupportMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.map)).getMap();
                // Check if we were successful in obtaining the map.

                if (mMap != null) {
                    setUpMap();
                }

                // This is how you register the LocationSource
                mMap.setLocationSource(this);
            }
        }

        /**
         * This is where we can add markers or lines, add listeners or move the
         * camera. In this case, we just add a marker near Africa.
         * <p>
         * This should only be called once and when we are sure that {@link #mMap}
         * is not null.
         */
        private void setUpMap() {
            mMap.setMyLocationEnabled(true);
        }

        @Override
        public void activate(OnLocationChangedListener listener) {
            mListener = listener;
        }

        @Override
        public void deactivate() {
            mListener = null;
        }

        @Override
        public void onLocationChanged(Location location) {
            if (mListener != null) {
                mListener.onLocationChanged(location);

                // Move the camera to the user's location once it's available!

                mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
                        location.getLatitude(), location.getLongitude()), 16.0f));
            }
        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
            Toast.makeText(this, "provider disabled", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
            Toast.makeText(this, "provider enabled", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            // TODO Auto-generated method stub
            Toast.makeText(this, "status changed", Toast.LENGTH_SHORT).show();
        }




        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            super.onCreateOptionsMenu(menu);
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.map_menu, menu);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case R.id.startRun:

                startRun();
            case R.id.stopRun:

                stopRun();

                return true;

            default:
                return super.onOptionsItemSelected(item);
            }

        }

        public void startRun() {
            ;



        }

        public void stopRun() {
            Location startPoint = new Location("Ran From");

            startPoint.setLatitude(lat);
            startPoint.setLongitude(lng);

            Location stopPoint = new Location("Ran To");
            stopPoint.setLatitude(stopLat);
            stopPoint.setLongitude(stopLong);
            float distance = startPoint.distanceTo(stopPoint);
            String distStr = String.valueOf(distance);
            Dialog d = new Dialog(this);
            d.setTitle("distance");
            TextView tv = new TextView(this);
            tv.setText(distStr);
            d.setContentView(tv);
            d.show();

        }

到目前为止,这是我更新的按钮,我有一个原则,我认为我正在努力使用正确的方式存储和传递变量:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.startRun:
            currentLocation = lat + lng;
            startLocation = currentLocation;

        case R.id.stopRun:
            currentLocation = lat + lng;
            stopLocatio

n = currentLocation;

        float distance = startLocation.distanceTo(stopLocation);
        String distStr = String.valueOf(distance);
        Dialog d = new Dialog(this);
        d.setTitle("distance");
        TextView tv = new TextView(this);
        tv.setText(distStr);
        d.setContentView(tv);
        d.show();

        return true;

    default:
        return super.onOptionsItemSelected(item);
    }

我的OnLocationchanged:

@Override
    public void onLocationChanged(Location location) {
        l = location;
        lat = l.getLatitude();
        lng = l.getLongitude();
        if (mListener != null) {
            mListener.onLocationChanged(location);

            // Move the camera to the user's location once it's available!

            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
                    location.getLatitude(), location.getLongitude()), 16.0f));
        }
    }

3 个答案:

答案 0 :(得分:3)

LocationdistanceTo。当用户按下开始时,注册从Gps获得的位置。当用户按停止时,获取当前位置并执行:

currentLocation.distanceTo(firstLocation) ;

distanceTo返回一个浮点数,表示此位置与给定位置之间的近似距离

public class MapRun extends FragmentActivity implements LocationListener,
        LocationSource {

   Location startLocation;
   Location endLocation;

   Location currentLocation;


    @Override
    public void onLocationChanged(Location location) {
        if (mListener != null) {
            mListener.onLocationChanged(location);

            // Move the camera to the user's location once it's available!

            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
                    location.getLatitude(), location.getLongitude()), 16.0f));
        }
       currentLocation = location;
    }

 public void startRun() {
        startLocation = currentLocation;
    }

    public void stopRun() {
       stopLocation = currentLocation;
    }

 public float getDistance() {
   float distance = 0f;
   if (stopLocation != null && startLocation != null)
       distance = stopLocation.distanceTo(startLocation);
   return distance;
 }

}

答案 1 :(得分:0)

你在startRun()上什么都不做,你期望发生什么?

我建议您将LatLng / Location currentLocation与onLocationChanged()保持同步。在startRun()你做

startLocation = currentLocation

在stopRun中你做

stopLocation = currentLocation

多数民众赞成这一切。 现在,你将你的lat和lon设置为最后一个已知的位置,我怀疑你要做什么,而且你永远不会设置你的stopLat和stopLon afai可以看到。

答案 2 :(得分:0)

试试这个:

private double distance(double lat1, double lon1, double lat2, double lon2) {
    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;
    return (dist);
}

private double deg2rad(double deg) {
    return (deg * Math.PI / 180.0);
}

private double rad2deg(double rad) {
    return (rad * 180.0 / Math.PI);
}

只需在distance()方法中传递Lat。