package org.croudtrip.directions;
import com.google.maps.model.LatLng;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class PolylineEncoder {
/**
* Encodes a sequence of LatLngs into an encoded path string.
* The basic encoding algorithm is copied from {@link com.google.maps.internal.PolylineEncoding},
* but this method is slightly adapted to our own needs. You can pass a list of waypoint indices
* that will contain indices of the path list that start a new route leg. And this method will also
* compute corresponding string indices for that particular waypoints.
*/
public static Polyline encode(final List<LatLng> path, final List<Integer> waypointIndices ) {
long lastLat = 0;
long lastLng = 0;
final StringBuffer result = new StringBuffer();
List<Integer> stringIndices = new ArrayList<Integer>();
for (int i = 0; i < path.size(); ++i) {
LatLng point = path.get(i);
long lat = Math.round(point.lat * 1e5);
long lng = Math.round(point.lng * 1e5);
long dLat = lat - lastLat;
long dLng = lng - lastLng;
encode(dLat, result);
encode(dLng, result);
// if we match a leg starting point we add the current index (buffer length) to the
// string indices.
// first condition checks if not all waypointIndices have been processed yet
// second condition checks the waypoint index that should be converted to a string index next
if( stringIndices.size() < waypointIndices.size() && i == waypointIndices.get( stringIndices.size() )){
stringIndices.add( result.length() );
}
lastLat = lat;
lastLng = lng;
}
// also add the last waypoint
stringIndices.add( result.length() );
return new Polyline( result.toString(), stringIndices, path, waypointIndices );
}
private static void encode(long v, StringBuffer result) {
v = v < 0 ? ~(v << 1) : v << 1;
while (v >= 0x20) {
result.append(Character.toChars((int) ((0x20 | (v & 0x1f)) + 63)));
v >>= 5;
}
result.append(Character.toChars((int) (v + 63)));
}
}