Autore Topic: Problemi nel disegnare un percorso attraverso vari Markers  (Letto 555 volte)

Offline Elmvor

  • Utente normale
  • ***
  • Post: 166
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Ubuntu 14.04, Windows 8.1
Problemi nel disegnare un percorso attraverso vari Markers
« il: 24 Aprile 2014, 22:19:27 CEST »
0
Premetto che ciò che ho scritto come titolo nel thread è stato da me già precedentemente implementato e risolto. Ora ho effettuato delle modifiche strutturali al codice ed ottengo un comportamento non corretto. Mi spiego meglio.

Si possono inserire dei Markers sulla GoogleMap tramite tocco, e poi scegliere di disegnare il percorso attraverso questi Markers (a piedi, in bici, automobile).
Quindi ho questa sequenza:

1) Riempio una lista di Markers man mano che li inserisco sulla mappa.
2) Scorro la lista di Markers e per ogni coppia faccio il calcolo del percorso tramite un AsyncTask che fa una richiesta HTTP alle Google Directions API.
3) Per ogni responso HTTP elaboro la risposta in formato JSON ed ottengo la lista di LatLng parziale.
4) Al termine della lista di Markers disegno effettivamente il percorso.

Se inserisco solo due Markers il percorso viene disegnato senza problemi. Se ne inserisco di più ottengo un comportamento strano. Quel che accade è che viene saltato il primo Markers ed il percorso viene disegnato solo attraverso tutti gli altri, ed in più viene disegnato un segmento tra gli ultimi due. Questo strano comportamento proprio non me lo so spiegare. La cosa curiosa è che facendo vari tentativi può capitare che il percorso viene disegnato interamente e correttamente.

Posto il codice relativo:

Codice: [Seleziona]
public class MultipleTracksDrawer extends AbstractDrawer {

    private static final String TAG_LOG = MultipleTracksAsyncTask.class.getName();

    private boolean flag = false;

    void draw() {

        for(int i = 0; i < markers.size() - 1; i++) {

            Marker firstMarker = markers.get(i);
            Marker secondMarker = markers.get(i + 1);
            //Estraggo latitudine e longitudine
            LatLng firstLatLng = new LatLng(firstMarker.getPosition().latitude, firstMarker.getPosition().longitude);
            LatLng secondLatLng = new LatLng(secondMarker.getPosition().latitude, secondMarker.getPosition().longitude);

            //Creo l'URL
            URL = Utilities.getInstance().makeURL(firstLatLng.latitude, firstLatLng.longitude,
                    secondLatLng.latitude, secondLatLng.longitude, travelMode);

            //Se sono arrivato alla fine imposto un flag, così da disegnare
            //il percorso una volta sola
            if(i == markers.size() - 2) {
                flag = true;
            }

            MultipleTracksAsyncTask multipleTracksAsyncTask = new MultipleTracksAsyncTask();
            multipleTracksAsyncTask.execute();
        }
    }

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

        private ProgressDialog mDialog;

        protected void onPreExecute() {
            mDialog = ProgressDialog.show(context, "", "Loading...", true);
        }

        protected void onPostExecute(String result) {
            if(mDialog != null) {
                if(mDialog.isShowing()) {
                    mDialog.dismiss();
                }
            }

            if(result != null) {
                parseJSON(result);
                if(flag) {
                    drawPath();
                }
            } else{
                Toast.makeText(context, "The path is not available", Toast.LENGTH_SHORT).show();
            }
        }

        public String doInBackground(Void... param) {
            //Istanzio il JSONRequest
            JSONRequest jParser = new JSONRequest();
            //Ottengo la stringa JSON
            String json = jParser.getJSONFromUrl(URL,connectionTimeout,dataTimeout);
            //Ritorno la stringa per l'onPostExecute
            return json;
        }
    }

    private void parseJSON(String result) {
        try {
            //Ottengo l'oggetto JSON
            final JSONObject json = new JSONObject(result);
            //Otteniamo l'array "routes" dall'oggetto json
            JSONArray routeArray = json.getJSONArray("routes");
            //Prendo il primo (ed unico) risultato
            JSONObject routes = routeArray.getJSONObject(0);
            //Ottengo l'array legs per la lunghezza e tempo di percorrenza
            JSONArray legsArray = routes.getJSONArray("legs");
            //Estraggo l'oggetto contenuto in legsArray
            JSONObject legsObject = legsArray.getJSONObject(0);
            //Estraggo lunghezza e tempo di percorrenza
            JSONObject distance = legsObject.getJSONObject("distance");
            JSONObject duration = legsObject.getJSONObject("duration");
            //Ottengo un oggetto che possiede un array di punti codificati che rappresentano
            //il percorso approssimato
            JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
            //Ottengo la stringa dei punti codificati
            String encodedString = overviewPolylines.getString("points");
            //Decodifico la stringa per ottenere una lista di LatLng
            model.getMarkersTrack().addAll(Utilities.getInstance().decodePoly(encodedString));

            mTrackDistance += distance.getInt("value");
            mTrackDuration += duration.getInt("value");
        }
        catch (JSONException e) {
            e.printStackTrace();
            Toast.makeText(context, "The path is not available", Toast.LENGTH_SHORT).show();
        }
    }

    private void drawPath() {

        for(int i = 0; i < model.getMarkersTrack().size() - 1; i++) {
            LatLng src = model.getMarkersTrack().get(i);
            LatLng dest = model.getMarkersTrack().get(i + 1);
            PolylineOptions polylineOptions = new PolylineOptions()
                    .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
                    .width(5)
                    .color(Color.BLUE).geodesic(true);
            Polyline polyline = googleMap.addPolyline(polylineOptions);
            //Salvo
le polylines nel caso voglia ridisegnare un altro tracciato
            model.getTrackPolylines().add(polyline);
        }
    }
}

Spero che mi possiate essere d'aiuto.

Post unito: 25 Aprile 2014, 15:07:08 CEST
Ho risolto anche se non so il motivo preciso. Praticamente l'URL della richiesta ora lo costruisco direttamente dentro il metodo draw() della classe invece di utilizzare la variabile della superclasse. Poi lo passo all'AsyncTask come parametro del costruttore.
« Ultima modifica: 25 Aprile 2014, 15:07:08 CEST da Elmvor, Reason: Merged DoublePost »