Как нарисовать интерактивную полилинию на маршруте google maps v2 android

у меня есть следующий код, который рисует ломаные линии для меня и работает нормально, но проблема в том, что он не рисует интерактивные ломаные линии, нарисованные линии пропускают некоторые пиксели!

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class testRoute extends FragmentActivity implements OnClickListener {

    private GoogleMap myMap;
    Polyline line;
    Context context;

    // Static LatLng
    LatLng startLatLng = new LatLng(30.707104, 76.690749);
    LatLng endLatLng = new LatLng(30.721419, 76.730017);

    public void onCreate(Bundle bd) {
        super.onCreate(bd);
        setContentView(R.layout.passanger_home_call);
        context = testRoute.this;

        // Temp GetTrails Button
        Button btntemp = (Button) findViewById(R.id.btn_pass_home_call_temp);
        btntemp.setOnClickListener(this);

        // GoogleMap myMap
        myMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map_pass_home_call)).getMap();
        myMap.setMyLocationEnabled(true);
        myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng));
        myMap.animateCamera(CameraUpdateFactory.zoomTo(12));

        // Now auto clicking the button
        btntemp.performClick();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
        case R.id.btn_pass_home_call_temp:
            String urlTopass = makeURL(startLatLng.latitude,
                    startLatLng.longitude, endLatLng.latitude,
                    endLatLng.longitude);
            new connectAsyncTask(urlTopass).execute();
            break;

        default:
            break;
        }

    }

    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(context);
            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);
            }
        }
    }

    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");
        return urlString.toString();
    }

    public class JSONParser {

        InputStream is = null;
        JSONObject jObj = null;
        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;

        }
    }

    public void drawPath(String result) {
        if (line != null) {
            myMap.clear();
        }
        myMap.addMarker(new MarkerOptions().position(endLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker)));
        myMap.addMarker(new MarkerOptions().position(startLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker)));
        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);

            for (int z = 0; z < list.size() - 1; z++) {
                LatLng src = list.get(z);
                LatLng dest = list.get(z + 1);
                line = myMap.addPolyline(new PolylineOptions()
                        .add(new LatLng(src.latitude, src.longitude),
                                new LatLng(dest.latitude, dest.longitude))
                        .width(5).color(Color.BLUE).geodesic(true));
            }

        } catch (Exception 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;
    }
}

Код работает нормально и рисует маршрут из одного места в другое, но не рисует интерактивные маршруты

Снимок экрана: - введите здесь описание изображения

Я думаю, что проблема связана с моим методом drawPath():

public void drawPath(String result) {
        if (line != null) {
            myMap.clear();
        }
        myMap.addMarker(new MarkerOptions().position(endLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker)));
        myMap.addMarker(new MarkerOptions().position(startLatLng).icon(
                BitmapDescriptorFactory.fromResource(R.drawable.redpin_marker)));
        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);

            for (int z = 0; z < list.size() - 1; z++) {
                LatLng src = list.get(z);
                LatLng dest = list.get(z + 1);
                line = myMap.addPolyline(new PolylineOptions()
                        .add(new LatLng(src.latitude, src.longitude),
                                new LatLng(dest.latitude, dest.longitude))
                        .width(5).color(Color.BLUE).geodesic(true));
            }

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

Игнорировать маркеры просто предложить мне добавить интерактивную полилинию?


