Намалюйте шлях між двома точками за допомогою Google Maps Android API v2


83

Google змінив свій API карт для Android та представив API V2. Попередні коди для шляху малювання не працюють з API V2.

Мені вдалося намалювати шлях за допомогою API V2. Я багато шукав рішення, але не знайшов жодної відповіді. Тож я ділюсь його відповіддю.


Привіт зеешан, чи зможу я отримати свої місця поблизу за допомогою Google Maps android API V2, або ми повинні використовувати лише API Google places ??? Будь-які ідеї
Фірназ

Відповіді:


171

Перш за все ми отримаємо вихідні та кінцеві пункти, між якими ми повинні прокласти маршрут. Тоді ми передамо ці атрибути функції нижче.

 public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.googleapis.com/maps/api/directions/json");
        urlString.append("?origin=");// from
        urlString.append(Double.toString(sourcelat));
        urlString.append(",");
        urlString.append(Double.toString( sourcelog));
        urlString.append("&destination=");// to
        urlString.append(Double.toString( destlat));
        urlString.append(",");
        urlString.append(Double.toString( destlog));
        urlString.append("&sensor=false&mode=driving&alternatives=true");
        urlString.append("&key=YOUR_API_KEY");
        return urlString.toString();
 }

Ця функція зробить URL-адресу, яку ми надішлемо для отримання відповіді Direction API. Тоді ми проаналізуємо цю відповідь. Клас синтаксичного аналізатора -

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";
    // constructor
    public JSONParser() {
    }
    public String getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            json = sb.toString();
            is.close();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }
        return json;

    }
}

Цей парсер поверне нам рядок. Ми будемо називати це так.

JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);

Тепер ми надішлемо цей рядок до нашої функції drawpath. Функція витяжки є

public void drawPath(String  result) {

    try {
            //Tranform the string into a json object
           final JSONObject json = new JSONObject(result);
           JSONArray routeArray = json.getJSONArray("routes");
           JSONObject routes = routeArray.getJSONObject(0);
           JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
           String encodedString = overviewPolylines.getString("points");
           List<LatLng> list = decodePoly(encodedString);
           Polyline line = mMap.addPolyline(new PolylineOptions()
                                    .addAll(list)
                                    .width(12)
                                    .color(Color.parseColor("#05b1fb"))//Google maps blue color
                                    .geodesic(true)
                    );
           /*
           for(int z = 0; z<list.size()-1;z++){
                LatLng src= list.get(z);
                LatLng dest= list.get(z+1);
                Polyline line = mMap.addPolyline(new PolylineOptions()
                .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude,   dest.longitude))
                .width(2)
                .color(Color.BLUE).geodesic(true));
            }
           */
    } 
    catch (JSONException e) {

    }
} 

Наведений вище код намалює шлях на mMap. Код decodePoly:

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

Оскільки виклик напрямку може зайняти час, тому ми зробимо все це в асинхронному завданні. Моє асинхронне завдання було

private class connectAsyncTask extends AsyncTask<Void, Void, String>{
    private ProgressDialog progressDialog;
    String url;
    connectAsyncTask(String urlPass){
        url = urlPass;
    }
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setMessage("Fetching route, Please wait...");
        progressDialog.setIndeterminate(true);
        progressDialog.show();
    }
    @Override
    protected String doInBackground(Void... params) {
        JSONParser jParser = new JSONParser();
        String json = jParser.getJSONFromUrl(url);
        return json;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);   
        progressDialog.hide();        
        if(result!=null){
            drawPath(result);
        }
    }
}

Сподіваюся, це допоможе.


Немає прямого способу видалити шлях. Ми повинні видалити його вручну.
Zeeshan Mirza

11
Я додав клас до свого сховища і модифікую його, щоб дозволити кілька точок і встановити позначки для вказівки. github.com/tato469/Android/tree/master/routes%20googleMaps%20v2
Ернандо Валле

1
Наведений вище код створює занадто багато коротких полилиний , які кілька разів робить карту лага .... У нас є кращий варіант, просто створити один рядок, замінивши наступний код в коді вищеPolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); for (int z = 0; z < list.size(); z++) { LatLng point = list.get(z); options.add(point); } line = myMap.addPolyline(options);
Мельбурн Lopes

3
Якщо ви отримали помилку Requests to this API must be over SSL, перейдіть httpнаhttps
AlvaroSantisteban

