2015-04-11 22 views
13

Voglio realizzare un touchListener su una polilinea visualizzato con Google Maps V2 Android API.rilevamento Touch polyline in Google Maps Android API v2

livello dello zoom: CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(lat_Lng, 5);

ho provato il seguente codice polilinea touch:

boolean onpoly = false; 
      for (Polyline polyline : mPolylines) { 
       for (LatLng polyCoords : polyline.getPoints()) { 
        float[] results = new float[1]; 

        Location.distanceBetween(points.latitude, points.longitude, polyCoords.latitude, polyCoords.longitude, results); 

        if (results[0] < 100) { 
         onpoly = true; 

         Marker mark = map.addMarker(new MarkerOptions().position(points).title("AddEvent") 

         .snippet("" + addressaddexpense).icon(BitmapDescriptorFactory.fromResource(R.drawable.addicon))); 

         UtilsClass.dropPinEffect(mark); 
        }// end if.. 
       } // end for loop 
      }// end for loop 

      if (onpoly == true) { 
       Toast.makeText(getActivity(), "Poly line detected", Toast.LENGTH_SHORT).show(); 
      }// end if 

Ha funzionato, ma non perfettamente. non rileverà l'evento tocco a meno che non esegua l'ingrandimento, a volte costringendomi a toccare la mappa più di 5 volte prima di eseguire lo zoom per ottenere il rilevamento.

Ho quindi modificato la summenzionata condizione if da if (results[0] < 100) a if (results[0] < 150 * (22 - map.getCameraPosition().zoom)) e la funzionalità è migliorata ma non funziona ancora tutto il tempo.

Nota: Voglio rilevare il tocco polilinea a qualsiasi livello di zoom.

+0

Ho le seguenti domande per fornire una risposta migliore di quella che ho attualmente fatto: 1. dove si trova il codice pubblicato? è in un 'onMapClickListener'? 'DispatchTouchEvent'? qualcos'altro? 2. quando si dice di voler rilevare un tocco polilinea; intendi un clic sulla linea o ti piacerebbe anche abilitare lo scorrimento o altri gesti tattili? –

+0

ho usato questo codice all'interno diMapLongClickListener .. – harikrishnan

+0

OK, quindi prova suMapClickListener (il clic lungo è in realtà progettato per fare ciò che hai descritto, che deve essere chiamato solo dopo un lungo clic sull'oggetto senza movimento) e guarda anche il mio answer :) –

risposta

0

Fino a quando le domande nei miei commenti trovano risposta ho pensato che proverò a farli ridondante suggerendo l'utilizzo di una libreria di terze parti; android-maps-utils

per fare quello che penso si potrebbe essere cercando di fare semplicemente integrare la biblioteca e utilizzare la seguente riga: PolyUtil.isLocationOnPath(point, polyline.getPoints(), isGeodesic, tolerance);

Per ulteriori informazioni si può anche guardare in questo thread che sembra applicabile.

Goodluck.

+0

ho provato questo royiby. ma, ho avuto errore in questi due parametri isGeodesic, tolleranza. dove posso ottenere i valori per quei parametri .. me per cercare in google e ottenuto sopra quella linea .. – harikrishnan

+0

Questi 2 parametri riguardano le tue preferenze di rilevamento, quali valori hai provato? –

+0

non ho dato alcun valore .. puoi suggerire due valori. – harikrishnan

1

provare questo

final List<LatLng> latLngList; // Extract polyline coordinates and put them on this list 
    private GoogleMap map; 

for(int i = 0; i < latLngList.size(); i++){ 
       MarkerOptions mar = new MarkerOptions(); 
        mar.position(new LatLng(latLngList.get(i).latitude, latLngList.get(i).longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.trasparent_image)); //this image should be very small in size and transparent 
        map.addMarker(mar); 
      } 

      map.setOnMarkerClickListener(new OnMarkerClickListener() { 

       @Override 
       public boolean onMarkerClick(Marker arg0) { 
        for(int i = 0; i < latLngList.size(); i++){ 
        if(latLngList.get(i).latitude == arg0.getPosition().latitude && latLngList.get(i).longitude == arg0.getPosition().longitude){ 
         Toast.makeText(MainActivity.this, "PolyLineClick ", Toast.LENGTH_SHORT).show(); 
         break; 
        } 
       } 
        return false; 
       } 
      }); 
+0

Tutto ciò di cui hai bisogno è un'immagine trasparente e sostituiscila con i marcatori – Abhishek

+0

fammi controllare questo metodo – harikrishnan

+0

il tuo metodo è corretto..ma, già qui, le dimensioni dell'elenco di coordinate polilinee supereranno più di cinquanta mila (50k). inoltre, errore arraylist di memoria insufficiente è venuto..non è stato possibile memorizzare tutti i valori di polilinea in un elenco .. – harikrishnan

0

Credo che il tuo approccio è corretto. L'unica cosa che fallisce è il controllo della distanza. E questo perché os il tocco e il livello di zoom:

Sai che quando si tocca lo schermo, il punto dello schermo che viene passato alle applicazioni è il centro della superficie del dito, che è in contatto con lo schermo . Ciò significa che, anche se sembra, che il tuo dito è esattamente sopra lo PolyLine, può essere spostato con alcuni pixel ...

Ora è il momento per il livello di Zoom, e in base al suo valore attuale, la distanza tra il punto passato all'applicazione e il PolyLine, possono variare molto.

Di conseguenza, la clausola if non riesce e è necessario toccare più volte, fino a quando alcuni dei tuoi tocchi sono abbastanza vicini allo PolyLine. E naturalmente migliora con il livello di zoom più elevato.

È necessario includere il livello di zoom come si è fatto nel codice modificato, ma con alcuni extra:
Controllare il "delta" che consentirà di immettere if, ma sul livello di zoom massimo. Dovrebbe essere un piccolo valore. Quindi devi solo moltiplicarlo per il livello di zoom corrente e calcolare come cambia questo delta. Utilizza questo valore dipendente dallo zoom nel confronto if.
Per migliorarlo, puoi eseguire un calcolo più complesso e ottenere questo delta, a partire dalla distanza dei pixel. Diciamo, un tocco che a 50px o meno per il PolyLine sarà accettato. Calcola questa distanza in pixel in metri, sempre sul livello di zoom massimo e usala moltiplicata per lo zoom corrente ...
Per aumentarlo ancora di più, è possibile ottenere questa distanza pixel, in base alla risoluzione e alla densità dello schermo.

Qui, si possono trovare come calcolare pixel dello schermo di metri: https://stackoverflow.com/a/13635952/4776540

+0

grazie ... fammi controllare – harikrishnan

0

ho implementato una cosa simile nel seguente modo:

  1. Converti tutte le posizioni allo schermo le coordinate utilizzando map.getProjection().toScreenLocation()
  2. Utilizza la formula della distanza standard per determinare la distanza da punto a punto (o da punto a segmento, se vuoi rilevare anche i clic su segmenti di linea) e se questa distanza è inferiore a qualche soglia, viene rilevato il clic.

Il punto chiave qui è utilizzare la proiezione della mappa per ottenere le coordinate dello schermo. In questo modo la decisione dipende dalla reale distanza dei pixel sullo schermo e non dipende da un livello di zoom.

Problemi correlati