两个位置之间的折线没有卡入道路

时间:2017-09-28 22:24:18

标签: java android google-maps google-polyline

我正试图在Android上的Google地图上两个相距一定距离(比如超过100英里)的位置之间绘制一条平滑折线。在使用Directions and Snap to Roads API方面,我一直关注此guide以及此guide,但由于Snap to Roads API的100个坐标限制,它似乎是几乎不可能将平滑的折线从一个位置绘制到另一个位置,沿着平滑的道路轮廓绘制。

我已设法提取方向的所有坐标以使用返回的 overview_points 绘制折线,并使用PolyUtil API中的解码方法对其进行解码,但是绘制了折线在绝大多数情况下,地图不会被抢断。相反,我尝试使用Snap to Roads API并设置了100个坐标的限制(允许的最大GPS点数),这些坐标似乎非常准确地从目的地A到B被捕捉到了道路(仅覆盖两个位置之间的一些距离)如果相距甚远)。

基本上,是否存在我完全缺失的内容,或是使用从 overview_points 从Directions API,即每隔XXX米绘制一个坐标。

以下是我通过Volley请求减去Snap to Roads请求实现的大部分代码,后者实现相当简单:

StringRequest stringRequest = new StringRequest(Request.Method.GET, 
"https://maps.googleapis.com/maps/api/directions/json?
origin=START_LOCATION_HERE&destination=END_LOCATION_HERE&key=API_KEY_HERE",
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    JSONObject directions;
                    try {
                        directions = new JSONObject(response);

                        JSONArray routes = directions.getJSONArray("routes");

                        mCoordinates = new ArrayList<>();
                        for (int i = 0; i < routes.length(); i++) {
                            JSONObject routesObject = routes.getJSONObject(i);

                            JSONObject overviewPolyline = routesObject.getJSONObject("overview_polyline");
                            String points = overviewPolyline.getString("points");

                            List<LatLng> coordinates = new ArrayList<>();
                            coordinates.addAll(PolyUtil.decode(points));

                            PolylineOptions routeCoordinates = new PolylineOptions();
                            for (LatLng latLng : coordinates) {
                                routeCoordinates.add(new LatLng(latLng.latitude, latLng.longitude));
                            }
                            routeCoordinates.width(5);
                            routeCoordinates.color(Color.BLUE);

                            Polyline route = mGoogleMap.addPolyline(routeCoordinates);
                            for (LatLng latLng : coordinates) {
                                mGoogleMap.addMarker(new MarkerOptions().position(new LatLng(latLng.latitude, latLng.longitude)));
                            }

                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // TODO handle error
        }

    });

2 个答案:

答案 0 :(得分:3)

好吧,如果有人遇到过这个问题或者类似问题,我已经成功解决了这个问题,似乎在地图上正确绘制折线的方法就是使用每个人折线&gt;每个步骤对象中的 point 编码字符串。我似乎误读documentation明确指出每个步骤对象中的折线编码字符串提供了每个步骤的近似平滑路径,我想其他人也可能错过了

基本上, overview_polyline 编码的字符串仅提供路线的概述,因此不能在位置之间提供平滑的路径。它可能非常适合由大部分直线组成的路线(显然在英国不是很好),因此每个单独的折线编码字符串都是需要的。我刚刚对此进行了测试,它完美无缺,完全不需要Snap to Roads API。

我在用例中修改问题的修改代码如下:

    StringRequest stringRequest = new StringRequest(Request.Method.GET, "https://maps.googleapis.com/maps/api/directions/json?origin=START_LOCATION&destination=END_LOCATION&key=API_KEY",
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {

                    JSONObject directions;
                    try {
                        directions = new JSONObject(response);

                        JSONArray routes = directions.getJSONArray("routes");

                        mCoordinates = new ArrayList<>();
                        for (int a = 0; a < routes.length(); a++) {
                            JSONObject routesObject = routes.getJSONObject(a);

                            JSONArray legsArray = routesObject.getJSONArray("legs");
                            for (int b = 0; b < legsArray.length(); b++) {
                                JSONObject legsObject = legsArray.getJSONObject(b);
                                JSONArray steps = legsObject.getJSONArray("steps");
                                for (int c = 0; c < steps.length(); c++) {
                                    JSONObject stepsObject = steps.getJSONObject(c);
                                    JSONObject polyLineObject = stepsObject.getJSONObject("polyline");
                                    mCoordinates.addAll(PolyUtil.decode(polyLineObject.getString("points")));
                                }
                            }

                            PolylineOptions routeCoordinates = new PolylineOptions();
                            for (LatLng latLng : mCoordinates) {
                                routeCoordinates.add(new LatLng(latLng.latitude, latLng.longitude));
                            }
                            routeCoordinates.width(5);
                            routeCoordinates.color(Color.BLUE);

                            Polyline route  = mGoogleMap.addPolyline(routeCoordinates);

                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // TODO handle error
        }

    });

答案 1 :(得分:0)

来自方向api的编码点已经被&#34; snapped&#34;到道路,所以不需要使用任何额外的API。

使用此代码解析/解码路径中的点:

List<LatLng> pointsList = null;
JSONArray routeArray = obj.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
pointsList = PolyUtil.decode(encodedString);

然后绘制折线:

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);

结果如下:

enter image description here