7

Tôi muốn có thể hiển thị tuyến đường giữa hai do người dùng xác định điểm địa lý bằng cách sử dụng API Google Maps dành cho Android. Tôi cũng muốn có thể cho phép người dùng chọn loại lộ trình để hiển thị, cho dù đó là đi bộ, đi xe đạp, xe hơi vv Ngoài ra, tôi muốn có thể tính toán thời gian và khoảng cách cần thiết để sử dụng tuyến đường này. Tôi đã thử tìm kiếm trên web và xem các câu hỏi về stackoverflow khác nhưng không có kết quả. Làm thế nào tôi sẽ đi về điều này? Làm cách nào để tôi có thể điều này.Tìm tuyến đường bằng Android API Google Maps

// ---- EDIT ---- //

Tôi cũng muốn để có được thông tin giao thông như các tuyến đường bận rộn, ùn tắc, vv

+0

Tôi đi theo này http://stackoverflow.com/questions/11745314/why-retrieving-google-directions-for-android-using-kml-data -is-không-làm việc-anymo để có được các tuyến đường. Đó là bước đầu tiên. – Stochastically

Trả lời

3

Android Google Maps Routing mã ví dụ sử dụng thư viện Wrapper

Sử dụng Android Studio Gradle nhập:

compile 'com.github.jd-alexander:library:1.1.0' 

MainActivity.java

import android.Manifest; 
import android.content.pm.PackageManager; 
import android.graphics.Color; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.app.FragmentActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.directions.route.Route; 
import com.directions.route.RouteException; 
import com.directions.route.Routing; 
import com.directions.route.RoutingListener; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.OnMapReadyCallback; 
import com.google.android.gms.maps.SupportMapFragment; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.LatLngBounds; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 
import com.google.android.gms.maps.model.Polyline; 
import com.google.android.gms.maps.model.PolylineOptions; 

import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

public class MainActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMarkerClickListener, RoutingListener { 

    private GoogleMap mMap = null; 
    private LocationManager locationManager = null; 
    private FloatingActionButton fab = null; 
    private TextView txtDistance, txtTime; 

    //Global UI Map markers 
    private Marker currentMarker = null; 
    private Marker destMarker = null; 
    private LatLng currentLatLng = null; 
    private Polyline line = null; 

