簡體   English   中英

計算兩點之間的距離

[英]Calculating distance between two points

我知道之前曾有人問過這個問題,但是對於什么是正確的,什么是錯誤的,我的看法不一,

我正在嘗試使用“開始”和“停止”兩個按鈕來計算應用中兩點之間的距離。

我認為這很簡單,按下開始時獲取位置的緯度和經度,然后按下停止時再次獲取它們的緯度,計算兩者和乘積。 但是,它不會計划。

單擊停止按鈕以獲取反饋時,我已經在“停止”按鈕上設置了一個對話框,目前,我僅返回(大概)一個緯度或經度。

我的代碼如下:

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

Location具有distanceTo 用戶按下開始時,注冊從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;
 }

}

您對startRun()不執行任何操作,您希望發生什么?

我建議您使用onLocationChanged()使LatLng / Location保持最新。 startRun()您可以

startLocation = currentLocation

在stopRun你

stopLocation = currentLocation

那真的就是所有這些。 現在,您將緯度和經度設置到最后一個已知的位置,我懷疑這是您要執行的操作,並且從未設置過stopLat和stopLon afai可以看到的位置。

嘗試這個:

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 long。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM