如何使用谷歌地图计算用户行进的准确距离?
Posted
技术标签:
【中文标题】如何使用谷歌地图计算用户行进的准确距离?【英文标题】:How to calculate accurate distance travelled by the user using google maps? 【发布时间】:2017-07-24 08:49:08 【问题描述】:我有两个疑问,因为今天我才开始在谷歌地图上做项目,我的第一个疑问是
-
如何计算用户在使用谷歌地图时走过的距离?
就像出租车应用程序如何计算距离一样,现在让我深入解释一下我关于这个问题的问题,当用户单击签入按钮时,我在地图中有签到和签出按钮,我将获取该用户的确切纬度和经度用户结帐我将从他签出的地方获取纬度和经度,在我将此源纬度和目的地纬度发送到谷歌 api 之后,这将返回公里。但我需要的是,无论他走到哪里,他可能会多走几公里,我需要计算一下,我该怎么做。
-
我的第二个疑问是我的谷歌地图需要很长时间才能在我的地图中绘制蓝色标记,它显示在通知栏中搜索 gps 我该如何实现?
以下是我的完整代码
VisitTravel.java
public class VisitTravel extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener
private List < LatLng > obj;
private GoogleMap mGoogleMap;
private Double latitue, longtitue, Start_lat, Start_long;
private SupportMapFragment mapFrag;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private ImageView cancel_bottomsheet;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
private Bundle bundle;
private ProgressDialog progressDialog;
private String Checkin, parsedDistance, duration, JsonResponse;
private VisitDAO visitDAO;
private Long primaryID;
private ArrayList < LatLng > points;
private Integer id, flag, incidentid, userid;
private TextView heading, duration_textview, dot_source, destination, distance;
private PowerManager.WakeLock wakeLock;
private BottomSheetBehavior bottomSheetBehavior;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_visit_travel);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFrag = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
InternetCheck internetCheck = new InternetCheck();
boolean check = internetCheck.isNetworkAvailable(VisitTravel.this);
if (!check)
showAlertDialog();
else
createLocationRequest();
buildGoogleApiClient();
Settingsapi();
progressDialog = new ProgressDialog(VisitTravel.this);
// polylineOptions = new PolylineOptions();
cancel_bottomsheet = (ImageView) findViewById(R.id.cancel);
heading = (TextView) findViewById(R.id.heading);
dot_source = (TextView) findViewById(R.id.dot_source);
distance = (TextView) findViewById(R.id.distance);
duration_textview = (TextView) findViewById(R.id.duration);
destination = (TextView) findViewById(R.id.destination);
progressDialog.setMessage("Fetching Location Updates");
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
View bottomSheet = findViewById(R.id.bottom_sheet);
LoginDAO loginobj = new LoginDAO(this);
userid = loginobj.getUserID();
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
cancel_bottomsheet.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
);
bundle = getIntent().getExtras();
if (bundle != null)
flag = bundle.getInt("flag");
latitue = bundle.getDouble("destination_lat");
longtitue = bundle.getDouble("destination_long");
incidentid = bundle.getInt("incidentid");
if (flag == 1)
else
// time = bundle.getString("checkin");
id = bundle.getInt("id");
incidentid = bundle.getInt("incidentid");
Start_lat = bundle.getDouble("lat");
Checkin = bundle.getString("checkin");
Start_long = bundle.getDouble("long");
String address = bundle.getString("startaddress");
String distance = bundle.getString("estimateddistance");
setBottomSheet(address, distance);
obj = new ArrayList < > ();
final FloatingActionButton startfab = (FloatingActionButton) findViewById(R.id.start);
final FloatingActionButton stopfab = (FloatingActionButton) findViewById(R.id.stopfab);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"WakelockTag");
wakeLock.acquire();
visitDAO = new VisitDAO(getApplicationContext());
if (flag == 2)
startfab.setVisibility(View.INVISIBLE);
startfab.setBackgroundResource(R.drawable.ic_play_circle_outline_black_24dp);
final SharedPreferences preferences = getSharedPreferences("lat_long", Context.MODE_PRIVATE);
startfab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
if (mLastLocation != null)
String checkin_to_server = dateFormat.format(new Date());
Date date = null;
try
date = dateFormat.parse(checkin_to_server);
catch (ParseException e)
e.printStackTrace();
String checkin_view = dateview.format(date);
double startinglat = mLastLocation.getLatitude();
double startinglong = mLastLocation.getLongitude();
// String addres=address(startinglat,startinglong);
String jsonresponse = null;
try
jsonresponse = new GetDistance().execute(startinglat, startinglong, 12.951601, 80.184641).get();
catch (InterruptedException e)
e.printStackTrace();
catch (ExecutionException e)
e.printStackTrace();
ParserTask parserTask = new ParserTask();
if (jsonresponse != null)
Log.d("responsejson", jsonresponse);
parserTask.execute(jsonresponse);
JSONObject jsonObject = null;
try
jsonObject = new JSONObject(jsonresponse);
catch (JSONException e)
e.printStackTrace();
//Here il save the userlocation in db
catch (JSONException e)
e.printStackTrace();
else
Toast.makeText(getApplicationContext(), "Please Wait Till We Recieve Location Updates", Toast.LENGTH_SHORT).show();
);
stopfab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
if (mLastLocation != null)
double lat = mLastLocation.getLatitude();
double longt = mLastLocation.getLongitude();
String startlat = preferences.getString("startlat", "");
Log.d("startlat", startlat);
String startlong = preferences.getString("startlong", "");
// Calculating distance
String distance = getKilometer(Double.valueOf(startlat), Double.valueOf(startlong), lat, longt);
Intent intent = new Intent(VisitTravel.this, IncidentView.class);
setResult(RESULT_OK, intent);
finish();
else
Toast.makeText(getApplicationContext(), "Please Wait Fetching Location", Toast.LENGTH_SHORT).show();
);
@Override
public void onStart()
super.onStart();
Log.d("start", "onStart fired ..............");
mGoogleApiClient.connect();
private void showAlertDialog()
AlertDialog.Builder builder = new AlertDialog.Builder(VisitTravel.this);
builder.setTitle("Network Connectivity")
.setMessage("Please Check Your Network Connectivity")
.setCancelable(false)
.setNegativeButton("Close", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
Intent intent = new Intent(getApplicationContext(), IncidentView.class);
setResult(RESULT_OK, intent);
finish();
);
AlertDialog alert = builder.create();
alert.show();
@Override
public void onPause()
super.onPause();
// progressDialog.dismiss();
if (wakeLock.isHeld())
wakeLock.release();
//stop location updates when Activity is no longer active
if (mGoogleApiClient.isConnected())
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
@Override
public void onMapReady(GoogleMap googleMap)
mGoogleMap = googleMap;
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map_marker_End(12.951601, 80.184641, "Destination");
if (flag == 2)
map_marker_start(Start_lat, Start_long, Checkin);
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)
//Location Permission already granted
createLocationRequest();
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
else
//Request Location Permission
checkLocationPermission();
else
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
protected synchronized void buildGoogleApiClient()
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
protected void createLocationRequest()
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000 * 10);
mLocationRequest.setFastestInterval(1000 * 5);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
@Override
public void onConnected(Bundle bundle)
startLocationUpdates();
protected void startLocationUpdates()
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
// TODO: Consider calling
Toast.makeText(this, "LocationNotUpdated", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(VisitTravel.this,
new String[]
android.Manifest.permission
.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION
,
20);
else
if (mGoogleApiClient.isConnected())
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d("Loc", "Location update started ..............: ");
// Toast.makeText(this, "LocationUpdatedStart", Toast.LENGTH_SHORT).show();
@Override
public void onConnectionSuspended(int i)
@Override
public void onConnectionFailed(ConnectionResult connectionResult)
public void map_marker_start(Double lat, Double longt, String title)
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng = new LatLng(lat, longt);
Log.d("lat", String.valueOf(latLng.longitude));
markerOptions.position(latLng);
markerOptions.title(title);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
mGoogleMap.addMarker(markerOptions).showInfoWindow();
public void map_marker_End(Double lat, Double longt, String title)
final MarkerOptions markerOptions_end = new MarkerOptions();
LatLng latLng = new LatLng(lat, longt);
Log.d("lat", String.valueOf(latLng.longitude));
markerOptions_end.position(latLng);
markerOptions_end.title(title);
markerOptions_end.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mGoogleMap.addMarker(markerOptions_end).showInfoWindow();
mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
@Override
public boolean onMarkerClick(Marker marker)
String title = marker.getTitle();
if (title.equals("Destination"))
dot_source.setText("\u2022");
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
heading.setText("TEST");
duration_textview.setText("Duration:" + " " + duration);
return true;
else
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
return true;
);
@Override
public void onLocationChanged(Location location)
mLastLocation = location;
PolylineOptions polylineOptions = new PolylineOptions();
Log.d("location", mLastLocation.toString());
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
obj.add(latLng);
polylineOptions.addAll(obj);
polylineOptions.width(9);
polylineOptions.color(Color.parseColor("#2196f3"));
mGoogleMap.addPolyline(polylineOptions);
progressDialog.dismiss();
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
latLng, 12);
mGoogleMap.animateCamera(cameraUpdate);
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission()
if (ContextCompat.checkSelfPermission(VisitTravel.this, android.Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED)
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.ACCESS_FINE_LOCATION))
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialogInterface, int i)
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(VisitTravel.this,
new String[]
android.Manifest.permission.ACCESS_FINE_LOCATION
,
MY_PERMISSIONS_REQUEST_LOCATION);
)
.create()
.show();
else
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]
android.Manifest.permission.ACCESS_FINE_LOCATION
,
MY_PERMISSIONS_REQUEST_LOCATION);
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults)
switch (requestCode)
case MY_PERMISSIONS_REQUEST_LOCATION:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED)
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)
if (mGoogleApiClient == null)
buildGoogleApiClient();
createLocationRequest();
/// buildGoogleApiClient();
// Settingsapi();
mGoogleMap.setMyLocationEnabled(true);
else
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
return;
// other 'case' lines to check for other
// permissions this app might request
public String getKilometer(final double lat1, final double lon1, final double lat2, final double lon2)
Thread thread = new Thread(new Runnable()
@Override
public void run()
try
URL url = new URL("http://maps.googleapis.com/maps/api/directions/json?origin=" + lat1 + "," + lon1 + "&destination=" + lat2 + "," + lon2 + "&sensor=false&units=metric&mode=driving");
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
StringBuilder buffer = new StringBuilder();
BufferedReader reader = null;
reader = new BufferedReader(new InputStreamReader( in ));
String inputLine;
while ((inputLine = reader.readLine()) != null)
buffer.append(inputLine + "\n");
if (buffer.length() == 0)
// Stream was empty. No point in parsing.
Log.e("empty", "empty");
JsonResponse = buffer.toString();
Log.d("response", JsonResponse);
JSONObject jsonObject = new JSONObject(JsonResponse);
JSONArray array = jsonObject.getJSONArray("routes");
JSONObject routes = array.getJSONObject(0);
JSONArray legs = routes.getJSONArray("legs");
JSONObject steps = legs.getJSONObject(0);
JSONObject distance = steps.getJSONObject("distance");
parsedDistance = distance.getString("text");
catch (ProtocolException e)
e.printStackTrace();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
);
thread.start();
try
thread.join();
catch (InterruptedException e)
e.printStackTrace();
return parsedDistance;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
switch (requestCode)
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode)
case Activity.RESULT_OK:
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
Intent intent = new Intent(this, Incident.class);
startActivity(intent);
break;
break;
@Override
protected void onStop()
super.onStop();
if (wakeLock.isHeld())
wakeLock.release();
@Override
public void onBackPressed()
super.onBackPressed();
Intent intent = new Intent(this, IncidentView.class);
if (mGoogleApiClient.isConnected())
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
setResult(RESULT_OK, intent);
finish();
搜索了很多,但没有找到正确的开始方式?任何帮助都会非常有价值。
--谢谢!
【问题讨论】:
【参考方案1】:这对我有用:
定期捕获纬度和经度并存储。计算并求和每个存储值之间的距离。
【讨论】:
以上是关于如何使用谷歌地图计算用户行进的准确距离?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用LatLng在谷歌地图v2中以公里为单位获取两个地方之间的距离