【问题标题】:Polyline between two locations not snapped to road两个位置之间的折线未捕捉到道路
【发布时间】:2017-09-28 22:24:17
【问题描述】:

我正在尝试在 Android 中的 Google 地图上相距一定距离(例如超过 100 英里)的两个位置之间绘制一条平滑的折线。在使用 Directions 和 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检索到的 GPS 点来传播 Snap to Roads API 的 100 个坐标分配> 来自 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
        }

    });

【问题讨论】:

  • 你为什么要这样做? String formattedResponse = points.replaceAll("'\\'", "'\'");
  • 嗨丹尼尔,根据这个链接developers.google.com/maps/documentation/utilities/…:'请注意,反斜杠被解释为字符串文字中的转义字符。此实用程序的任何输出都应将反斜杠字符转换为字符串文字中的双反斜杠。我尝试了一些组合,这是让它工作的唯一方法之一,除非我完全误读了这个。
  • 对不起,我的错误我现在已经删除了这行,没有它似乎也可以工作。但是,问题仍然存在,因为坐标不遵循道路轮廓。

标签: java android google-maps google-polyline


【解决方案1】:

好的,如果有人遇到这个问题或类似问题,我已经设法解决了这个问题,似乎在地图上正确绘制一条遵循道路平滑轮廓的折线的方法是使用每个单独的 折线 > point 每个 steps 对象内的编码字符串。我似乎也误读了documentation,它清楚地说明了每个 steps 对象中的折线编码字符串提供了每个步骤的近似平滑路径,我想其他人也可能错过了。

基本上,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
        }

    });

【讨论】:

    【解决方案2】:

    directions api 中的编码点已经“捕捉”到道路,因此无需使用任何额外的 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);
    

    这是结果:

    【讨论】:

    • 嗨,丹尼尔,再次感谢您的意见,但我刚刚尝试了您建议的代码,但仍然存在快速道路问题。我将在我的原始帖子中附上一张照片,以使用您的代码为您提供一个示例,以说明我一直面临的相同问题。
    • 我似乎无法附上上面的图片,尽管这里有一个链接来说明我仍然面临的问题:imgur.com/a/IM0bk。似乎当您从远处缩小折线时,它们似乎还可以。只是我见过其他例子,即使近距离,它们也紧紧地贴在道路上。
    • @RichardAnsell 你能给我你正在使用的开始纬度/经度和结束纬度/经度吗?我可以试试看是否得到相同的结果。
    • @RichardAnsell 嗯,你是对的,它在某些路段没有正确捕捉到道路。看起来像是方向api的限制,似乎他们的英格兰数据不如海湾地区的数据完整。
    • 这么想,感谢上帝,你也看到了这个。这很令人沮丧,因为我真的认为我一直在做完全错误的事情。至少通过这种方式,我知道我可以使用我们现有的 API。我确实尝试实现一种在 100 个 GPS 点内工作的方法,并尝试使用 Snap to Roads API,但这需要更多时间来完成。非常感谢您的帮助,Daniel,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多