1
Мені довелося ввімкнути API Google Places для Android на консолі розробників Google і створити серверний ключ, і поставити його як keyпараметр у makeURLфункції, інакше я отримав This IP, site or mobile application is not authorized to use this API key. Крім того, змініть url на httpsзамість того, httpяк згадував AlvaroSantisteban.
Primož Kralj

3

Не знаю, чи варто це ставити як відповідь чи ні ...

Я використав рішення @ Zeeshan0026, щоб намалювати шлях ... і проблема полягала в тому, що якщо я намалюю шлях один раз, а потім спробую ще раз намалювати шлях, обидва два шляхи відображаються, і це продовжується ... шляхи, що відображаються навіть тоді, коли маркери були видалено ... в той час як, в ідеалі, старих шляхів не повинно бути там після того, як намальовано новий шлях / маркери видалено ..

перебираючи інше питання над SO, я мав таке рішення

Я додаю наступну функцію в клас Zeeshan

 public void clearRoute(){

         for(Polyline line1 : polylines)
         {
             line1.remove();
         }

         polylines.clear();

     }

у своїй діяльності на карті, перед тим як намалювати шлях, я зателефонував цій функції .. приклад використання відповідно до мого додатка

private Route rt;

rt.clearRoute();

            if (src == null) {
                Toast.makeText(getApplicationContext(), "Please select your Source", Toast.LENGTH_LONG).show();
            }else if (Destination == null) {
                Toast.makeText(getApplicationContext(), "Please select your Destination", Toast.LENGTH_LONG).show();
            }else if (src.equals(Destination)) {
                Toast.makeText(getApplicationContext(), "Source and Destinatin can not be the same..", Toast.LENGTH_LONG).show();
            }else{

                rt.drawRoute(mMap, MapsMainActivity.this, src,
                        Destination, false, "en");
            }

Ви можете використовувати rt.clearRoute();відповідно до ваших вимог .. Сподіваючись, що це заощадить кілька хвилин когось іншого та допоможе новачкові у вирішенні цього питання ..

Повний код класу

див. на github

Редагувати: ось частина коду від основної діяльності ..

case R.id.mkrbtn_set_dest:
                    Destination = selmarker.getPosition();
                    destmarker = selmarker;
                    desShape = createRouteCircle(Destination, false);

                    if (src == null) {
                        Toast.makeText(getApplicationContext(),
                                "Please select your Source first...",
                                Toast.LENGTH_LONG).show();
                    } else if (src.equals(Destination)) {
                        Toast.makeText(getApplicationContext(),
                                "Source and Destinatin can not be the same..",
                                Toast.LENGTH_LONG).show();
                    } else {

                        if (isNetworkAvailable()) {
                            rt.drawRoute(mMap, MapsMainActivity.this, src,
                                    Destination, false, "en");
                            src = null;
                            Destination = null;

                        } else {
                            Toast.makeText(
                                    getApplicationContext(),
                                    "Internet Connection seems to be OFFLINE...!",
                                    Toast.LENGTH_LONG).show();

                        }

                    }

                    break;

Редагуйте 2 відповідно до коментарів

використання:

//variables as data members
GoogleMap mMap;
private Route rt;
static LatLng src;
static LatLng Destination;
//MapsMainActivity is my activity
//false for interim stops for traffic, google
// en language for html description returned

rt.drawRoute(mMap, MapsMainActivity.this, src,
                            Destination, false, "en");

Привіт Заффаре, чи можна було б побачити ваш клас MapsMainActivity? Я новачок в Android і намагаюся зрозуміти цей код. Я не впевнений, як ви передаєте всі аргументи методу drawroute (). Дякую за будь-яку допомогу
KvnH

дякую Заффаре, але я все ще не бачу, де створено багато з цих змінних, тобто дестмаркер. А що в класі Destination? Я подивлюся і спробую ще раз.
KvnH

0

внизу коду midpointsList - це ArrayList шляхових точок

private String getMapsApiDirectionsUrl(GoogleMap googleMap, LatLng startLatLng, LatLng endLatLng, ArrayList<LatLng> midpointsList) {
    String origin = "origin=" + startLatLng.latitude + "," + startLatLng.longitude;

    String midpoints = "";
    for (int mid = 0; mid < midpointsList.size(); mid++) {
        midpoints += "|" + midpointsList.get(mid).latitude + "," + midpointsList.get(mid).longitude;
    }

    String waypoints = "waypoints=optimize:true" + midpoints + "|";

    String destination = "destination=" + endLatLng.latitude + "," + endLatLng.longitude;
    String key = "key=AIzaSyCV1sOa_7vASRBs6S3S6t1KofFvDhjohvI";

    String sensor = "sensor=false";
    String params = origin + "&" + waypoints + "&" + destination + "&" + sensor + "&" + key;
    String output = "json";
    String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + params;


    Log.e("url", url);
    parseDirectionApidata(url, googleMap);
    return url;
}

