7

Ich möchte in der Lage sein, die Route zwischen zwei benutzerdefinierte geographische Punkte mit der Google Maps API für Android anzuzeigen. Ich möchte auch in der Lage sein, den Benutzer entscheiden zu lassen, welche Art von Route angezeigt werden soll, ob es sich um Wandern, Radfahren, Auto usw. handelt. Außerdem möchte ich die Zeit und die Entfernung berechnen können, die diese Route benötigen würde. Ich habe versucht, im Internet zu suchen und andere stackoverflow Fragen zu suchen, aber ohne Erfolg. Wie würde ich darüber gehen? Wie würde ich dazu in der Lage sein Code dies.Route finden mit Android Google Maps API

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

Ich würde auch die Google Directions API gerne Verkehrsinformationen wie stark frequentierten Strecken, Staus etc.

+0

Ich folgte dieser http://stackoverflow.com/questions/11745314/why-retrieving-google-directions-for-android-using-kml-data -ist-nicht-arbeiten-anymo, um die Route zu bekommen. Das ist der erste Schritt. – Stochastically

Antwort

3

Android Google Maps Routing Codebeispiel mit Wrapper-Bibliothek

Verwenden Android Studio Gradle Eintrag:

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

bekommen versuchen. Es ist ein Webservice, der Turn-by-Turn-Führer im JSON-Format mit allen Informationen gibt, um von Auto nach A oder B zu kommen.

Um dies zu codieren, folgen Sie dem Link im Kommentar von Stochastically.

+2

In der Einführung in die API heißt es: "Dieser Dienst ist im Allgemeinen für die Berechnung von Richtungen für statische (im Voraus bekannt) Adressen für die Platzierung von Anwendungsinhalt auf einer Karte ausgelegt. Dieser Dienst ist nicht darauf ausgelegt, in Echtzeit auf Benutzereingaben zu reagieren. Nehmen Sie beispielsweise für dynamische Richtungsberechnungen (z. B. innerhalb eines Benutzeroberflächenelements) die Dokumentation zum JavaScript API V3 Directions Service zurate. " – AndroidDev

+0

Ja, der Punkt ist, dass die API nicht für mehrere Echtzeit-Anrufe ausgelegt ist. Rufen Sie einfach die API einmal auf, extrahieren Sie die Informationen aus JSON und durchlaufen Sie sie, bis Sie angekommen sind. Wie ich sagte, die API gibt die Informationen, aber die Logik, um mit diesen Informationen umzugehen, muss implementiert werden. –

+0

Hast du den Schnitt gesehen? – AndroidDev

6

Hier ist ein Code, der Ihnen hilft.

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

Um die Daten mit androidhttpclient, etwas tun zu holen:

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; 

wo buildStringIOUtils sind:

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

Sie können dann den tatsächlichen Linienzug aus der JSON-Antwort extrahieren mit etwas wie dieses:

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); 
         } 
        } 

wo das Verfahren decodePolyline ist dies:

/** 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; 
    } 

Anschließend können Sie die Polylinie auf die Karte mit diesem Zusatz:

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

Modus zu ändern, fügen Sie diese auf die URL (siehe https://developers.google.com/maps/documentation/directions/): & mode = YOUR_MODE

Fahren (Standard) zeigt Standardfahranweisungen über das Straßennetz an.

zu Fuß Anfragen über Fußgängerwege & Gehwege (wo verfügbar).

radfahren anträge radfahrtrichtungen über fahrradwege & bevorzugte straßen (wo vorhanden).

Transitanfragen Richtungen über öffentliche Verkehrsmittel (wo verfügbar).

Edit: Über die "Ich möchte auch Verkehrsinformationen wie befahrene Routen, Stau, etc." Ich habe mir das nicht angeschaut, aber mein Code sollte dir ziemlich gut anfangen.

Edit2: Gefunden dies in der Google-Richtungen api: „Anweisung Fahren. Maps für Geschäftskunden die departure_time angeben Reisedauer unter Berücksichtigung aktuelle Verkehrssituation erhalten Die departure_time muss innerhalb von wenigen Minuten von der eingestellt werden aktuelle Uhrzeit."

+0

hi, ist es möglich, mehrere Ziele hinzuzufügen? –