Google Maps API和标记之间的自定折线路线
我想为Android应用程序做一个自定义的路线,我不知道我应该使用哪个API,以及它是否与Java兼容。
据我所知,我需要使用航点来build立一条路线(我不需要知道两点之间的距离,只是做一个路线)。
目标是从地图侧面的菜单中select一个选项,并显示两个标记之间的自定义路线之一。
您可以使用适用于Android的Google Maps API v2和Google Maps Directions web服务API来执行此操作
对于Google Maps API的入门,还有很多其他的好的答案。 在这里看到一个简单的地图活动的完整工作示例。 请注意,您还需要设置API密钥以与您的项目配合使用。
至于使用Google Maps Directions webservice API,您应该先阅读文档。 您可以使用API密钥并在您的开发人员控制台中启用该API,但仍可以在不使用API密钥的情况下正常工作。
以下是为了使用Google Maps API在两点之间绘制多段线所需的基本代码,请注意从API返回的点编码为需要解码的基本64编码string。
首先,这里是AsyncTask,你应该给它两个LatLng点来调用它。
您可以使用两个LatLng对象调用AsyncTask,例如在两个标记之间:
new GetDirectionsAsync().execute(markerOne.getPosition(), markerTwo.getPosition());
这是AsyncTask代码:
class GetDirectionsAsync extends AsyncTask<LatLng, Void, List<LatLng>> { JSONParser jsonParser; String DIRECTIONS_URL = "https://maps.googleapis.com/maps/api/directions/json"; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected List<LatLng> doInBackground(LatLng... params) { LatLng start = params[0]; LatLng end = params[1]; HashMap<String, String> points = new HashMap<>(); points.put("origin", start.latitude + "," + start.longitude); points.put("destination", end.latitude + "," + end.longitude); jsonParser = new JSONParser(); JSONObject obj = jsonParser.makeHttpRequest(DIRECTIONS_URL, "GET", points, true); if (obj == null) return null; try { List<LatLng> list = null; JSONArray routeArray = obj.getJSONArray("routes"); JSONObject routes = routeArray.getJSONObject(0); JSONObject overviewPolylines = routes.getJSONObject("overview_polyline"); String encodedString = overviewPolylines.getString("points"); list = decodePoly(encodedString); return list; } catch (JSONException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(List<LatLng> pointsList) { if (pointsList == null) return; if (line != null){ line.remove(); } PolylineOptions options = new PolylineOptions().width(5).color(Color.MAGENTA).geodesic(true); for (int i = 0; i < pointsList.size(); i++) { LatLng point = pointsList.get(i); options.add(point); } line = mMap.addPolyline(options); } }
AsyncTask引用Activity的一些成员variables,即Polyline和GoogleMap,Activity的定义如下所示:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback{ GoogleMap mMap; Polyline line; //.....
以下是用于解码点的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; }
下面是这个例子中使用的JSONParser类,请注意,这是一个为android-23更新的修改版本,我写了一篇博客文章 :
public class JSONParser { String charset = "UTF-8"; HttpURLConnection conn; DataOutputStream wr; StringBuilder result; URL urlObj; JSONObject jObj = null; StringBuilder sbParams; String paramsString; public JSONObject makeHttpRequest(String url, String method, HashMap<String, String> params, boolean encode) { sbParams = new StringBuilder(); int i = 0; for (String key : params.keySet()) { try { if (i != 0){ sbParams.append("&"); } if (encode) { sbParams.append(key).append("=") .append(URLEncoder.encode(params.get(key), charset)); } else{ sbParams.append(key).append("=") .append(params.get(key)); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } i++; } if (method.equals("POST")) { // request method is POST try { urlObj = new URL(url); conn = (HttpURLConnection) urlObj.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Accept-Charset", charset); conn.setReadTimeout(10000); conn.setConnectTimeout(15000); conn.connect(); paramsString = sbParams.toString(); wr = new DataOutputStream(conn.getOutputStream()); wr.writeBytes(paramsString); wr.flush(); wr.close(); } catch (IOException e) { e.printStackTrace(); } } else if(method.equals("GET")){ // request method is GET if (sbParams.length() != 0) { url += "?" + sbParams.toString(); } Log.d("JSONParser", "full GET url: " + url); try { urlObj = new URL(url); conn = (HttpURLConnection) urlObj.openConnection(); conn.setDoOutput(false); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept-Charset", charset); conn.setConnectTimeout(15000); conn.connect(); } catch (IOException e) { e.printStackTrace(); } } try { //Receive the response from the server InputStream in = new BufferedInputStream(conn.getInputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; result = new StringBuilder(); while ((line = reader.readLine()) != null) { result.append(line); } Log.d("JSON Parser", "result: " + result.toString()); } catch (IOException e) { e.printStackTrace(); } conn.disconnect(); // try parse the string to a JSON object try { jObj = new JSONObject(result.toString()); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } // return JSON Object return jObj; } }
在两个标记之间绘制路线的结果: