Decoding polyline with new Google Maps API

后端 未结 6 1675
时光取名叫无心
时光取名叫无心 2020-12-07 21:12

I am drawing a route between two points in a map. I receive the points this way:

StringBuilder urlString = new StringBuilder();
    urlString.append("htt         


        
相关标签:
6条回答
  • 2020-12-07 21:49

    I changed the decodePoly that I was using for this one I found after a long search in Google, and now the route is drawn properly.

    http://wptrafficanalyzer.in/blog/route-between-two-locations-with-waypoints-in-google-map-android-api-v2/

    Changing

    LatLng p = new LatLng((int) (((double) lat /1E5)* 1E6), (int) (((double) lng/1E5   * 1E6)));
    

    for

    LatLng p = new LatLng((((double) lat / 1E5)),(((double) lng / 1E5)));
    

    And now works.

    0 讨论(0)
  • 2020-12-07 21:49

    Same in Pascal (Delphi):

    function DecodeLine(inputstring: String): String;
    var
      lat, lon, lat_f, lon_f: Double;
      index: Integer;
      len: Integer;
      b: Integer;
      shift: Integer;
      decodeResult: Integer;
      encoded: String;
      dlat: Integer;
      dlng: Integer;
    begin
      Result := '';
    
      encoded := inputstring;
      len := Length(encoded);
      index := 1;
      lat := 0;
      lon := 0;
    
      while (index <= len) do begin
        b := $20;
        shift := 0;
        decodeResult := 0;
    
        while (b >= $20) do begin
          b := ord(encoded[index]);
          b := b - 63;
          inc(index);
          decodeResult := decodeResult or (b and $1f) Shl shift;
          shift := shift + 5;
        end;
    
        if (decodeResult and 1) <> 0 then
          dlat := not (decodeResult shr 1)
        else
          dlat := decodeResult shr 1;
        lat := lat+dlat;
    
        shift := 0;
        decodeResult := 0;
        b := $20;
        while (b >= $20) do begin
          b := ord(encoded[index]);
          b := b-63;
          inc(index);
          decodeResult := decodeResult or (b and $1f) Shl shift;
          shift := shift + 5;
        end;
    
        if (decodeResult and 1) <> 0 then
          dlng := not (decodeResult shr 1)
        else
          dlng := decodeResult shr 1;
        lon := lon + dlng;
    
        { The coordinates of the point are used for our purposes }
        lon_f := lon/100000.0;
        lat_f := lat/100000.0;
    
        if Result <> '' then
          Result := Result + ', ';
        Result := Result + '(' + FloatToStr(lon_f) + ' - ' + FloatToStr(lat_f) + ')';
      end; //while
    end;
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      str: String;
    begin
      // Do stuff
      str := DecodeLine('ibgqGq}ycIMvM');
      ShowMessage(str);
    end;
    
    0 讨论(0)
  • 2020-12-07 21:51

    This method is useful for decoding polyline

     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 is how i'm getting polyline

    JSONObject poly = route.getJSONObject("overview_polyline");
    String polyline = poly.getString("points");
    polyLineList = decodePoly(polyline);
    
    0 讨论(0)
  • 2020-12-07 21:52

    Here is the implementation in iOS, for anybody who is curious, which is entirely based upon @Fustigador's answer, but converted to iOS. Note that I have not formatted the code accordingly. I only added some variables for the sake of returning the promised object.

    - (GMSPath *)decodedPolylinePathFromEncodedPolylineString:(NSString *)encodedPolylineString {
    
    
        NSString *decodedPolylineString = @"";
        GMSMutablePath *decodedPolylinePath = [GMSMutablePath new];
        CLLocationCoordinate2D decodedCoordinate;
        CLLocationDegrees latitude, longitude;
    
        int index = 0;
        NSUInteger len = encodedPolylineString.length;
    
        int lat = 0, lng = 0;
    
        while (index < len) {
            int b, shift = 0, result = 0;
            do {
    
                b = [encodedPolylineString characterAtIndex: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 = [encodedPolylineString characterAtIndex:index++] - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;
    
            latitude =  (((double) lat / 1E5));
            longitude = (((double) lng / 1E5));
    
            decodedCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
    
            decodedPolylineString = [NSString stringWithFormat:@"%f%f", latitude, longitude];
            ;
            NSLog(@"%@",decodedPolylineString);
    
            [decodedPolylinePath addCoordinate:decodedCoordinate];
        }
    
    
        return decodedPolylinePath;
    }
    
    0 讨论(0)
  • 2020-12-07 21:57

    Same in Javascript

        function decodePolyline(encoded) {
            if (!encoded) {
                return [];
            }
            var poly = [];
            var index = 0, len = encoded.length;
            var lat = 0, lng = 0;
    
            while (index < len) {
                var b, shift = 0, result = 0;
    
                do {
                    b = encoded.charCodeAt(index++) - 63;
                    result = result | ((b & 0x1f) << shift);
                    shift += 5;
                } while (b >= 0x20);
    
                var dlat = (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
                lat += dlat;
    
                shift = 0;
                result = 0;
    
                do {
                    b = encoded.charCodeAt(index++) - 63;
                    result = result | ((b & 0x1f) << shift);
                    shift += 5;
                } while (b >= 0x20);
    
                var dlng = (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
                lng += dlng;
    
                var p = {
                    latitude: lat / 1e5,
                    longitude: lng / 1e5,
                };
                poly.push(p);
            }
            return poly;
        }
    
    0 讨论(0)
  • 2020-12-07 22:00

    For those who need this now, there's an open-source library with a lot of useful stuff regarding the Google Maps Android API, including decoding and encoding of polylines.

    Check it out at Android Maps Utils and Android Maps Util Github. For decoding and encoding use:

    PolyUtil.decode(String encodedPath);
    PolyUtil.encode(List<LatLng> path);
    
    0 讨论(0)
提交回复
热议问题