【问题标题】:Map View draw directions using google Directions API - decoding polylines地图视图绘制方向使用谷歌方向 API - 解码折线
【发布时间】:2011-07-15 14:18:12
【问题描述】:

我正在尝试使用 Google 路线 API 在我的地图视图上显示路线,但我在从 JSON 响应中获取数据时遇到了困难。我可以得到“级别”和“点”字符串,但不知道如何将它们解码为地图上的点。

任何帮助将不胜感激。

【问题讨论】:

    标签: android json google-maps android-mapview polyline


    【解决方案1】:

    我有一个可以为你解码的类,添加下面的类,然后像这样调用你的代码:

    int[] decodedZoomLevels = PolylineDecoder.decodeZoomLevels(levels);
    GeoPoint[] gPts = PolylineDecoder.decodePoints(points, decodedZoomLevels.length);
    

    其中pointslevels 是您从JSON 响应中提取的数据。然后,您可以遍历地理点数组,在它们之间画一条线以显示您的方向。

    希望这会有所帮助!肯尼


    编辑:谷歌方向 API 似乎不再返回缩放级别字符串作为 JSON 响应的一部分,不过不用担心,我们使用它的目的只是检查点数,所以我们可以简单地将它们放入如下列表中:

    public static List <GeoPoint> decodePoints(String encoded_points){
    int index = 0;
    int lat = 0;
    int lng = 0;
    List <GeoPoint> out = new ArrayList<GeoPoint>();
    
    try {
        int shift;
        int result;
        while (index < encoded_points.length()) {
            shift = 0;
            result = 0;
            while (true) {
                int b = encoded_points.charAt(index++) - '?';
                result |= ((b & 31) << shift);
                shift += 5;
                if (b < 32)
                    break;
            }
            lat += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
    
            shift = 0;
            result = 0;
            while (true) {
                int b = encoded_points.charAt(index++) - '?';
                result |= ((b & 31) << shift);
                shift += 5;
                if (b < 32)
                    break;
            }
            lng += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
            /* Add the new Lat/Lng to the Array. */
            out.add(new GeoPoint((lat*10),(lng*10)));
        }
        return out;
    }catch(Exception e) {
        e.printStackTrace();
    }
    return out;
    }
    

    编辑:旧代码

    public class PolylineDecoder {
    /**
     * Transform a encoded PolyLine to a Array of GeoPoints.
     * Java implementation of the original Google JS code.
     * @see Original encoding part: <a href="http://code.google.com/apis/maps/documentation/polylinealgorithm.html">http://code.google.com/apis/maps/documentation/polylinealgorithm.html</a>
     * @return Array of all GeoPoints decoded from the PolyLine-String.
     * @param encoded_points String containing the encoded PolyLine. 
     * @param countExpected Number of points that are encoded in the PolyLine. Easiest way is to use the length of the ZoomLevels-String. 
     * @throws DecodingException 
     */
    public static GeoPoint[] decodePoints(String encoded_points, int countExpected){
        int index = 0;
        int lat = 0;
        int lng = 0;
        int cnt = 0;
        GeoPoint[] out = new GeoPoint[countExpected];
    
        try {
            int shift;
            int result;
            while (index < encoded_points.length()) {
                shift = 0;
                result = 0;
                while (true) {
                    int b = encoded_points.charAt(index++) - '?';
                    result |= ((b & 31) << shift);
                    shift += 5;
                    if (b < 32)
                        break;
                }
                lat += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
    
                shift = 0;
                result = 0;
                while (true) {
                    int b = encoded_points.charAt(index++) - '?';
                    result |= ((b & 31) << shift);
                    shift += 5;
                    if (b < 32)
                        break;
                }
                lng += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
                /* Add the new Lat/Lng to the Array. */
                out[cnt++] = new GeoPoint((lat*10),(lng*10));
            }
            return out;
        }catch(Exception e) {
            e.printStackTrace();
        }
        return out;
    }
    
    public static int[] decodeZoomLevels(String encodedZoomLevels){
        int[] out = new int[encodedZoomLevels.length()];
        int index = 0;
    
        for(char c : encodedZoomLevels.toCharArray())
            out[index++] = c - '?';
        return out;
    
    }
    }
    

    【讨论】:

    • 哇!非常感谢这门课!
    • 嗨肯尼,我怎样才能得到级别编码的字符串?还是levels和points字符串是一样的?
    • llango J - 似乎他们已将其从响应中删除,所以它只是您现在得到的分数。我已修改代码以仅使用这一个参数,您应该在编辑后的答案中看到它!
    • 嗨,现在有一个新的谷歌地图版本,新的 api 不支持 GeoPoint 类。我可以使用 LatLng(double lat,double lng) 代替 GeoPoint(int, int) 吗?
    • 这会在 int b = encoded_points.charAt(index++) - '?' 行上产生异常(StringIndexOutOfBoundsException)对于第二个内部while循环,如何处理?谢谢
    【解决方案2】:

    您可以使用Google Maps Android API Utility Library。它提出了一个PolyUtil.decode(String encoded) 方法,可以完全满足您的需求!

    【讨论】:

      【解决方案3】:

      GeoPoint 对我不起作用,我找不到使用它的库。这是一个返回 LatLng 值的函数。

      public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
          int len = encodedPath.length();
      
          final ArrayList<LatLng> path = new ArrayList<LatLng>();
          int index = 0;
          int lat = 0;
          int lng = 0;
      
          while (index < len) {
              int result = 1;
              int shift = 0;
              int b;
              do {
                  b = encodedPath.charAt(index++) - 63 - 1;
                  result += b << shift;
                  shift += 5;
              } while (b >= 0x1f);
              lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
      
              result = 1;
              shift = 0;
              do {
                  b = encodedPath.charAt(index++) - 63 - 1;
                  result += b << shift;
                  shift += 5;
              } while (b >= 0x1f);
              lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
      
              path.add(new LatLng(lat * 1e-5, lng * 1e-5));
          }
      
          return path;
      }
      

      Google Maps Android API utility library 获取。 代码可以找到here

      在代码中使用硬编码字符串进行测试时的一些提醒,Java 无法正确读取

      "\"
      

      您需要添加另一个斜线才能被 java 正确读取。

      "\\"
      

      请注意,因为编码的字符串包含奇怪的字符。

      【讨论】:

        【解决方案4】:

        下面的代码解码任何编码的折线

        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=0, shift = 0, result = 0;
                do {
                    if(index<len) {
                        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 {
                    if(index<len) {
                        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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-11
          • 1970-01-01
          • 2015-03-17
          • 1970-01-01
          • 2013-07-02
          • 2023-04-06
          • 2011-12-03
          • 1970-01-01
          相关资源
          最近更新 更多