7

Я хочу, чтобы иметь возможность отображать маршрут между двумя определяемыми пользователем географическими точками, используя API Карт Google для Android. Я также хочу, чтобы пользователь позволял пользователю выбирать тип маршрута для отображения, будь то ходьба, езда на велосипеде, автомобиль и т. Д. Кроме того, я хочу рассчитать время и расстояние, необходимые для использования этого маршрута. Я попытался найти в Интернете и посмотреть на другие вопросы, связанные с stackoverflow, но безрезультатно. Как я могу это сделать? Как я смогу код это.Найти маршрут с андроидами API Карт Google

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

Я также хотел бы получить информацию о дорожном движении, такие как занятые маршруты, перегрузки и т.д.

+0

Я следовал за этим http://stackoverflow.com/questions/11745314/why-retrieving-google-directions-for-android-using-kml-data -и-не-рабочий-anymo, чтобы получить маршрут. Это первый шаг. – Stochastically

ответ

3

Android Google Maps Routing пример кода с использованием библиотеки оболочки

Использование Android-студия Gradle запись:

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

Попробуйте Google Directions API. Это веб-сервис, который дает пошаговые руководства в формате JSON-Format со всей информацией, чтобы добраться от пункта A до B на машине, транзите или ногах.

Чтобы код, перейдя по ссылке в примечании Стохастически.

+2

Во введении к API в нем говорится: «Эта услуга, как правило, предназначена для расчета направлений для статических (известных заранее) адресов для размещения содержимого приложения на карте, эта служба не предназначена для ответа в режиме реального времени на ввод пользователя, Например, для расчетов динамических направлений (например, в элементе пользовательского интерфейса) обратитесь к документации для службы JavaScript V3 Directions Service. " – AndroidDev

+0

Да, дело в том, что API не предназначен для нескольких вызовов в реальном времени. Просто вызовите API один раз, извлеките информацию из JSON и пропустите ее до тех пор, пока вы не придете. Как я сказал, API дает информацию, но логика для обработки этой информации должна быть реализована. –

+0

Вы видели редактирование? – AndroidDev

6

Вот код, который поможет вам.

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

Для извлечения данных с androidhttpclient, сделать что-то вроде этого:

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; 

где buildStringIOUtils является:

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

Вы можете извлечь реальную ломаную линию из JSON-ответ с что-то вроде этого:

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

где метод decodePolyline это:

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

Вы можете добавить полилинию на карту с этим:

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

Для изменения режима, добавьте к этому URL (см https://developers.google.com/maps/documentation/directions/): & mode = YOUR_MODE

Вождение (по умолчанию) указывает стандартные направления движения по дорожной сети.

прогулочные запросы по пешеходным дорожкам & тротуары (если имеется).

велосипед требует велосипедных дорожек с помощью велосипедных дорожек & предпочтительные улицы (если есть).

транзитные запросы направляются через маршруты общественного транспорта (если таковые имеются).

Редактировать: Об «Мне также хотелось бы получить информацию о дорожном движении, такую ​​как занятые маршруты, заторы и т. Д.». Я не рассматривал это, но мой код должен заставить вас начать очень хорошо.

Edit2: Нашел в направлениях API Google: «Для Направления движения:. Карт для бизнеса можно указать DEPARTURE_TIME получить продолжительность поездки с учетом текущих условий движения DEPARTURE_TIME должен быть установлен в течение нескольких минут после Текущее время."

+0

привет, можно ли добавить несколько пунктов назначения? –

Смежные вопросы