Нарисуйте путь между двумя точками с помощью Google Maps Android API v2
Google изменил свой API Карт для Android и представил API V2. Предыдущие коды для рисования пути не работают с API V2.
мне удалось нарисовать путь с API V2. Я много искал решение, но не нашел никакого ответа. Поэтому я разделяю его ответ.
2 ответа:
прежде всего мы получим исходные и конечные точки, между которыми мы должны нарисовать маршрут. Затем мы передадим эти атрибуты ниже функции.
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"); urlString.append("&key=YOUR_API_KEY"); return urlString.toString(); }
эта функция сделает url, который мы отправим, чтобы получить ответ API направления. Затем мы проанализируем этот ответ . Класс синтаксического анализатора -
public class JSONParser { static InputStream is = null; static JSONObject jObj = null; static 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; } }
этот парсер вернет нам строку. Мы будем называть это так.
JSONParser jParser = new JSONParser(); String json = jParser.getJSONFromUrl(url);
теперь мы отправим эту строку в нашу функцию drawpath. Этот drawpath функция
public void drawPath(String result) { 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<LatLng> list = decodePoly(encodedString); Polyline line = mMap.addPolyline(new PolylineOptions() .addAll(list) .width(12) .color(Color.parseColor("#05b1fb"))//Google maps blue color .geodesic(true) ); /* for(int z = 0; z<list.size()-1;z++){ LatLng src= list.get(z); LatLng dest= list.get(z+1); Polyline line = mMap.addPolyline(new PolylineOptions() .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude)) .width(2) .color(Color.BLUE).geodesic(true)); } */ } catch (JSONException e) { } }
выше код будет рисовать путь на mMap. Код decodePoly-это
private List<LatLng> decodePoly(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; }
поскольку вызов направления может занять время, поэтому мы сделаем все это в асинхронной задаче. Моя асинхронная задача была
private class connectAsyncTask extends AsyncTask<Void, Void, String>{ private ProgressDialog progressDialog; String url; connectAsyncTask(String urlPass){ url = urlPass; } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); progressDialog = new ProgressDialog(MainActivity.this); 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); } } }
Я надеюсь, что это поможет.
не знаю, должен ли я поставить это как ответ или нет...
я использовал решение @Zeeshan0026, чтобы нарисовать путь...и проблема была в том, что если я нарисую путь один раз, а затем я попытаюсь нарисовать путь еще раз, оба пути покажут, и это продолжается...пути показаны даже при удалении маркеров... хотя, в идеале, старые пути " не должны быть там, как только новый путь нарисован / маркеры удалены..
проходя через какой-то другой вопрос, у меня было следующее решение
я добавляю следующую функцию в класс Zeeshan
public void clearRoute(){ for(Polyline line1 : polylines) { line1.remove(); } polylines.clear(); }
в моей деятельности карты, прежде чем рисовать путь, я вызвал эту функцию.. пример использования в соответствии с моим приложением является
private Route rt; rt.clearRoute(); if (src == null) { Toast.makeText(getApplicationContext(), "Please select your Source", Toast.LENGTH_LONG).show(); }else if (Destination == null) { Toast.makeText(getApplicationContext(), "Please select your Destination", Toast.LENGTH_LONG).show(); }else if (src.equals(Destination)) { Toast.makeText(getApplicationContext(), "Source and Destinatin can not be the same..", Toast.LENGTH_LONG).show(); }else{ rt.drawRoute(mMap, MapsMainActivity.this, src, Destination, false, "en"); }
можно использовать
rt.clearRoute();
согласно вашим требованиям.. Надеюсь, что это сэкономит несколько минут кому-то еще и поможет какому-то новичку в решении этого вопроса..Полный Код Класса
посмотреть на github
Edit: вот часть кода из mainactivity..
case R.id.mkrbtn_set_dest: Destination = selmarker.getPosition(); destmarker = selmarker; desShape = createRouteCircle(Destination, false); if (src == null) { Toast.makeText(getApplicationContext(), "Please select your Source first...", Toast.LENGTH_LONG).show(); } else if (src.equals(Destination)) { Toast.makeText(getApplicationContext(), "Source and Destinatin can not be the same..", Toast.LENGTH_LONG).show(); } else { if (isNetworkAvailable()) { rt.drawRoute(mMap, MapsMainActivity.this, src, Destination, false, "en"); src = null; Destination = null; } else { Toast.makeText( getApplicationContext(), "Internet Connection seems to be OFFLINE...!", Toast.LENGTH_LONG).show(); } } break;
Edit 2 согласно комментариям
использование :
//variables as data members GoogleMap mMap; private Route rt; static LatLng src; static LatLng Destination; //MapsMainActivity is my activity //false for interim stops for traffic, google // en language for html description returned rt.drawRoute(mMap, MapsMainActivity.this, src, Destination, false, "en");