Потім скопіюйте та вставте цю URL-адресу у свій браузер для перевірки. І наведений нижче код - це синтаксичний аналіз URL-адреси

    private void parseDirectionApidata(String url, final GoogleMap googleMap) {

    final JSONObject jsonObject = new JSONObject();

    try {

        AppUtill.getJsonWithHTTPPost(ViewMapActivity.this, 1, new ServiceCallBack() {
            @Override
            public void serviceCallBack(int id, JSONObject jsonResult) throws JSONException {

                if (jsonResult != null) {

                    Log.e("jsonRes", jsonResult.toString());

                    String status = jsonResult.optString("status");

                    if (status.equalsIgnoreCase("ok")) {
                        drawPath(jsonResult, googleMap);
                    }

                } else {

                    Toast.makeText(ViewMapActivity.this, "Unable to parse Directions Data", Toast.LENGTH_LONG).show();
                }

            }
        }, url, jsonObject);

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

    }
}

А потім передайте результат методу drawPath

    public void drawPath(JSONObject jObject, GoogleMap googleMap) {

    List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String, String>>>();
    JSONArray jRoutes = null;
    JSONArray jLegs = null;
    JSONArray jSteps = null;
    List<LatLng> list = null;
    try {

        Toast.makeText(ViewMapActivity.this, "Drawing Path...", Toast.LENGTH_SHORT).show();
        jRoutes = jObject.getJSONArray("routes");

        /** Traversing all routes */
        for (int i = 0; i < jRoutes.length(); i++) {
            jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
            List path = new ArrayList<HashMap<String, String>>();

            /** Traversing all legs */
            for (int j = 0; j < jLegs.length(); j++) {
                jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");

                /** Traversing all steps */
                for (int k = 0; k < jSteps.length(); k++) {
                    String polyline = "";
                    polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points");
                    list = decodePoly(polyline);
                }
                Log.e("list", list.toString());
                routes.add(path);
                Log.e("routes", routes.toString());
                if (list != null) {
                    Polyline line = googleMap.addPolyline(new PolylineOptions()
                            .addAll(list)
                            .width(12)
                            .color(Color.parseColor("#FF0000"))//Google maps blue color #05b1fb
                            .geodesic(true)
                    );
                }
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

}

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

функція декодування полі полягає в декодуванні точок (широких та довгих), наданих Directions API, у закодованому вигляді


0

Спробуйте наведене нижче рішення, щоб намалювати шлях з анімацією, а також отримати час і відстань між двома точками.

DirectionHelper.java

public class DirectionHelper {

    public List<List<HashMap<String, String>>> parse(JSONObject jObject) {

        List<List<HashMap<String, String>>> routes = new ArrayList<>();
        JSONArray jRoutes;
        JSONArray jLegs;
        JSONArray jSteps;
        JSONObject jDistance = null;
        JSONObject jDuration = null;

        try {

            jRoutes = jObject.getJSONArray("routes");

            /** Traversing all routes */
            for (int i = 0; i < jRoutes.length(); i++) {
                jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
                List path = new ArrayList<>();

                /** Traversing all legs */
                for (int j = 0; j < jLegs.length(); j++) {

                    /** Getting distance from the json data */
                    jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
                    HashMap<String, String> hmDistance = new HashMap<String, String>();
                    hmDistance.put("distance", jDistance.getString("text"));

                    /** Getting duration from the json data */
                    jDuration = ((JSONObject) jLegs.get(j)).getJSONObject("duration");
                    HashMap<String, String> hmDuration = new HashMap<String, String>();
                    hmDuration.put("duration", jDuration.getString("text"));

                    /** Adding distance object to the path */
                    path.add(hmDistance);

                    /** Adding duration object to the path */
                    path.add(hmDuration);

                    jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");

                    /** Traversing all 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);

                        /** Traversing all points */
                        for (int l = 0; l < list.size(); l++) {
                            HashMap<String, String> hm = new HashMap<>();
                            hm.put("lat", Double.toString((list.get(l)).latitude));
                            hm.put("lng", Double.toString((list.get(l)).longitude));
                            path.add(hm);
                        }
                    }
                    routes.add(path);
                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
        }


        return routes;
    }

    //Method to decode polyline points
    private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<>();
        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;
    }
}

GetPathFromLocation.java

public class GetPathFromLocation extends AsyncTask<String, Void, List<List<HashMap<String, String>>>> {

    private Context context;
    private String TAG = "GetPathFromLocation";
    private LatLng source, destination;
    private ArrayList<LatLng> wayPoint;
    private GoogleMap mMap;
    private boolean animatePath, repeatDrawingPath;
    private DirectionPointListener resultCallback;
    private ProgressDialog progressDialog;

    //https://www.mytrendin.com/draw-route-two-locations-google-maps-android/
    //https://www.androidtutorialpoint.com/intermediate/google-maps-draw-path-two-points-using-google-directions-google-map-android-api-v2/

    public GetPathFromLocation(Context context, LatLng source, LatLng destination, ArrayList<LatLng> wayPoint, GoogleMap mMap, boolean animatePath, boolean repeatDrawingPath, DirectionPointListener resultCallback) {
        this.context = context;
        this.source = source;
        this.destination = destination;
        this.wayPoint = wayPoint;
        this.mMap = mMap;
        this.animatePath = animatePath;
        this.repeatDrawingPath = repeatDrawingPath;
        this.resultCallback = resultCallback;
    }

    synchronized public String getUrl(LatLng source, LatLng dest, ArrayList<LatLng> wayPoint) {

        String url = "https://maps.googleapis.com/maps/api/directions/json?sensor=false&mode=driving&origin="
                + source.latitude + "," + source.longitude + "&destination=" + dest.latitude + "," + dest.longitude;
        for (int centerPoint = 0; centerPoint < wayPoint.size(); centerPoint++) {
            if (centerPoint == 0) {
                url = url + "&waypoints=optimize:true|" + wayPoint.get(centerPoint).latitude + "," + wayPoint.get(centerPoint).longitude;
            } else {
                url = url + "|" + wayPoint.get(centerPoint).latitude + "," + wayPoint.get(centerPoint).longitude;
            }
        }
        url = url + "&key=" + context.getResources().getString(R.string.google_api_key);

        return url;
    }

    public int getRandomColor() {
        Random rnd = new Random();
        return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(context);
        progressDialog.setMessage("Please wait...");
        progressDialog.setIndeterminate(false);
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected List<List<HashMap<String, String>>> doInBackground(String... url) {

        String data;

        try {
            InputStream inputStream = null;
            HttpURLConnection connection = null;
            try {
                URL directionUrl = new URL(getUrl(source, destination, wayPoint));
                connection = (HttpURLConnection) directionUrl.openConnection();
                connection.connect();
                inputStream = connection.getInputStream();

                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuffer stringBuffer = new StringBuffer();

                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuffer.append(line);
                }

                data = stringBuffer.toString();
                bufferedReader.close();

            } catch (Exception e) {
                Log.e(TAG, "Exception : " + e.toString());
                return null;
            } finally {
                inputStream.close();
                connection.disconnect();
            }
            Log.e(TAG, "Background Task data : " + data);

            //Second AsyncTask

            JSONObject jsonObject;
            List<List<HashMap<String, String>>> routes = null;

            try {
                jsonObject = new JSONObject(data);
                // Starts parsing data
                DirectionHelper helper = new DirectionHelper();
                routes = helper.parse(jsonObject);
                Log.e(TAG, "Executing Routes : "/*, routes.toString()*/);

                return routes;

            } catch (Exception e) {
                Log.e(TAG, "Exception in Executing Routes : " + e.toString());
                return null;
            }

        } catch (Exception e) {
            Log.e(TAG, "Background Task Exception : " + e.toString());
            return null;
        }
    }

    @Override
    protected void onPostExecute(List<List<HashMap<String, String>>> result) {
        super.onPostExecute(result);

        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }

        ArrayList<LatLng> points;
        PolylineOptions lineOptions = null;
        String distance = "";
        String duration = "";

        // Traversing through all the routes
        for (int i = 0; i < result.size(); i++) {
            points = new ArrayList<>();
            lineOptions = new PolylineOptions();

            // Fetching i-th route
            List<HashMap<String, String>> path = result.get(i);

            // Fetching all the points in i-th route
            for (int j = 0; j < path.size(); j++) {
                HashMap<String, String> point = path.get(j);

                if (j == 0) {    // Get distance from the list
                    distance = (String) point.get("distance");
                    continue;
                } else if (j == 1) { // Get duration from the list
                    duration = (String) point.get("duration");
                    continue;
                }

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

                points.add(position);
            }

            // Adding all the points in the route to LineOptions
            lineOptions.addAll(points);
            lineOptions.width(8);
            lineOptions.color(Color.RED);
            //lineOptions.color(getRandomColor());

            if (animatePath) {
                final ArrayList<LatLng> finalPoints = points;
                ((AppCompatActivity) context).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        PolylineOptions polylineOptions;
                        final Polyline greyPolyLine, blackPolyline;
                        final ValueAnimator polylineAnimator;

                        LatLngBounds.Builder builder = new LatLngBounds.Builder();
                        for (LatLng latLng : finalPoints) {
                            builder.include(latLng);
                        }
                        polylineOptions = new PolylineOptions();
                        polylineOptions.color(Color.RED);
                        polylineOptions.width(8);
                        polylineOptions.startCap(new SquareCap());
                        polylineOptions.endCap(new SquareCap());
                        polylineOptions.jointType(ROUND);
                        polylineOptions.addAll(finalPoints);
                        greyPolyLine = mMap.addPolyline(polylineOptions);

                        polylineOptions = new PolylineOptions();
                        polylineOptions.width(8);
                        polylineOptions.color(Color.WHITE);
                        polylineOptions.startCap(new SquareCap());
                        polylineOptions.endCap(new SquareCap());
                        polylineOptions.zIndex(5f);
                        polylineOptions.jointType(ROUND);

                        blackPolyline = mMap.addPolyline(polylineOptions);
                        polylineAnimator = ValueAnimator.ofInt(0, 100);
                        polylineAnimator.setDuration(5000);
                        polylineAnimator.setInterpolator(new LinearInterpolator());
                        polylineAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                                List<LatLng> points = greyPolyLine.getPoints();
                                int percentValue = (int) valueAnimator.getAnimatedValue();
                                int size = points.size();
                                int newPoints = (int) (size * (percentValue / 100.0f));
                                List<LatLng> p = points.subList(0, newPoints);
                                blackPolyline.setPoints(p);
                            }
                        });

                        polylineAnimator.addListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {

                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {
                                if (repeatDrawingPath) {
                                    List<LatLng> greyLatLng = greyPolyLine.getPoints();
                                    if (greyLatLng != null) {
                                        greyLatLng.clear();

                                    }
                                    polylineAnimator.start();
                                }
                            }

                            @Override
                            public void onAnimationCancel(Animator animation) {
                                polylineAnimator.cancel();
                            }

                            @Override
                            public void onAnimationRepeat(Animator animation) {
                            }
                        });
                        polylineAnimator.start();
                    }
                });
            }

            Log.e(TAG, "PolylineOptions Decoded");
        }

        // Drawing polyline in the Google Map for the i-th route
        if (resultCallback != null && lineOptions != null)
            resultCallback.onPath(lineOptions, distance, duration);
    }
}

