如何使用谷歌地图计算用户行进的准确距离?

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】:

这对我有用:

定期捕获纬度和经度并存储。计算并求和每个存储值之间的距离。

【讨论】:

以上是关于如何使用谷歌地图计算用户行进的准确距离?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用陀螺仪和加速度计找到行进的距离?

如何在swift 3.0中计算用户从当前位置行进的距离

如何使用LatLng在谷歌地图v2中以公里为单位获取两个地方之间的距离

如何使用谷歌地图api V3计算两个城市之间的距离[关闭]

如何在android中的谷歌地图上绘制路线并计算多个标记之间的距离

如何计算百度地图上两点的距离