Map View Draw Directions Using Google Directions API - Decoding Polylines

Map View draw directions using google Directions API - decoding polylines

I have a class which can decode them for you, add the class below then call in your code like this:

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

where points and levels are the data you've extracted from the JSON response. You can then go through the array of geopoints drawing a line between them to display your directions.

Hope this helps! Kenny


EDIT: It would seem that the google directions API no longer returns the zoom levels string as part of the JSON response, not to worry though, all we were using this for was to check the number of points, so we can simply put these into a list like:

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;
}

EDIT: OLD CODE

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;

}
}

How to decode the Google Directions API polylines field into lat long points in Objective-C for iPhone?

I hope it's not against the rules to link to my own blog post if it's relevant to the question, but I've solved this problem in the past. Stand-alone answer from linked post:

@implementation MKPolyline (MKPolyline_EncodedString)

+ (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;

NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;

float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;

do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);

float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;

shift = 0;
res = 0;

do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);

float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;

float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;

CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;

if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}

MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);

return polyline;
}

@end

Decoding polyline with new Google Maps API

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.

Google maps getdirections api - polyline

I think this is what you want: http://www.geekyblogger.com/2010/12/decoding-polylines-from-google-maps.html

Google map api drawn polyline with encoded points

See the geometry library documentation for decodePath

That will convert your encoded string into an array of google.maps.LatLng objects that can be used to create a Polyline

Working example

working code snippet:

function initialize() {
var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
var mapOptions = {
zoom: 13,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};

var bermudaTriangle;

var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);

// Construct the polygon
bermudaTriangle = new google.maps.Polygon({
paths: google.maps.geometry.encoding.decodePath("yzocFzynhVq}@n}@o}@nzD"),
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});

bermudaTriangle.setMap(map);
map.setCenter(bermudaTriangle.getPath().getAt(Math.round(bermudaTriangle.getPath().getLength() / 2)));
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
@media print {
html,
body {
height: auto;
}
#map_canvas {
height: 650px;
}
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>


Related Topics



Leave a reply



Submit