package io.github.vibrouter.utils;

import com.google.android.gms.maps.model.LatLng;

import java.util.ArrayList;
import java.util.List;

public class DirectionApiUtil {
    public static List<LatLng> decodePolyline(String encoded) {
        List<LatLng> poly = new ArrayList<>();
        int index = 0;
        int lat = 0;
        int lng = 0;

        while (index < encoded.length()) {
            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;
    }
}

@@ -223,24 +223,81 @@
  encoded) %7B%0A
+        StringBuffer buffer = new StringBuffer(encoded);%0A
         List
@@ -309,16 +309,20 @@
 ng%3E poly
+line
  = new A
@@ -335,24 +335,25 @@
 st%3C%3E();%0A
+%0A
         
 int inde
@@ -348,21 +348,42 @@
     
-int index =
+LatLng previous = new LatLng(0,
  0
+)
 ;%0A  
@@ -392,385 +392,603 @@
     
-int lat = 0;%0A        int lng = 0;%0A%0A        while (index %3C encoded.length()) %7B%0A            int b, shift = 0, result = 0;%0A            do %7B%0A                b = encoded.charAt(index++) - 63;%0A                result %7C= (b & 0x1f) %3C%3C shift;%0A                shift += 5;%0A            %7D while (b %3E= 0x20);%0A%0A            int dlat = ((result & 1) != 0 ? ~(result %3E%3E 1) : (result %3E%3E 1
+while (0 %3C buffer.length()) %7B%0A            // Diff from previous point is encoded.%0A            LatLng diff = decodeLatLng(buffer);%0A            LatLng location = new LatLng(diff.latitude + previous.latitude,%0A                    diff.longitude + previous.longitude);%0A            polyline.add(location);%0A            previous = location;%0A        %7D%0A%0A        return polyline;%0A    %7D%0A%0A    private static LatLng decodeLatLng(StringBuffer buffer) %7B%0A        int lat = decodeValue(buffer);%0A        int lng = decodeValue(buffer);%0A        return new LatLng((((double) lat / 1E5)), (((double) lng / 1E5)
 ));%0A    
     
@@ -987,41 +987,100 @@
     
+%7D%0A%0A
     
-    lat += dlat;%0A%0A           
+private static int decodeValue(StringBuffer buffer) %7B%0A        int binary;%0A        int
  shi
@@ -1087,35 +1087,35 @@
 ft = 0;%0A        
-   
+int
  result = 0;%0A   
@@ -1119,20 +1119,16 @@
         
-  
-  
 do %7B%0A   
@@ -1140,31 +1140,31 @@
     
-    b = encoded
+binary = buffer
 .charAt(
 inde
@@ -1163,15 +1163,9 @@
 rAt(
-index++
+0
 ) - 
@@ -1168,24 +1168,65 @@
 ) - 63;%0A    
+        buffer = buffer.deleteCharAt(0);%0A
             
@@ -1237,16 +1237,21 @@
 lt %7C= (b
+inary
  & 0x1f)
@@ -1273,20 +1273,16 @@
         
-    
 shift +=
@@ -1285,20 +1285,16 @@
 t += 5;%0A
-    
         
@@ -1303,16 +1303,21 @@
 while (b
+inary
  %3E= 0x20
@@ -1319,25 +1319,24 @@
  0x20);%0A
-%0A
         
     int 
@@ -1331,22 +1331,14 @@
     
-    int dlng =
+return
  ((r
@@ -1392,174 +1392,8 @@
 ));%0A
-            lng += dlng;%0A%0A            LatLng p = new LatLng((((double) lat / 1E5)), (((double) lng / 1E5)));%0A            poly.add(p);%0A        %7D%0A%0A        return poly;%0A
     

Clean polyline decode logic