DirectionPointListener

public interface DirectionPointListener {
    public void onPath(PolylineOptions polyLine,String distance,String duration);
}

Тепер намалюйте шлях, використовуючи наведений нижче код у вашій діяльності

private GoogleMap mMap;
private ArrayList<LatLng> wayPoint = new ArrayList<>();
private SupportMapFragment mapFragment;

mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

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

        mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                LatLngBounds.Builder builder = new LatLngBounds.Builder();

                /*Add Source Marker*/
                MarkerOptions markerOptions = new MarkerOptions();
                markerOptions.position(source);
                markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                mMap.addMarker(markerOptions);
                builder.include(source);

                /*Add Destination Marker*/
                markerOptions = new MarkerOptions();
                markerOptions.position(destination);
                markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                mMap.addMarker(markerOptions);
                builder.include(destination);

                LatLngBounds bounds = builder.build();

                int width = mapFragment.getView().getMeasuredWidth();
                int height = mapFragment.getView().getMeasuredHeight();
                int padding = (int) (width * 0.15); // offset from edges of the map 10% of screen

                CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);

                mMap.animateCamera(cu);

                new GetPathFromLocation(context, source, destination, wayPoint, mMap, true, false, new DirectionPointListener() {
                    @Override
                    public void onPath(PolylineOptions polyLine, String distance, String duration) {
                        mMap.addPolyline(polyLine);
                        Log.e(TAG, "onPath :: Distance :: " + distance + " Duration :: " + duration);

                        binding.txtDistance.setText(String.format(" %s", distance));
                        binding.txtDuration.setText(String.format(" %s", duration));
                    }
                }).execute();
            }
        });
    }

Вихід

введіть тут опис зображення

Сподіваюся, це може вам допомогти!

Дякую.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.