我知道之前有人问过这个问题,但是我对这些问题的看法不一致,而且没有,
我正在尝试使用两个按钮“开始和停止”来计算我的应用中两点之间的距离。
我认为这很简单,在按下开始时获取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));
}
}
答案 0 :(得分:3)
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;
}
}
答案 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。