仍然是建议个异步小任务
1 private GetPathTask mGetPathTask = null; 2 3 private void getGuidePath(LatLng origin){ 4 if(mGetPathTask != null){ 5 mGetPathTask.cancel(true); 6 } 7 mGetPathTask = new GetPathTask(); 8 mGetPathTask.execute(origin, mMarker.getPosition()); 9 }
第8行的两个入参都是LatLng对象,分别为其实地点和目标地点。
GetPathTask任务定义如下:
1 private class GetPathTask extends AsyncTask<LatLng, Void, List<LatLng>>{ 2 3 @Override 4 protected void onPostExecute(List<LatLng> result){ 5 if((result == null) || result.isEmpty()){ 6 Toast.makeText(MapsActivity.this, R.string.GetPathErr, Toast.LENGTH_LONG).show(); 7 return; 8 } 9 10 if(mGuidePath == null){ 11 mGuidePath = mMapView.addPolyline(new PolylineOptions() 12 .color(0xfff5cb08) 13 .width(10) 14 .geodesic(true)); 15 } 16 mGuidePath.setPoints(result); 17 } 18 19 @Override 20 protected List<LatLng> doInBackground(LatLng... params) { 21 LatLng origin = params[0]; 22 LatLng destination = params[1]; 23 String responseString = null; 24 String urlString = "http://maps.google.com/maps/api/directions/xml?sensor=true&mode=walking&avoid=highways"; 25 26 HttpGet httpGet = new HttpGet(urlString + "&origin=" + origin.latitude + "," + origin.longitude 27 + "&destination=" + destination.latitude + "," + destination.longitude); 28 29 HttpResponse mHttpResponse = null; 30 HttpEntity mHttpEntity = null; 31 try{ 32 HttpParams httpParameters = new BasicHttpParams(); 33 HttpConnectionParams.setConnectionTimeout(httpParameters, 3000); 34 HttpClient httpClient = new DefaultHttpClient(httpParameters); 35 36 mHttpResponse = httpClient.execute(httpGet); 37 38 if (mHttpResponse.getStatusLine().getStatusCode() == 200){ 39 mHttpEntity = mHttpResponse.getEntity(); 40 responseString = mHttpEntity.toString(); 41 responseString = EntityUtils.toString(mHttpEntity); 42 } 43 } 44 catch (Exception e){ 45 log("Exception in GetPathTask doInBackground():" + e); 46 } 47 48 if(responseString == null){ 49 log("GetPathTask doInBackground() responseString == null"); 50 }else if (-1 == responseString.indexOf("<status>OK</status>")){ 51 log("GetPathTask doInBackground() response status error"); 52 }else{ 53 int pos1 = responseString.indexOf("<overview_polyline>"); 54 pos1 = responseString.indexOf("<points>", pos1 + 1); 55 int pos2 = responseString.indexOf("</points>", pos1); 56 responseString = responseString.substring(pos1 + 8, pos2); 57 58 List<LatLng> points = decodePoly(responseString); 59 return points; 60 } 61 return null; 62 } 63 64 private List<LatLng> decodePoly(String encoded) { 65 List<LatLng> poly = new ArrayList<LatLng>(); 66 int index = 0, len = encoded.length(); 67 int lat = 0, lng = 0; 68 69 while (index < len) { 70 if(isCancelled()) 71 break; 72 int b, shift = 0, result = 0; 73 do { 74 b = encoded.charAt(index++) - 63; 75 result |= (b & 0x1f) << shift; 76 shift += 5; 77 } while (b >= 0x20); 78 int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 79 lat += dlat; 80 81 shift = 0; 82 result = 0; 83 do { 84 b = encoded.charAt(index++) - 63; 85 result |= (b & 0x1f) << shift; 86 shift += 5; 87 } while (b >= 0x20); 88 int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 89 lng += dlng; 90 91 double dLat = lat / 1E5; 92 double dLng = lng / 1E5; 93 LatLng p = new LatLng(dLat, dLng); 94 95 poly.add(p); 96 } 97 if(isCancelled()) 98 return null; 99 100 return poly; 101 } 102 }
看doInBackgound函数
24~27行,构造一个google directions API的HTTP请求,格式类似这样:
http://maps.google.com/maps/api/directions/xml?sensor=true&mode=walking&avoid=highways&origin=纬度,经度&destination=纬度,经度
我这个设置的步行模式,避免高速,返回数据是XML格式。更多的可选项请参考官文:
https://developers.google.com/maps/documentation/directions/
48~59行,返回的response中<point></point>标签中是base64编码的数据,是一组point,即google direction 服务为我们规划出的路径途经的各个点,调用decodePoly解析成List<LatLng>。
4行,onPostExecute函数中
10~16行,调用GoogleMap.addPolyline(PolylineOptions polylineOption) 在地图上加一个折线。调用Polyline.setPoints(point)设置折线的各个点。
贴个图看看,黄色的粗线把我们导向了美丽的莫愁湖。这里我还加了一条细红线,直接指向目的地,用于在移动过程中始终标识出目的地所在方位。
google地图支持在地图上添加几种shape对象,详见官文。