2017-02-23 33 views
0

我正在使用項目來查找兩個地點之間的距離,一個是當前位置,另一個是使用自動完成文本視圖的用戶輸入值。使用Google地圖中的按鈕查找當前位置和用戶輸入字段之間的距離

如何使用按鈕點擊獲得正確的距離。我沒有點擊按鈕就得到了這些值。我怎樣才能實現按鈕點擊?

output with map click listener

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_maps); 
    MarkerPoints = new ArrayList<>(); 
    final AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); 

    autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list_item)); 
    autoCompView.setOnItemClickListener(this); 
    b1=(Button)findViewById(R.id.search_button); 
    b1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String location = autoCompView.getText().toString(); 
      List<Address>addressList = null; 

      if (location != null || !location.equals("")) { 
       Geocoder geocoder = new Geocoder(MapsActivity.this); 
       try { 
        addressList = geocoder.getFromLocationName(location, 1); 

       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       Address address = addressList.get(0); 
       LatLng dest = new LatLng(address.getLatitude(), address.getLongitude()); 
       lat1=String.valueOf(address.getLatitude()); 
       lon1 = String.valueOf(address.getLongitude()); 
       Toast.makeText(MapsActivity.this, "new Lati and new longi1 "+dest, Toast.LENGTH_LONG).show(); 


       mMap.addMarker(new MarkerOptions().position(dest).title("Marker")); 
       mMap.animateCamera(CameraUpdateFactory.newLatLng(dest)); 
       // SendDataToServer(unique_id,lat1,lon1); 
       // mMap.clear(); 
       findPath(point); 

      } 



     } 
    }); 

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     checkLocationPermission(); 
    } 
    // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(R.id.map); 
    mapFragment.getMapAsync(this); 
    sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE); 

} 

private void findPath(LatLng point) { 
    if (MarkerPoints.size() >= 2) { 
     LatLng origin = MarkerPoints.get(0); 
     LatLng dest = MarkerPoints.get(1); 

     // Getting URL to the Google Directions API 
     String url = getUrl(origin, dest); 
    // Log.d("onMapClick", url.toString()); 
     FetchUrl FetchUrl = new FetchUrl(); 

     // Start downloading json data from Google Directions API 
     FetchUrl.execute(url); 
     //move map camera 
     mMap.moveCamera(CameraUpdateFactory.newLatLng(origin)); 
     mMap.animateCamera(CameraUpdateFactory.zoomTo(16)); 
    } 

} 

private void drawMarker(LatLng point) { 
    MarkerPoints.add(point); 

    // Creating MarkerOptions 
    MarkerOptions options = new MarkerOptions(); 

    // Setting the position of the marker 
    options.position(point); 
    private String getUrl(LatLng origin, LatLng dest) { 

    // Origin of route 
    String str_origin = "origin=" + origin.latitude + "," + origin.longitude; 

    // Destination of route 
    String str_dest = "destination=" + dest.latitude + "," + dest.longitude; 


    // Sensor enabled 
    String sensor = "sensor=false"; 

    // Building the parameters to the web service 
    String parameters = str_origin + "&" + str_dest + "&" + sensor; 

    // Output format 
    String output = "json"; 

    // Building the url to the web service 
    String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters; 


    return url; 
} 

/** 
* A method to download json data from url 
*/ 
private String downloadUrl(String strUrl) throws IOException { 
    String data = ""; 
    InputStream iStream = null; 
    HttpURLConnection urlConnection = null; 
    try { 
     URL url = new URL(strUrl); 

     // Creating an http connection to communicate with url 
     urlConnection = (HttpURLConnection) url.openConnection(); 

     // Connecting to url 
     urlConnection.connect(); 

     // Reading data from url 
     iStream = urlConnection.getInputStream(); 

     BufferedReader br = new BufferedReader(new InputStreamReader(iStream)); 

     StringBuffer sb = new StringBuffer(); 

     String line = ""; 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
     } 

     data = sb.toString(); 
     Log.d("downloadUrl", data.toString()); 
     br.close(); 

    } catch (Exception e) { 
     Log.d("Exception", e.toString()); 
    } finally { 
     iStream.close(); 
     urlConnection.disconnect(); 
    } 
    return data; 
} 

// Fetches data from url passed 
private class FetchUrl extends AsyncTask<String, Void, String> { 

    @Override 
    protected String doInBackground(String... url) { 

     // For storing data from web service 
     String data = ""; 

     try { 
      // Fetching the data from web service 
      data = downloadUrl(url[0]); 
      Log.d("Background Task data", data.toString()); 
     } catch (Exception e) { 
      Log.d("Background Task", e.toString()); 
     } 
     return data; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 

     ParserTask parserTask = new ParserTask(); 

     // Invokes the thread for parsing the JSON data 
     parserTask.execute(result); 

    } 
} 

