使用Google Maps Android API v2绘制两点之间的路径
Google改变了Android的地图API并引入了API V2。 以前的绘图路径代码不适用于API V2。
我设法用API V2绘制了一条路径。 我已经搜索了很多的解决方案,但没有找到任何答案。 所以我正在分享它的答案。
首先,我们将获得源点和目标点之间的路线。 然后我们将这些属性传递给下面的函数。
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上看到
编辑:这里是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;
按照评论编辑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");