Android:如何从当前位置到目的地绘制路线方向谷歌地图API V2
如何绘制从当前位置到目的地(经纬度)的路线方向,我的代码如下:
import android.os.Bundle; import com.actionbarsherlock.app.SherlockActivity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; public class DetailMapActivity extends SherlockActivity { private GoogleMap map; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_detail_map); LatLng TO_DESTINATION = new LatLng(-6.33438, 106.74316); map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)) .getMap(); map.setMyLocationEnabled(true); map.addMarker(new MarkerOptions().position(TO_DESTINATION).title("Destination Title") .snippet("Destination Description")); map.moveCamera(CameraUpdateFactory.newLatLngZoom(TO_LOCATION, 40)); map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); } }
我想通过提供商networking或gps从当前位置提取,然后通过开车到目的地来绘制路线。
我正在使用Android谷歌apis V2。
谢谢你的帮助。
这对我很好:
这不是我的代码 ,我把它从一个很好的答案在stackoverflow,但我现在找不到这个答案,所以这里是代码:
将这个类添加到您的项目中:
package ...; import java.io.InputStream; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.google.android.gms.maps.model.LatLng; import android.content.Context; import android.util.Log; public class GMapV2Direction { public final static String MODE_DRIVING = "driving"; public final static String MODE_WALKING = "walking"; public GMapV2Direction() { } public Document getDocument(LatLng start, LatLng end, String mode) { String url = "http://maps.googleapis.com/maps/api/directions/xml?" + "origin=" + start.latitude + "," + start.longitude + "&destination=" + end.latitude + "," + end.longitude + "&sensor=false&units=metric&mode=driving"; Log.d("url", url); try { HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpPost httpPost = new HttpPost(url); HttpResponse response = httpClient.execute(httpPost, localContext); InputStream in = response.getEntity().getContent(); DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); Document doc = builder.parse(in); return doc; } catch (Exception e) { e.printStackTrace(); } return null; } public String getDurationText(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("duration"); Node node1 = nl1.item(0); NodeList nl2 = node1.getChildNodes(); Node node2 = nl2.item(getNodeIndex(nl2, "text")); Log.i("DurationText", node2.getTextContent()); return node2.getTextContent(); } catch (Exception e) { return "0"; } } public int getDurationValue(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("duration"); Node node1 = nl1.item(0); NodeList nl2 = node1.getChildNodes(); Node node2 = nl2.item(getNodeIndex(nl2, "value")); Log.i("DurationValue", node2.getTextContent()); return Integer.parseInt(node2.getTextContent()); } catch (Exception e) { return -1; } } public String getDistanceText(Document doc) { /* * while (en.hasMoreElements()) { type type = (type) en.nextElement(); * * } */ try { NodeList nl1; nl1 = doc.getElementsByTagName("distance"); Node node1 = nl1.item(nl1.getLength() - 1); NodeList nl2 = null; nl2 = node1.getChildNodes(); Node node2 = nl2.item(getNodeIndex(nl2, "value")); Log.d("DistanceText", node2.getTextContent()); return node2.getTextContent(); } catch (Exception e) { return "-1"; } /* * NodeList nl1; if(doc.getElementsByTagName("distance")!=null){ nl1= * doc.getElementsByTagName("distance"); * * Node node1 = nl1.item(nl1.getLength() - 1); NodeList nl2 = null; if * (node1.getChildNodes() != null) { nl2 = node1.getChildNodes(); Node * node2 = nl2.item(getNodeIndex(nl2, "value")); Log.d("DistanceText", * node2.getTextContent()); return node2.getTextContent(); } else return * "-1";} else return "-1"; */ } public int getDistanceValue(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("distance"); Node node1 = null; node1 = nl1.item(nl1.getLength() - 1); NodeList nl2 = node1.getChildNodes(); Node node2 = nl2.item(getNodeIndex(nl2, "value")); Log.i("DistanceValue", node2.getTextContent()); return Integer.parseInt(node2.getTextContent()); } catch (Exception e) { return -1; } /* * NodeList nl1 = doc.getElementsByTagName("distance"); Node node1 = * null; if (nl1.getLength() > 0) node1 = nl1.item(nl1.getLength() - 1); * if (node1 != null) { NodeList nl2 = node1.getChildNodes(); Node node2 * = nl2.item(getNodeIndex(nl2, "value")); Log.i("DistanceValue", * node2.getTextContent()); return * Integer.parseInt(node2.getTextContent()); } else return 0; */ } public String getStartAddress(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("start_address"); Node node1 = nl1.item(0); Log.i("StartAddress", node1.getTextContent()); return node1.getTextContent(); } catch (Exception e) { return "-1"; } } public String getEndAddress(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("end_address"); Node node1 = nl1.item(0); Log.i("StartAddress", node1.getTextContent()); return node1.getTextContent(); } catch (Exception e) { return "-1"; } } public String getCopyRights(Document doc) { try { NodeList nl1 = doc.getElementsByTagName("copyrights"); Node node1 = nl1.item(0); Log.i("CopyRights", node1.getTextContent()); return node1.getTextContent(); } catch (Exception e) { return "-1"; } } public ArrayList<LatLng> getDirection(Document doc) { NodeList nl1, nl2, nl3; ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>(); nl1 = doc.getElementsByTagName("step"); if (nl1.getLength() > 0) { for (int i = 0; i < nl1.getLength(); i++) { Node node1 = nl1.item(i); nl2 = node1.getChildNodes(); Node locationNode = nl2 .item(getNodeIndex(nl2, "start_location")); nl3 = locationNode.getChildNodes(); Node latNode = nl3.item(getNodeIndex(nl3, "lat")); double lat = Double.parseDouble(latNode.getTextContent()); Node lngNode = nl3.item(getNodeIndex(nl3, "lng")); double lng = Double.parseDouble(lngNode.getTextContent()); listGeopoints.add(new LatLng(lat, lng)); locationNode = nl2.item(getNodeIndex(nl2, "polyline")); nl3 = locationNode.getChildNodes(); latNode = nl3.item(getNodeIndex(nl3, "points")); ArrayList<LatLng> arr = decodePoly(latNode.getTextContent()); for (int j = 0; j < arr.size(); j++) { listGeopoints.add(new LatLng(arr.get(j).latitude, arr .get(j).longitude)); } locationNode = nl2.item(getNodeIndex(nl2, "end_location")); nl3 = locationNode.getChildNodes(); latNode = nl3.item(getNodeIndex(nl3, "lat")); lat = Double.parseDouble(latNode.getTextContent()); lngNode = nl3.item(getNodeIndex(nl3, "lng")); lng = Double.parseDouble(lngNode.getTextContent()); listGeopoints.add(new LatLng(lat, lng)); } } return listGeopoints; } private int getNodeIndex(NodeList nl, String nodename) { for (int i = 0; i < nl.getLength(); i++) { if (nl.item(i).getNodeName().equals(nodename)) return i; } return -1; } private ArrayList<LatLng> decodePoly(String encoded) { ArrayList<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 position = new LatLng((double) lat / 1E5, (double) lng / 1E5); poly.add(position); } return poly; } }
然后使用这个类为您的需要。
例如要画出方向:
GMapV2Direction md = new GMapV2Direction(); mMap = ((SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map)).getMap(); Document doc = md.getDocument(sourcePosition, destPosition, GMapV2Direction.MODE_DRIVING); ArrayList<LatLng> directionPoint = md.getDirection(doc); PolylineOptions rectLine = new PolylineOptions().width(3).color( Color.RED); for (int i = 0; i < directionPoint.size(); i++) { rectLine.add(directionPoint.get(i)); } Polyline polylin = mMap.addPolyline(rectLine);
sourcePosition, destPosition
来自LatLngtypes,你给他们想要的点。
我在这里写了我认为可以帮助的部分代码,欢迎任何问题。
使用dvrm解决schemeGMapV2Direction类 ,这是一个很好的解决scheme,它仍然在工作,但现在你需要在一个新的线程中实现getDocument方法来允许networking连接。 这是一个AsyncTask这个方法的例子,其余的类是一样的。 你可以用Handle处理它,或者实现你自己的接口callback来获得Docmuent xml响应。
public class GMapV2DirectionAsyncTask extends AsyncTask<String, Void, Document> { private final static String TAG = GMapV2DirectionAsyncTask.class.getSimpleName(); private Handler handler; private LatLng start, end; private String mode; public GMapV2DirectionAsyncTask(Handler handler, LatLng start, LatLng end, String mode) { this.start = start; this.end = end; this.mode = mode; this.handler = handler; } @Override protected Document doInBackground(String... params) { String url = "http://maps.googleapis.com/maps/api/directions/xml?" + "origin=" + start.latitude + "," + start.longitude + "&destination=" + end.latitude + "," + end.longitude + "&sensor=false&units=metric&mode=" + mode; Log.d("url", url); try { HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpPost httpPost = new HttpPost(url); HttpResponse response = httpClient.execute(httpPost, localContext); InputStream in = response.getEntity().getContent(); DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); Document doc = builder.parse(in); return doc; } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Document result) { if (result != null) { Log.d(TAG, "---- GMapV2DirectionAsyncTask OK ----"); Message message = new Message(); message.obj = result; handler.dispatchMessage(message); } else { Log.d(TAG, "---- GMapV2DirectionAsyncTask ERROR ----"); } } @Override protected void onPreExecute() { } @Override protected void onProgressUpdate(Void... values) { }
}
这是该活动的asynchronous处理程序方法:
protected void route(LatLng sourcePosition, LatLng destPosition, String mode) { final Handler handler = new Handler() { public void handleMessage(Message msg) { try { Document doc = (Document) msg.obj; GMapV2Direction md = new GMapV2Direction(); ArrayList<LatLng> directionPoint = md.getDirection(doc); PolylineOptions rectLine = new PolylineOptions().width(15).color(getActivity().getResources().getColor(R.color.magoo_user_base_color)); for (int i = 0; i < directionPoint.size(); i++) { rectLine.add(directionPoint.get(i)); } Polyline polylin = googleMap.addPolyline(rectLine);md.getDurationText(doc)); } catch (Exception e) { e.printStackTrace(); } } ; }; new GMapV2DirectionAsyncTask(handler, sourcePosition, destPosition, GMapV2Direction.MODE_DRIVING).execute(); }
还有一件事,如果持续时间值是错误的,那么解决方法是更改GMapV2Direction类的一行代码:
Node node1 = nl1.item(nl1.getLength() - 1);
代替:
Node node1 = nl1.item(0);
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_detail_map); ..... ..... /* Use the LocationManager class to obtain GPS locations */ LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); LocationListener mlocListener = new MyLocationListener(); mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener); } /* Class My Location Listener */ public class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { CURRENT_LAT = loc.getLatitude(); CURRENT_LNG = loc.getLongitude(); } @Override public void onProviderDisabled(String provider) { Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show(); } @Override public void onProviderEnabled(String provider) { Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } }