Reputation: 4391
In my Android Project, I'm trying to use PolyUtil.decode
to draw a polyline on google map using a response from google maps API.
Here is the code I've used for this :
public void gettingDerictions(double sourceLat, double sourceLong, double destLat, double destLong) {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + sourceLat + "," + sourceLong + "&destination=" + destLat + "," + destLong + "&key=****************************";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
Log.e("The response", response);
List<LatLng> route = PolyUtil.decode(response);
System.out.println(route);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("The response", "it didn't work");
}
});
queue.add(stringRequest);
}
I'm getting this error:
07-31 22:04:13.486 21530-21530/com.innoventiq.arkbeh E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.innoventiq.arkbeh, PID: 21530
java.lang.StringIndexOutOfBoundsException: length=10684; index=10684
at java.lang.String.charAt(Native Method)
at com.google.maps.android.PolyUtil.decode(PolyUtil.java:464)
at com.innoventiq.arkbeh.MapsActivity$6.onResponse(MapsActivity.java:260)
at com.innoventiq.arkbeh.MapsActivity$6.onResponse(MapsActivity.java:255)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7406)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
UPDATE
Here is the value of response
.
{
"geocoded_waypoints" : [
{
"geocoder_status" : "OK",
"place_id" : "Ek82IFJpY2ggSG9tZSwgQWwgQWdhbXkgQWwgQmFocmksIFFlc20gQWQgRGVraGlsYWgsIEFsZXhhbmRyaWEgR292ZXJub3JhdGUsIEVneXB0IhoSGAoUChIJv3T_1uiU9RQR7X1tYzsaZ8QQBg",
"types" : [ "street_address" ]
},
{
"geocoder_status" : "OK",
"place_id" : "ChIJ83j9iddBWBQR3SDSTdvOCbk",
"types" : [ "airport", "establishment", "point_of_interest" ]
}
],
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 31.1095921,
"lng" : 31.2352784
},
"southwest" : {
"lat" : 30.0439783,
"lng" : 29.7347456
}
},
"copyrights" : "Map data ©2019 ORION-ME",
"legs" : [
{
"distance" : {
"text" : "206 km",
"value" : 206160
},
"duration" : {
"text" : "2 hours 29 mins",
"value" : 8967
},
"end_address" : "Nasser, Madinaty, محافظة القاهرة 11566, Egypt",
"end_location" : {
"lat" : 30.0445393,
"lng" : 31.2352658
},
"start_address" : "6 Rich Home, Al Agamy Al Bahri, Qesm Ad Dekhilah, Alexandria Governorate, Egypt",
"start_location" : {
"lat" : 31.1092252,
"lng" : 29.7598111
},
"steps" : [
{
"distance" : {
"text" : "57 m",
"value" : 57
},
"duration" : {
"text" : "1 min",
"value" : 15
},
"end_location" : {
"lat" : 31.1089022,
"lng" : 29.7602755
},
"html_instructions" : "Head \u003cb\u003esoutheast\u003c/b\u003e toward \u003cb\u003eRich Home\u003c/b\u003e",
"polyline" : {
"points" : "u_{|DymstDLU`@q@PU"
},
"start_location" : {
"lat" : 31.1092252,
"lng" : 29.7598111
},
"travel_mode" : "DRIVING"
},
{
"distance" : {
"text" : "0.1 km",
"value" : 106
},
"duration" : {
"text" : "1 min",
"value" : 41
},
"end_location" : {
"lat" : 31.1095921,
"lng" : 29.7610398
},
"html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eRich Home\u003c/b\u003e",
"maneuver" : "turn-left",
"polyline" : {
"points" : "s}z|DwpstDIKu@cAiAgA"
},
"start_location" : {
"lat" : 31.1089022,
"lng" : 29.7602755
},
"travel_mode" : "DRIVING"
},
{
"distance" : {
"text" : "1.6 km",
"value" : 1553
},
"duration" : {
"text" : "8 mins",
"value" : 485
},
"end_location" : {
"lat" : 31.0988067,
"lng" : 29.7712707
},
Upvotes: 0
Views: 587
Reputation: 3562
EDIT:
I just realized there is an easier way to fix this. If you are getting your response in json then you should use JsonObjectRequest
instead of String request, it will give you properly encoded Json that you can parse to String.
OLD ANSWER:.
This must have been caused by Escape Characters during encoding/decoding since you are using string.
Just remove unescape characters and it should work:
response = StringEscapeUtils.unescapeJava(polyLine);
There is an implementation of StringEscapeUtils in Apache commons-text, you can use it from here:
Upvotes: 1
Reputation: 4658
Your response object is not well formatted before decoding. Try below implementation
public void gettingDerictions(double sourceLat, double sourceLong, double destLat, double destLong) {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + sourceLat + "," + sourceLong + "&destination=" + destLat + "," + destLong + "&key=****************************";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
// Log.e("The response", response);
// List<LatLng> route = PolyUtil.decode(response);
// System.out.println(route);
List<LatLng> movements = new ArrayList<LatLng>();
try{
JSONObject json = new JSONObject(response);
//Retrieve routes from response
JSONObject jsonRoute = json.getJSONArray("routes").getJSONObject(0);
//Retrieve legs from routes
JSONObject legs = jsonRoute.getJSONArray("legs").getJSONObject(0);
//Retrieve steps from legs
JSONArray steps = legs.getJSONArray("steps");
final int numSteps = steps.length();
JSONObject step;
//Retrieve points from steps
for (int i = 0; i < numSteps; i++) {
step = steps.getJSONObject(i);
String pontos = step.getJSONObject("polyline").getString("points");
movements.addAll(PolyUtil.decode(pontos));
}
}catch(Exception ex){
Log.d("DirectionErr",ex.getMessage());
}
//make use of movements object here
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("The response", "it didn't work");
}
});
queue.add(stringRequest);
}
Upvotes: 1