person Tarsem Singh    schedule 02.07.2013    source источник
comment
Что вы имеете в виду, говоря об интерактивных полилиниях/маршрутах?   -  person MaciejGórski    schedule 03.07.2013
comment
@MaciejGórski спасибо за ответ! я имею в виду, что синяя линия, которая рисуется на карте, не интерактивна, в синей линии отсутствуют некоторые пиксели! Пожалуйста, посмотрите на снимок экрана!   -  person Tarsem Singh    schedule 03.07.2013
comment
@Tarsem Я нахожусь в процессе создания стандартного класса, чтобы люди могли легко реализовать GDirection/polyline, и я позаимствовал часть вашего кода. Пожалуйста, дайте мне знать, если вы не возражаете, если я его использую, я, конечно, отмечу вас. Если вам нужно, вы можете связаться со мной в Твиттере: beckahsheeler Спасибо!   -  person beckah    schedule 29.11.2015
comment
github.com/amalChandran/trail-android Вы можете использовать API проекций, чтобы нарисовать его как наложение.   -  person amalBit    schedule 25.04.2019


Ответы (5)


Вместо того, чтобы создавать слишком много коротких Polyline, просто создайте один, как здесь:

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

Я также не уверен, что вам следует использовать geodesic, когда ваши точки расположены так близко друг к другу.

person MaciejGórski    schedule 03.07.2013
comment
можно ли обнаружить клик по полилинии? - person Muhammad Babar; 19.10.2014
comment
я думаю, что ответы могут быть Yes или No. Никогда не стоит создавать новый вопрос. - person Muhammad Babar; 20.10.2014
comment
@MuhammadBabar Тогда мой ответ будет Yes. - person MaciejGórski; 22.10.2014
comment
Это только нарисует путь. если вы хотите, чтобы ваш путь придерживался дороги, используйте API направления Google. - person Fajar Khan; 03.08.2017
comment
@MaciejGórski Не могли бы вы помочь мне с анимацией полилинии, если я использую класс com.google.maps.model.LatLng, а не класс com.google.android.gms.maps.model.LatLng Вот опубликованный вопрос: < href="https://stackoverflow.com/q/48473889/7948825">stackoverflow.com/q/48473889/7948825. - person Rakshit Sorathiya; 27.01.2018
comment
вы можете уменьшить этот код, просто выполнив новый PolylineOptions() .addAll(list).width(5).color(Color.BLUE).geodesic(true); - person Gastón Saillén; 03.11.2018

Я создал пару руководств по картам, которые охватят то, что вам нужно.

Анимация карты описывает, как создавать полилинии на основе набора LatLng. Использование API Google на вашей карте: направления и места описывает, как использовать API направлений и анимировать маркер вдоль пути.

Взгляните на эти 2 руководства и проект Github, содержащий пример приложения.

Он содержит несколько советов, как сделать ваш код чище и эффективнее:

  • Использование Google HTTP Library для более эффективного доступа к API и простой обработки JSON.
  • Использование библиотеки google-map-utils для функций, связанных с картами (например, для декодирования полилиний).
  • Анимационные маркеры
person ddewaele    schedule 02.07.2013

Вы можете использовать этот метод для рисования полилинии на googleMap.

// Draw polyline on map
public void drawPolyLineOnMap(List<LatLng> list) {
    PolylineOptions polyOptions = new PolylineOptions();
    polyOptions.color(Color.RED);
    polyOptions.width(5);
    polyOptions.addAll(list);

    googleMap.clear();
    googleMap.addPolyline(polyOptions);

    LatLngBounds.Builder builder = new LatLngBounds.Builder();
    for (LatLng latLng : list) {
        builder.include(latLng);
    }

    final LatLngBounds bounds = builder.build();

    //BOUND_PADDING is an int to specify padding of bound.. try 100.
    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, BOUND_PADDING);
    googleMap.animateCamera(cu);
}

Вам нужно добавить эту строку в свой градиент, если вы этого не сделали.

compile 'com.google.android.gms:play-services-maps:8.4.0'
person Abhishek    schedule 29.04.2016

Вы должны использовать options.addAll(allPoints); вместо options.add(point);

person eggcaker    schedule 19.12.2013

Использование API-интерфейса проекции Google Maps для рисования полилиний в наложенном виде позволяет нам делать много вещей. Посмотрите этот репозиторий, в котором есть пример.

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

person amalBit    schedule 25.04.2019