Cómo dibujar Polyline interactivo en la ruta google maps v2 android

Tengo el siguiente código que dibuja polilíneas para mí y funciona bien, pero el problema es que no dibuja polilíneas interactivas, las líneas dibujadas faltan algunos píxeles.

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONObject; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; 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 android.app.ProgressDialog; import android.content.Context; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class testRoute extends FragmentActivity implements OnClickListener { private GoogleMap myMap; Polyline line; Context context; // Static LatLng LatLng startLatLng = new LatLng(30.707104, 76.690749); LatLng endLatLng = new LatLng(30.721419, 76.730017); public void onCreate(Bundle bd) { super.onCreate(bd); setContentView(R.layout.passanger_home_call); context = testRoute.this; // Temp GetTrails Button Button btntemp = (Button) findViewById(R.id.btn_pass_home_call_temp); btntemp.setOnClickListener(this); // GoogleMap myMap myMap = ((SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map_pass_home_call)).getMap(); myMap.setMyLocationEnabled(true); myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng)); myMap.animateCamera(CameraUpdateFactory.zoomTo(12)); // Now auto clicking the button btntemp.performClick(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_pass_home_call_temp: String urlTopass = makeURL(startLatLng.latitude, startLatLng.longitude, endLatLng.latitude, endLatLng.longitude); new connectAsyncTask(urlTopass).execute(); break; default: break; } } private class connectAsyncTask extends AsyncTask { private ProgressDialog progressDialog; String url; connectAsyncTask(String urlPass) { url = urlPass; } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); progressDialog = new ProgressDialog(context); progressDialog.setMessage("Fetching route, Please wait..."); progressDialog.setIndeterminate(true); progressDialog.show(); } @Override protected String doInBackground(Void... params) { JSONParser jParser = new JSONParser(); String json = jParser.getJSONFromUrl(url); return json; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); progressDialog.hide(); if (result != null) { drawPath(result); } } } public String makeURL(double sourcelat, double sourcelog, double destlat, double destlog) { StringBuilder urlString = new StringBuilder(); urlString.append("http://maps.googleapis.com/maps/api/directions/json"); urlString.append("?origin=");// from urlString.append(Double.toString(sourcelat)); urlString.append(","); urlString.append(Double.toString(sourcelog)); urlString.append("&destination=");// to urlString.append(Double.toString(destlat)); urlString.append(","); urlString.append(Double.toString(destlog)); urlString.append("&sensor=false&mode=driving&alternatives=true"); return urlString.toString(); } public class JSONParser { InputStream is = null; JSONObject jObj = null; String json = ""; // constructor public JSONParser() { } public String getJSONFromUrl(String url) { // Making HTTP request try { // defaultHttpClient DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { BufferedReader reader = new BufferedReader( new InputStreamReader(is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } json = sb.toString(); is.close(); } catch (Exception e) { Log.e("Buffer Error", "Error converting result " + e.toString()); } return json; } } public void drawPath(String result) { if (line != null) { myMap.clear(); } myMap.addMarker(new MarkerOptions().position(endLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker))); myMap.addMarker(new MarkerOptions().position(startLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker))); try { // Tranform the string into a json object final JSONObject json = new JSONObject(result); JSONArray routeArray = json.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes .getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); List list = decodePoly(encodedString); for (int z = 0; z < list.size() - 1; z++) { LatLng src = list.get(z); LatLng dest = list.get(z + 1); line = myMap.addPolyline(new PolylineOptions() .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude)) .width(5).color(Color.BLUE).geodesic(true)); } } catch (Exception e) { e.printStackTrace(); } } private List decodePoly(String encoded) { List poly = new ArrayList(); 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) <= 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) <= 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; } } 

El código funciona bien y dibuja la ruta de un lugar a otro, pero no dibuja las rutas interactivas

Screent Shot: – enter image description here

Creo que el problema es con mi método drawPath() :

 public void drawPath(String result) { if (line != null) { myMap.clear(); } myMap.addMarker(new MarkerOptions().position(endLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker))); myMap.addMarker(new MarkerOptions().position(startLatLng).icon( BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker))); try { // Tranform the string into a json object final JSONObject json = new JSONObject(result); JSONArray routeArray = json.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes .getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); List list = decodePoly(encodedString); for (int z = 0; z < list.size() - 1; z++) { LatLng src = list.get(z); LatLng dest = list.get(z + 1); line = myMap.addPolyline(new PolylineOptions() .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude)) .width(5).color(Color.BLUE).geodesic(true)); } } catch (Exception e) { e.printStackTrace(); } } 

Ignorar ¿Los marcadores me sugieren acerca de agregar polilínea interactiva?

En lugar de crear demasiados Polyline cortos, simplemente crea uno como aquí:

 PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); for (int z = 0; z < list.size(); z++) { LatLng point = list.get(z); options.add(point); } line = myMap.addPolyline(options); 

Tampoco estoy seguro de que deba usar geodesic cuando sus puntos estén tan cerca el uno del otro.

Creé un par de tutoriales de mapas que cubrirán lo que necesitas

Animar el mapa describe cómo crear polilíneas en base a un conjunto de LatLngs. Usar las API de Google en su mapa: Direcciones y lugares describe cómo usar la API de indicaciones y animar un marcador a lo largo de la ruta.

Eche un vistazo a estos 2 tutoriales y al proyecto Github que contiene la aplicación de muestra.

Contiene algunos consejos para hacer su código más limpio y más eficiente:

  • Utilizando Google HTTP Library para un acceso API más eficiente y un fácil manejo de JSON.
  • Uso de la biblioteca google-map-utils para funciones relacionadas con mapas (como la desencoding de las polilíneas)
  • Marcadores de animación

Puede usar este método para dibujar polyline en googlemap

 // Draw polyline on map public void drawPolyLineOnMap(List list) { PolylineOptions polyOptions = new PolylineOptions(); polyOptions.color(Color.RED); polyOptions.width(5); polyOptions.addAll(list); googleMap.clear(); googleMap.addPolyline(polyOptions); LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (LatLng latLng : list) { builder.include(latLng); } final LatLngBounds bounds = builder.build(); //BOUND_PADDING is an int to specify padding of bound.. try 100. CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, BOUND_PADDING); googleMap.animateCamera(cu); } 

Necesita agregar esta línea en su gradle en caso de que no lo haya hecho.

 compile 'com.google.android.gms:play-services-maps:8.4.0' 

Deberías usar options.addAll(allPoints); en lugar de options.add(point);