it-swarm.com.ru

Google Maps Android API v2

Google изменил API карты для Android и представил API V2. Предыдущие коды для рисования пути не работают с API V2.

Мне удалось нарисовать путь с помощью API V2. Я много искал решение, но не нашел ответа. Поэтому я делюсь своим ответом. 

82
Zeeshan Mirza

Прежде всего мы получим точки отправления и назначения, между которыми мы должны нарисовать маршрут. Затем мы передадим эти атрибуты функции ниже.

 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, который мы отправим, чтобы получить ответ API Direction. Затем мы проанализируем этот ответ. Класс парсера

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. Функция 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);
        }
    }
}

Надеюсь, это поможет.

171
Zeeshan Mirza

Не знаю, должен ли я поставить это как ответ или нет ...

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

проходя через какой-то другой вопрос по поводу SO, у меня было следующее решение

Я добавляю следующую функцию в классе Зеешана

 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

Edit: Вот часть кода из mainacctivity ..

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");
3
Zaffar Saffee

в приведенном ниже коде 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;
}

функция decode poly предназначена для декодирования точек (широта и долгота), предоставляемых Directions API, в закодированном виде.

0
Brinda Rathod