    //Global flags 
    private boolean firstRefresh = true; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_map); 
     Constants.POINT_DEST = new LatLng(18.758663, 73.382025);  //Lonavala destination. 
     //Load the map fragment on UI 
     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
     txtDistance = (TextView)findViewById(R.id.txt_distance); 
     txtTime = (TextView)findViewById(R.id.txt_time); 
     fab = (FloatingActionButton)findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       MainActivity.this.getRoutingPath(); 
       Snackbar.make(v, "Fetching Route", Snackbar.LENGTH_SHORT).show(); 
      } 
     }); 

    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     firstRefresh = true; 
     //Ensure the GPS is ON and location permission enabled for the application. 
     locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 
     if (!PermissionCheck.getInstance().checkGPSPermission(this, locationManager)) { 
      //GPS not enabled for the application. 
     } else if (!PermissionCheck.getInstance().checkLocationPermission(this)) { 
      //Location permission not given. 
     } else { 
      Toast.makeText(MainActivity.this, "Fetching Location", Toast.LENGTH_SHORT).show(); 
      try { 
       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 
       locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, this); 
      } catch(Exception e) 
      { 
       Toast.makeText(MainActivity.this, "ERROR: Cannot start location listener", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    } 

    @Override 
    protected void onPause() { 
     if (locationManager != null) { 
      //Check needed in case of API level 23. 

      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      } 
      try { 
       locationManager.removeUpdates(this); 
      } catch (Exception e) { 
      } 
     } 
     locationManager = null; 
     super.onPause(); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) 
    { 
     mMap = googleMap; 
     //mMap.getUiSettings().setZoomControlsEnabled(true); 
     mMap.getUiSettings().setCompassEnabled(true); 
     mMap.getUiSettings().setAllGesturesEnabled(true); 
     mMap.setOnMarkerClickListener(this); 
    } 

    /** 
    * @desc LocationListener Interface Methods implemented. 
    */ 

    @Override 
    public void onLocationChanged(Location location) 
    { 
     double lat = location.getLatitude(); 
     double lng = location.getLongitude(); 
     currentLatLng = new LatLng(lat, lng); 
     if(firstRefresh) 
     { 
      //Add Start Marker. 
      currentMarker = mMap.addMarker(new MarkerOptions().position(currentLatLng).title("Current Position"));//.icon(BitmapDescriptorFactory.fromResource(R.drawable.location))); 
      firstRefresh = false; 
      destMarker = mMap.addMarker(new MarkerOptions().position(Constants.POINT_DEST).title("Destination"));//.icon(BitmapDescriptorFactory.fromResource(R.drawable.location))); 
      mMap.moveCamera(CameraUpdateFactory.newLatLng(Constants.POINT_DEST)); 
      mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); 
      getRoutingPath(); 
     } 
     else 
     { 
      currentMarker.setPosition(currentLatLng); 
     } 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) {} 

    @Override 
    public void onProviderEnabled(String provider) {} 

    @Override 
    public void onProviderDisabled(String provider) {} 

    /** 
    * @desc MapMarker Interface Methods Implemented. 
    */ 

    @Override 
    public boolean onMarkerClick(Marker marker) 
    { 
     if(marker.getTitle().contains("Destination")) 
     { 
      //Do some task on dest pin click 
     } 
     else if(marker.getTitle().contains("Current")) 
     { 
      //Do some task on current pin click 
     } 
     return false; 
    } 

    /** 
    *@desc Routing Listener interface methods implemented. 
    **/ 
    @Override 
    public void onRoutingFailure(RouteException e) 
    { 
     Toast.makeText(MainActivity.this, "Routing Failed", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onRoutingStart() { } 

    @Override 
    public void onRoutingSuccess(ArrayList<Route> list, int i) 
    { 
     try 
     { 
      //Get all points and plot the polyLine route. 
      List<LatLng> listPoints = list.get(0).getPoints(); 
      PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); 
      Iterator<LatLng> iterator = listPoints.iterator(); 
      while(iterator.hasNext()) 
      { 
       LatLng data = iterator.next(); 
       options.add(data); 
      } 

      //If line not null then remove old polyline routing. 
      if(line != null) 
      { 
       line.remove(); 
      } 
      line = mMap.addPolyline(options); 

      //Show distance and duration. 
      txtDistance.setText("Distance: " + list.get(0).getDistanceText()); 
      txtTime.setText("Duration: " + list.get(0).getDurationText()); 

      //Focus on map bounds 
      mMap.moveCamera(CameraUpdateFactory.newLatLng(list.get(0).getLatLgnBounds().getCenter())); 
      LatLngBounds.Builder builder = new LatLngBounds.Builder(); 
      builder.include(currentLatLng); 
      builder.include(Constants.POINT_DEST); 
      LatLngBounds bounds = builder.build(); 
      mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); 
     } 
     catch (Exception e) 
     { 
      Toast.makeText(MainActivity.this, "EXCEPTION: Cannot parse routing response", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    @Override 
    public void onRoutingCancelled() 
    { 
     Toast.makeText(MainActivity.this, "Routing Cancelled", Toast.LENGTH_SHORT).show(); 
    } 

    /** 
    * @method getRoutingPath 
    * @desc Method to draw the google routed path. 
    */ 
    private void getRoutingPath() 
    { 
     try 
     { 
      //Do Routing 
      Routing routing = new Routing.Builder() 
        .travelMode(Routing.TravelMode.DRIVING) 
        .withListener(this) 
        .waypoints(currentLatLng, Constants.POINT_DEST) 
        .build(); 
      routing.execute(); 
     } 
     catch (Exception e) 
     { 
      Toast.makeText(MainActivity.this, "Unable to Route", Toast.LENGTH_SHORT).show(); 
     } 
    } 

} 

Constants.java

/** 
* @class Constants 
* @desc Constant class for holding values at runtime. 
*/ 
public class Constants 
{ 

    //Map LatLong points 
    public static LatLng POINT_DEST = null; 

} 

activity_map.xml

<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:map="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 

android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<LinearLayout android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <LinearLayout 
     android:id="@+id/viewA" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="0.1" 
     android:orientation="horizontal"> 

     <fragment 
      android:id="@+id/map" 
      android:name="com.google.android.gms.maps.SupportMapFragment" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      tools:context="com.packagename.MainActivity" /> 


    </LinearLayout> 

    <LinearLayout 
     android:id="@+id/viewB" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_weight="0.9" 
     android:gravity="center|left" 
     android:paddingLeft="20dp" 
     android:background="#FFFFFF" 
     android:orientation="vertical" > 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:textSize="16dp" 
      android:text="Distance ?" 
      android:paddingTop="3dp" 
      android:paddingLeft="3dp" 
      android:paddingBottom="3dp" 
      android:id="@+id/txt_distance" /> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:textSize="17dp" 
      android:paddingLeft="3dp" 
      android:text="Duration ?" 
      android:id="@+id/txt_time" /> 

    </LinearLayout> 

</LinearLayout> 

<android.support.design.widget.FloatingActionButton 
    android:id="@+id/fab" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_margin="16dp" 
    android:clickable="true" 
    android:src="@android:drawable/ic_dialog_map" 
    app:layout_anchor="@id/viewA" 
    app:layout_anchorGravity="bottom|right|end"/> 

</android.support.design.widget.CoordinatorLayout> 
3

Thử Google Directions API. Đó là một dịch vụ web, cung cấp hướng dẫn từng chặng theo Định dạng JSON với tất cả thông tin để đi từ điểm A đến B bằng xe hơi, phương tiện hoặc chân của bạn.

Để mã theo liên kết trong nhận xét của Stochastically.

+2

Trong phần giới thiệu về API, nó nói "Dịch vụ này thường được thiết kế để tính chỉ đường cho các địa chỉ tĩnh (đã biết trước) để sắp xếp nội dung ứng dụng trên bản đồ; dịch vụ này không được thiết kế để phản hồi trong thời gian thực tới đầu vào của người dùng, Ví dụ: Để tính toán chỉ đường động (ví dụ: trong phần tử giao diện người dùng), hãy tham khảo tài liệu về Dịch vụ chỉ đường JavaScript API V3. " – AndroidDev

+0

Có, vấn đề là API không được thiết kế cho nhiều cuộc gọi thời gian thực. Chỉ cần gọi API một lần, trích xuất thông tin từ JSON và lặp lại thông tin đó cho đến khi bạn đến. Làm thế nào tôi nói API cung cấp thông tin, nhưng logic để xử lý thông tin đó phải được thực hiện. –

+0

Bạn đã xem bản chỉnh sửa chưa? – AndroidDev

6

Dưới đây là một số mã giúp bạn.

String url= 
"http://maps.googleapis.com/maps/api/directions/json?origin=" 
+ origin.latitude + "," + origin.longitude +"&destination=" 
+ destination.latitude + "," + destination.longitude + "&sensor=false"; 

Để lấy dữ liệu với androidhttpclient, làm một cái gì đó như thế này:

HttpResponse response; 
HttpGet request; 
AndroidHttpClient client = AndroidHttpClient.newInstance("somename"); 

request = new HttpGet(url); 
response = client.execute(request); 

InputStream source = response.getEntity().getContent(); 
String returnValue = buildStringIOutils(source); 

return returnValue; 

nơi buildStringIOUtils là:

private String buildStringIOutils(InputStream is) { 
    try { 
     return IOUtils.toString(is, "UTF-8"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

Sau đó bạn có thể trích xuất các polyline thực tế từ JSON-phản ứng với một cái gì đó như thế này:

JSONObject result = new JSONObject(returnValue); 
JSONArray routes = result.getJSONArray("routes"); 

        long distanceForSegment = routes.getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("distance").getInt("value"); 

        JSONArray steps = routes.getJSONObject(0).getJSONArray("legs") 
          .getJSONObject(0).getJSONArray("steps"); 

        List<LatLng> lines = new ArrayList<LatLng>(); 

        for(int i=0; i < steps.length(); i++) { 
         String polyline = steps.getJSONObject(i).getJSONObject("polyline").getString("points"); 

         for(LatLng p : decodePolyline(polyline)) { 
          lines.add(p); 
         } 
        } 

nơi phương pháp decodePolyline là thế này:

/** POLYLINE DECODER - http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java **/ 
    private List<LatLng> decodePolyline(String encoded) { 

     List<LatLng> poly = new ArrayList<LatLng>(); 

     int index = 0, len = encoded.length(); 
     int lat = 0, lng = 0; 

     while (index < len) { 
      int b, shift = 0, result = 0; 
      do { 
       b = encoded.charAt(index++) - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 
      lat += dlat; 

      shift = 0; 
      result = 0; 
      do { 
       b = encoded.charAt(index++) - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 
      lng += dlng; 

      LatLng p = new LatLng((double) lat/1E5, (double) lng/1E5); 
      poly.add(p); 
     } 

     return poly; 
    } 

Sau đó, bạn có thể thêm các polyline vào bản đồ với điều này:

Polyline polylineToAdd = mMap.addPolyline(new PolylineOptions().addAll(lines).width(3).color(Color.RED)); 

Để thay đổi chế độ, thêm video này vào url (Xem https://developers.google.com/maps/documentation/directions/): & chế độ = YOUR_MODE

lái xe (mặc định) cho biết chỉ đường lái xe tiêu chuẩn sử dụng mạng lưới đường bộ.

yêu cầu đi bộ chỉ đường đi bộ qua đường dành cho người đi bộ & vỉa hè (nếu có).

yêu cầu đi xe đạp chỉ đường đi xe đạp qua đường dành cho xe đạp & các đường phố ưa thích (nếu có).

chỉ đường yêu cầu chuyển tuyến qua các tuyến chuyển tuyến công cộng (nếu có).

Chỉnh sửa: Giới thiệu về "Tôi cũng muốn nhận thông tin giao thông như các tuyến đường bận rộn, tắc nghẽn, v.v ..." Tôi đã không nhìn vào điều này, nhưng mã của tôi sẽ giúp bạn bắt đầu khá tốt.

Chỉnh sửa2: Tìm thấy điều này trong chỉ đường google api: "Chỉ đường lái xe: Khách hàng Maps for Business có thể chỉ định thời gian khởi hành để nhận thời gian chuyến đi xem xét điều kiện giao thông hiện tại. thời điểm hiện tại."

+0

hi, có thể thêm nhiều điểm đến không ?? –