How to Draw a Route, Along an Existing Road, Between Two Points

How do I draw a route, along an existing road, between two points?

Indeed, you can draw precise route in Google Maps Android API using results provided by Directions API web service. If you read the documentation for Directions API you will see that response contains information about route legs and steps. Each step has a field polyline that is described in the documentation as

polyline contains a single points object that holds an encoded polyline representation of the step. This polyline is an approximate (smoothed) path of the step.

So, the main idea to solve your issue is to get response from Directions API, loop through route legs and steps, for each step get encoded polyline and decode it to the list of coordinates. Once done you will have a list of all coordinates that compound the route, not only begin and end point of each step.

For simplicity I recommend using the Java client library for Google Maps Web services:

https://github.com/googlemaps/google-maps-services-java

Using this library you can avoid implementing your own async tasks and decoding function for polylines. Read the documentation to figure out how to add the client library in your project.

In Gradle it should be something similar to

compile 'com.google.maps:google-maps-services:(insert latest version)'
compile 'org.slf4j:slf4j-nop:1.7.25'

I have created a simple example to demonstrate how it works. Have a look at my comments in the code

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;
private String TAG = "so47492459";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

LatLng barcelona = new LatLng(41.385064,2.173403);
mMap.addMarker(new MarkerOptions().position(barcelona).title("Marker in Barcelona"));

LatLng madrid = new LatLng(40.416775,-3.70379);
mMap.addMarker(new MarkerOptions().position(madrid).title("Marker in Madrid"));

LatLng zaragoza = new LatLng(41.648823,-0.889085);

//Define list to get all latlng for the route
List<LatLng> path = new ArrayList();

//Execute Directions API request
GeoApiContext context = new GeoApiContext.Builder()
.apiKey("YOUR_API_KEY")
.build();
DirectionsApiRequest req = DirectionsApi.getDirections(context, "41.385064,2.173403", "40.416775,-3.70379");
try {
DirectionsResult res = req.await();

//Loop through legs and steps to get encoded polylines of each step
if (res.routes != null && res.routes.length > 0) {
DirectionsRoute route = res.routes[0];

if (route.legs !=null) {
for(int i=0; i<route.legs.length; i++) {
DirectionsLeg leg = route.legs[i];
if (leg.steps != null) {
for (int j=0; j<leg.steps.length;j++){
DirectionsStep step = leg.steps[j];
if (step.steps != null && step.steps.length >0) {
for (int k=0; k<step.steps.length;k++){
DirectionsStep step1 = step.steps[k];
EncodedPolyline points1 = step1.polyline;
if (points1 != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords1 = points1.decodePath();
for (com.google.maps.model.LatLng coord1 : coords1) {
path.add(new LatLng(coord1.lat, coord1.lng));
}
}
}
} else {
EncodedPolyline points = step.polyline;
if (points != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords = points.decodePath();
for (com.google.maps.model.LatLng coord : coords) {
path.add(new LatLng(coord.lat, coord.lng));
}
}
}
}
}
}
}
}
} catch(Exception ex) {
Log.e(TAG, ex.getLocalizedMessage());
}

//Draw the polyline
if (path.size() > 0) {
PolylineOptions opts = new PolylineOptions().addAll(path).color(Color.BLUE).width(5);
mMap.addPolyline(opts);
}

mMap.getUiSettings().setZoomControlsEnabled(true);

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(zaragoza, 6));
}
}

Please note that for web service you have to create a separate API key, the API key with Android app restriction won't work with web service.

The result of my example is shown in screenshot

enter image description here

You can also download a complete sample project from

https://github.com/xomena-so/so47492459

Don't forget replace the API key with yours.

I hope this helps!

how to draw path between 2 points on google map

you can use the latest google api

http://developer.android.com/google/play-services/maps.html

thre are lot of links available for this. take a look on

Drawing a line/path on Google Maps

How to Draw Route in Google Maps API V2 from my location

Android: How to draw route directions google maps API V2 from current location to destination

Android Google Maps draw a path between two points

Path is sequence of point . One of the solution is to make HTTP request to Google maps API specifying your two locations as parameters and get back JSON describing the points required to make the path between the two points. Require code to do that are listed below :

  1. Get direction URL require to call Google Maps API