/** 
* A class to parse the Google Places in JSON format 
*/ 
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> { 

    // Parsing the data in non-ui thread 
    @Override 
    protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { 

     JSONObject jObject; 
     List<List<HashMap<String, String>>> routes = null; 

     try { 
      jObject = new JSONObject(jsonData[0]); 
      Log.d("ParserTask",jsonData[0].toString()); 
      DataParser parser = new DataParser(); 
      Log.d("ParserTask", parser.toString()); 

      // Starts parsing data 
      routes = parser.parse(jObject); 
      Log.d("ParserTask","Executing routes"); 
      Log.d("ParserTask",routes.toString()); 

     } catch (Exception e) { 
      Log.d("ParserTask",e.toString()); 
      e.printStackTrace(); 
     } 
     return routes; 
    } 

    // Executes in UI thread, after the parsing process 
    @Override 
    protected void onPostExecute(List<List<HashMap<String, String>>> result) { 
     ArrayList<LatLng> points; 
     PolylineOptions lineOptions = null; 
     String distance = ""; 
     String duration = ""; 

     // Traversing through all the routes 
     for (int i = 0; i < result.size(); i++) { 
      points = new ArrayList<>(); 
      lineOptions = new PolylineOptions(); 

      // Fetching i-th route 
      List<HashMap<String, String>> path = result.get(i); 

      // Fetching all the points in i-th route 
      for (int j = 0; j < path.size(); j++) { 
       HashMap<String, String> point = path.get(j); 

       if(j==0){ // Get distance from the list 
        distance = (String)point.get("distance"); 
        continue; 
       }else if(j==1){ // Get duration from the list 
        duration = (String)point.get("duration"); 
        continue; 
       } 

       double lat = Double.parseDouble(point.get("lat")); 
       double lng = Double.parseDouble(point.get("lng")); 
       LatLng position = new LatLng(lat, lng); 

       points.add(position); 
      } 

      // Adding all the points in the route to LineOptions 
      lineOptions.addAll(points); 
      lineOptions.width(10); 
      lineOptions.color(Color.RED); 

      Log.d("onPostExecute","onPostExecute lineoptions decoded"); 
      tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration); 
     } 

     // Drawing polyline in the Google Map for the i-th route 
     if(lineOptions != null) { 
      mMap.addPolyline(lineOptions); 
     } 
     else { 
      Log.d("onPostExecute","without Polylines drawn"); 
     } 
    } 
+0

你不需要兩個Asynctasks ... JSON解析在UI線程上很好。此代碼似乎比需要更復雜 –

+0

好吧,先生,我怎麼能得到距離,使用按鈕? – Jincy

+0

我認爲'LatLng'或者'Location'類本身就有一個距離方法。該按鈕與實際距離計算無關 –

回答

0

如果您知道兩個位置的經度和緯度,那麼您可以輕鬆計算兩個位置之間的距離。訪問http://www.geodatasource.com/developers/java獲取更多信息。

這裏是你如何在android中做到這一點。

創建一個方法,在某些類以下

private static double distance(double lat1, double lon1, double lat2, double lon2, String unit) { 
     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; 
     if (unit == "K") { 
      dist = dist * 1.609344; 
     } else if (unit == "N") { 
      dist = dist * 0.8684; 
     } 

     return (dist); 
    } 

    /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
    /*:: This function converts decimal degrees to radians      :*/ 
    /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
    private static double deg2rad(double deg) { 
     return (deg * Math.PI/180.0); 
    } 

    /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
    /*:: This function converts radians to decimal degrees      :*/ 
    /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/ 
    private static double rad2deg(double rad) { 
     return (rad * 180/Math.PI); 
    } 

然後你可以使用distance方法

例如距離在千米助手類的靜態方法,然後

int distance = Helper.distance(lat1,lon1,lat2,lon2,"K")使用「K」 「N」爲

我希望這能幫助你。

+0

謝謝Zeeshan,這可能在谷歌地圖? – Jincy

+0

你應該使用谷歌地圖來獲得位置1和位置2的座標,然後找到與這些方法的距離,一旦你得到的距離,你可以顯示它在任何你想要的。 –

0

這是我用來獲取從用戶位置到選定位置的距離和時間旅行的方法。其添加到您AsyncTask如下:

public void getDistAndDuration(JSONObject jObj){ 
    try{ 
     JSONArray array = jObj.getJSONArray("routes"); 
     JSONObject rou = array.getJSONObject(0); 
     JSONArray legs = rou.getJSONArray("legs"); 
     JSONObject steps = legs.getJSONObject(0); 
     JSONObject distance = steps.getJSONObject("distance"); 
     JSONObject duration = steps.getJSONObject("duration"); 
     final String textDist = distance.getString("text"); 
     final String textDur = duration.getString("text"); 

     Log.i("DISTANCE", ""+textDist); 
     Log.i("TIME", ""+textDur); 

    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

調用此方法可在ParserTaskdoInBackground方法是這樣的:

@Override 
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) { 

    JSONObject jObject; 
    List<List<HashMap<String, String>>> routes = null; 

    try { 
     jObject = new JSONObject(jsonData[0]); 

     ////////// HERE ////////////// 
     getDistAndDuration(jObject); 
     ////////////////////////////// 

     Log.d("ParserTask",jsonData[0].toString()); 
     DataParser parser = new DataParser(); 
     Log.d("ParserTask", parser.toString()); 

     // Starts parsing data 
     routes = parser.parse(jObject); 
     Log.d("ParserTask","Executing routes"); 
     Log.d("ParserTask",routes.toString()); 

    } catch (Exception e) { 
     Log.d("ParserTask",e.toString()); 
     e.printStackTrace(); 
    } 
    return routes; 
} 

如果你只是想獲得點擊按鈕的距離,聲明你jObject全球範圍內,並在您的按鈕的點擊偵聽器中調用getDistAndDuration(JSONObject jObj)。請先撥打AsyncTask後再打電話。

希望它有幫助:)

相關問題