Android GoogleMap显示覆盖所有位置的路线?

时间:2018-03-31 14:34:06

标签: android google-maps

我使用Google地图addMarker()标记了10个地点,可以显示到达所有地点的路线,这是覆盖所有地点的最短路线。如果我们点击一​​个位置,它会显示到达那里的路线,但我不仅需要连接一条路线。

1 个答案:

答案 0 :(得分:1)

optimize:true(来自Google Maps Directions API优化,最多可使用waypoints Official Docs(不包括出发地和目的地)(足以支持您的10个标记位置)你的航点部分):

  

您可以将optimize:true作为航点内的第一个参数传递   允许Directions服务优化提供的参数   通过以更有效的顺序重新安排航路点来路线。

像那样的要求:

https://maps.googleapis.com/maps/api/directions/json?origin=kilimanoor,in&destination=delhi,in&waypoints=optimize:true|via:12.972614,77.619728|via:17.381196,78.491409|via:21.150758,79.090297&key=YOUR_API_KEY

并且你应该解析JSON响应,例如,根据它绘制路径折线(你需要来自overview_polyline标签的数据)。您可以使用以下代码:

  private String buildDirectionsUrl(List<LatLng> trackPoints) {

    if (trackPoints.size() < 2) {
        return null;
    }

    final LatLng origin = trackPoints.get(0);
    final LatLng dest = trackPoints.get(trackPoints.size() - 1);

    StringBuilder url = new StringBuilder();
    url.append("https://maps.googleapis.com/maps/api/directions/json?");
    url.append(String.format("origin=%8.5f,%8.5f", origin.latitude, origin.longitude));
    url.append(String.format("&destination=%8.5f,%8.5f", dest.latitude, dest.longitude));

    // add waypoints, if they exists
    if (trackPoints.size() > 2) {
        url.append("&waypoints=optimize:true|");
        LatLng wayPoint;
        for (int ixWaypoint = 1; ixWaypoint < trackPoints.size() - 2; ixWaypoint++) {
            wayPoint = trackPoints.get(ixWaypoint);
            url.append(String.format("%8.5f,%8.5f|", wayPoint.latitude, wayPoint.longitude));
        }
        url.delete(url.length() - 1, url.length());
    }

    url.append(String.format("&key=%s", getResources().getString(R.string.google_maps_key)));

    return url.toString();
}


private class GetDirectionPointsAsyncTask extends AsyncTask<List<LatLng>, Void, List<LatLng>> {

    protected void onPreExecute() {
        super.onPreExecute();
    }

    protected List<LatLng> doInBackground(List<LatLng>... params) {

        List<LatLng> routePoints = new ArrayList<>();

        HttpURLConnection connection = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(buildDirectionsUrl(params[0]));
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            int responseCode = connection.getResponseCode();
            InputStream stream = connection.getInputStream();

            reader = new BufferedReader(new InputStreamReader(stream));
            StringBuilder jsonStringBuilder = new StringBuilder();

            StringBuffer buffer = new StringBuffer();
            String line = "";

            while ((line = reader.readLine()) != null) {
                buffer.append(line+"\n");
                jsonStringBuilder.append(line);
                jsonStringBuilder.append("\n");
            }

            JSONObject jsonRoot = new JSONObject(jsonStringBuilder.toString());
            JSONArray jsonRoutes = jsonRoot.getJSONArray("routes");

            if (jsonRoutes.length() < 1) {
                return null;
            }

            JSONObject jsonRoute = jsonRoutes.getJSONObject(0);
            JSONObject overviewPolyline = jsonRoute.getJSONObject("overview_polyline");
            String overviewPolylineEncodedPoints = overviewPolyline.getString("points");
            routePoints = decodePoly(overviewPolylineEncodedPoints);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return routePoints;
    }

    @Override
    protected void onPostExecute(List<LatLng> result) {
        super.onPostExecute(result);

        PolylineOptions polyLineOptions = new PolylineOptions();
        polyLineOptions.addAll(result);
        polyLineOptions.width(5);
        polyLineOptions.color(Color.RED);
        mGoogleMap.addPolyline(polyLineOptions);

        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        builder.include(result.get(0));
        builder.include(result.get(result.size()-1));
        LatLngBounds bounds = builder.build();
        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));

    }
}

//
// Method to decode polyline points
// Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
private List<LatLng> decodePoly(String encoded) {

    List<LatLng> poly = new ArrayList<>();
    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;
}

另见this教程。