private String  getMapsApiDirectionsUrl(LatLng origin,LatLng dest) {
// Origin of route
String str_origin = "origin="+origin.latitude+","+origin.longitude;

// Destination of route
String str_dest = "destination="+dest.latitude+","+dest.longitude;

// Sensor enabled
String sensor = "sensor=false";

// Building the parameters to the web service
String parameters = str_origin+"&"+str_dest+"&"+sensor;

// Output format
String output = "json";

// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;

return url;

}

  1. Do the URL call in background

    private class ReadTask extends AsyncTask<String, Void , String> {

    @Override
    protected String doInBackground(String... url) {
    // TODO Auto-generated method stub
    String data = "";
    try {
    MapHttpConnection http = new MapHttpConnection();
    data = http.readUr(url[0]);

    } catch (Exception e) {
    // TODO: handle exception
    Log.d("Background Task", e.toString());
    }
    return data;
    }

    @Override
    protected void onPostExecute(String result) {
    super.onPostExecute(result);
    new ParserTask().execute(result);
    }

    }
  public class MapHttpConnection {
public String readUr(String mapsApiDirectionsUrl) throws IOException{
String data = "";
InputStream istream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(mapsApiDirectionsUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
istream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(istream));
StringBuffer sb = new StringBuffer();
String line ="";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();

}
catch (Exception e) {
Log.d("Exception while reading url", e.toString());
} finally {
istream.close();
urlConnection.disconnect();
}
return data;

}
}

  1. Create Parser class to parse the data from JSON to List of pointes

    public class PathJSONParser {

    public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
    List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>();
    JSONArray jRoutes = null;
    JSONArray jLegs = null;
    JSONArray jSteps = null;
    try {
    jRoutes = jObject.getJSONArray("routes");
    for (int i=0 ; i < jRoutes.length() ; i ++) {
    jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
    List<HashMap<String, String>> path = new ArrayList<HashMap<String,String>>();
    for(int j = 0 ; j < jLegs.length() ; j++) {
    jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
    for(int k = 0 ; k < jSteps.length() ; k ++) {
    String polyline = "";
    polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points");
    List<LatLng> list = decodePoly(polyline);
    for(int l = 0 ; l < list.size() ; l ++){
    HashMap<String, String> hm = new HashMap<String, String>();
    hm.put("lat",
    Double.toString(((LatLng) list.get(l)).latitude));
    hm.put("lng",
    Double.toString(((LatLng) list.get(l)).longitude));
    path.add(hm);
    }
    }
    routes.add(path);
    }

    }

    } catch (Exception e) {
    e.printStackTrace();
    }
    return routes;

    }

    private List<LatLng> decodePoly(String encoded) {
    List<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 p = new LatLng((((double) lat / 1E5)),
    (((double) lng / 1E5)));
    poly.add(p);
    }
    return poly;
    }}
  2. Do the parse using another Thread to expand performance

private class ParserTask extends AsyncTask<String,Integer, List<List<HashMap<String , String >>>> {
@Override
protected List<List<HashMap<String, String>>> doInBackground(
String... jsonData) {
// TODO Auto-generated method stub
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
PathJSONParser parser = new PathJSONParser();
routes = parser.parse(jObject);

} catch (Exception e) {
e.printStackTrace();
}
return routes;
}

@Override
protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
ArrayList<LatLng> points = null;
PolylineOptions polyLineOptions = null;

// traversing through routes
for (int i = 0; i < routes.size(); i++) {
points = new ArrayList<LatLng>();
polyLineOptions = new PolylineOptions();
List<HashMap<String, String>> path = routes.get(i);

for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);

double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);

points.add(position);
}

polyLineOptions.addAll(points);
polyLineOptions.width(4);
polyLineOptions.color(Color.BLUE);
}

googleMap.addPolyline(polyLineOptions);

}}

  1. When you want to get the path of two point
 String url = getMapsApiDirectionsUrl(latlngOne, latlngTwo);                    
ReadTask downloadTask = new ReadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);

To calculate distance between points

float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongB.longitude,
latLongB.latitude, latLongB.longitude,
results);

the results will be in meters

how to draw a route between two markers in google maps

Quite a few mistakes. First is the geolocation. Your second location is wrong as the longitude can only be from +180 to -180 so -181 doesn't exist in the earth! Secondly, as MrUpsidedown mentioned in the comment, you are calling a function within a function. Correct the geolocation first and then your function calls, that should fix the problems you're having.

How to draw a path between two locations in google maps

First you have to create a Polyline object to specify the points, then you can set the Polyline object adding the Polyline options:

PolylineOptions polylineOptions = new PolylineOptions()
.add(new LatLng(37.35, -122.0)); // Point A.
.add(new LatLng(38.35, -123.0)); // Point B.

Polyline polyline = mMap.addPolyline(polylineOptions);

To alter the shape of the polyline after it has been added, you can call Polyline.setPoints() and provide a new list of points for the polyline.

How to display a path between two points in android google maps activity?

Here is the way to draw a path.

here is the link for the library - https://github.com/ar-android/DrawRouteMaps

Add that library into your Android project.

Apply the following code inside onMapReady Method

Android Code:

    @Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;

//Pass the origin coordinates(latitude,longitude)
LatLng origin = new LatLng(-7.788969, 110.338382);

//Pass the destination coordinates(latitude,longitude)
LatLng destination = new LatLng(-7.781200, 110.349709);

DrawRouteMaps.getInstance(this)
.draw(origin, destination, mMap);
DrawMarker.getInstance(this).draw(mMap, origin, R.drawable.marker_a, "Origin Location");
DrawMarker.getInstance(this).draw(mMap, destination, R.drawable.marker_b, "Destination Location");

LatLngBounds bounds = new LatLngBounds.Builder()
.include(origin)
.include(destination).build();
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getSize(displaySize);
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, displaySize.x, 250, 30));
}

You can also change the route color by applying this code inside colors.xml :

   <color name="colorRouteLine">YOUR COLOUR CODE</color>

issue in Draw route between two point using polyline in google map

Step is route instruction. You must parse overview_polyline object and get the encoded polyline string. then decode the string using android-maps-utils library:

List<LatLng> decodedPoints = PolyUtil.decode(polylineString);
PolylineOptions options = new PolylineOptions();
options.width(3);
options.color(Color.RED);
options.addAll(decodedPoints);

map.addPolyline(options);


Related Topics



Leave a reply



Submit