2

I want to draw the route between two Location. I used the retrofit library to call the API. I didn't get any response. I need the polyline in an ArrayList. How i do that? Need help to create the GsonAdapter also... Thank you..

zacharia
  • 1,083
  • 2
  • 10
  • 22

1 Answers1

26

In the activity `

     String base_url = "http://maps.googleapis.com/";

    Gson gson = new GsonBuilder()
            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .create();

    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint(base_url)
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    MyApiRequestInterface reqinterface = restAdapter.create(MyApiRequestInterface.class);

    reqinterface.getJson(fromPosition.latitude + "," + fromPosition.longitude, toPosition.latitude + "," + toPosition.longitude, new Callback<DirectionResults>() {


        @Override
        public void success(DirectionResults directionResults, Response response) {
            Log.i("zacharia", "inside on success" +directionResults.getRoutes().size());
            ArrayList<LatLng> routelist = new ArrayList<LatLng>();
            if(directionResults.getRoutes().size()>0){
                ArrayList<LatLng> decodelist;
                Route routeA = directionResults.getRoutes().get(0);
                Log.i("zacharia", "Legs length : "+routeA.getLegs().size());
                if(routeA.getLegs().size()>0){
                    List<Steps> steps= routeA.getLegs().get(0).getSteps();
                    Log.i("zacharia","Steps size :"+steps.size());
                    Steps step;
                    Location location;
                    String polyline;
                    for(int i=0 ; i<steps.size();i++){
                        step = steps.get(i);
                        location =step.getStart_location();
                        routelist.add(new LatLng(location.getLat(), location.getLng()));
                        Log.i("zacharia", "Start Location :" + location.getLat() + ", " + location.getLng());
                        polyline = step.getPolyline().getPoints();
                        decodelist = RouteDecode.decodePoly(polyline);
                        routelist.addAll(decodelist);
                        location =step.getEnd_location();
                        routelist.add(new LatLng(location.getLat() ,location.getLng()));
                        Log.i("zacharia","End Location :"+location.getLat() +", "+location.getLng());
                    }
                }
            }
            Log.i("zacharia","routelist size : "+routelist.size());
            if(routelist.size()>0){
                PolylineOptions rectLine = new PolylineOptions().width(10).color(
                        Color.RED);

                for (int i = 0; i < routelist.size(); i++) {
                    rectLine.add(routelist.get(i));
                }
                // Adding route on the map
                mMap.addPolyline(rectLine);
                markerOptions.position(toPosition);
                markerOptions.draggable(true);
                mMap.addMarker(markerOptions);
            }
        }

        @Override
        public void failure(RetrofitError retrofitError) {
            System.out.println("Failure, retrofitError" + retrofitError);
        }
    });`

Create retrofit interface

public interface MyApiRequestInterface {

@GET("/maps/api/directions/json")
public void getJson(@Query("origin") String origin,@Query("destination") String destination, Callback<DirectionResults> callback);}

Create Model classes

public class DirectionResults {
@SerializedName("routes")
private List<Route> routes;

public List<Route> getRoutes() {
    return routes;
}}
 public class Route {
@SerializedName("overview_polyline")
private OverviewPolyLine overviewPolyLine;

private List<Legs> legs;

public OverviewPolyLine getOverviewPolyLine() {
    return overviewPolyLine;
}

public List<Legs> getLegs() {
    return legs;
}
}

public class Legs {
private List<Steps> steps;

public List<Steps> getSteps() {
    return steps;
}
}

public class Steps {
private Location start_location;
private Location end_location;
private OverviewPolyLine polyline;

public Location getStart_location() {
    return start_location;
}

public Location getEnd_location() {
    return end_location;
}

public OverviewPolyLine getPolyline() {
    return polyline;
}
}

public class OverviewPolyLine {

@SerializedName("points")
public String points;

public String getPoints() {
    return points;
}
}

public class Location {
private double lat;
private double lng;

public double getLat() {
    return lat;
}

public double getLng() {
    return lng;
}
}

Create the Polyline Decode method

public class RouteDecode {

public static ArrayList<LatLng> decodePoly(String encoded) {
    ArrayList<LatLng> poly = new ArrayList<LatLng>();
    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 position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
        poly.add(position);
    }
    return poly;
}
}
zacharia
  • 1,083
  • 2
  • 10
  • 22
  • Currently the response from retrofit is of DirectionResult... I need it as ArrayList.... How can i achieve this by GsonConverter... – zacharia May 12 '15 at 07:19
  • 1
    You can now decode and encoded path using PolyUtils.decode() in the "Google Maps Android API utility library" available here https://github.com/googlemaps/android-maps-utils – speedynomads Sep 19 '16 at 14:00
  • Any idea how to get the total distance from this? – Sudip Feb 28 '18 at 13:06
  • @speedynomads yes but that will add more overhead burden to the code as well. This code snippet seems to be copied from the same library `PolyUtil.decode` method – Mirwise Khan Mar 27 '20 at 15:45
  • @MirwiseKhan what sort of overhead? If using maps in the project it makes sense to use and official utility library with well maintained code rather than copying code from the library and having to maintain it yourself. There's a good chance the utility library will include other commonly used functionality and will be optimised at compile time to only include what someone may be using in their project. – speedynomads Mar 27 '20 at 19:25
  • @speedynomads yeah but it contains heatmaps, marker clusters that might not be needed in every project. I'm saying from my experience that I just hit DEX limit if you are just gonna use a function why add other excessive utilites that aren't needed? – Mirwise Khan Mar 28 '20 at 05:59