2010-12-09 10 views
6

Cuando uso MapController.setZoom (x) y, por ejemplo, el zoom del nivel 5 al 15, el zoom se realiza muy rápido y con frecuencia no se cargan las teselas del mapa del nuevo nivel.Suavizar el zoom en la vista de mapa

Esto no se ve tan bien para el usuario. ¿Alguna función de compilación de Maps para cambiar esto a un zoom más lento para que los mosaicos se puedan cargar, o al menos casi cargar, antes de que se alcance el nivel 15?

Saludos

P

+2

hay una gran ventaja de la velocidad que está animado: La cantidad de imágenes cargadas inútiles es reducido. Cuando se trabaja con la muestra @ 1ka y @Reuben, resultaría en una gran cantidad de llamadas de carga de mapa de bits en (posible) red 3G/UMTS que se descartarán 350ms más tarde. Eso es un desperdicio de ancho de banda y, a veces, dinero puro del usuario. También tenga en cuenta que incluso el mapa de Google en el navegador de la PC funciona de esta manera y todos están acostumbrados. Nadie espera que un mapa ya esté cargado mientras se cambia la ubicación mostrada. – WarrenFaith

Respuesta

0

No hay manera simple de hacer esto. Sin embargo, puedo ayudarte.

En primer lugar, esto es un regalo libre de una de mis clases de utilidad personales, Tween.java:

import android.os.Handler; 

public class Tween { 

    public static interface TweenCallback { 
     public void onTick(float time, long duration); 
     public void onFinished(); 
    } 

    long start; 
    long duration; 
    Handler handler; 
    TweenCallback callback; 

    public Tween(TweenCallback callback) {  
     handler = new Handler(); 
     this.callback = callback; 
    } 
    public void start(final int duration) { 
     start = android.os.SystemClock.uptimeMillis(); 
     this.duration = duration; 
     tickRunnable.run(); 
    } 
    public void stop() { 
     handler.removeCallbacks(tickRunnable); 
    } 
    Runnable tickRunnable= new Runnable() { 
     public void run() { 
      long now = android.os.SystemClock.uptimeMillis(); 
      float time = now - start; 
      boolean finished = (time >= duration); 
      if (finished) { 
       time = duration; 
      } 
      callback.onTick(time, duration); 
      if (!finished) { 
       handler.post(tickRunnable); 
      } 
      else { 
       callback.onFinished(); 
      } 
     } 
    }; 

    // 
    // Tweening functions. The 4 parameters are : 
    // 
    // t - time, ranges from 0 to d 
    // b - begin, i.e. the initial value for the quantity being changed over time 
    // c - change, the amount b will be changed by at the end 
    // d - duration, of the transition, normally in milliseconds. 
    // 
    // All were adapted from http://jstween.sourceforge.net/Tween.js 
    // 
    public static float strongEaseInOut(float t, float b, float c, float d) { 
     t/=d/2; 
     if (t < 1) return c/2*t*t*t*t*t + b; 
     return c/2*((t-=2)*t*t*t*t + 2) + b; 
    } 
    public static float regularEaseIn(float t, float b, float c, float d) { 
     return c*(t/=d)*t + b; 
    } 
    public static float strongEaseIn(float t, float b, float c, float d) { 
     return c*(t/=d)*t*t*t*t + b; 
    } 
} 

Lo que recomiendo que se hace es utilizar MapController.zoomToSpan() en conjunción con un Tween ... éstas son algunas completamente código no probado que debería funcionar, tal vez con un tweak o dos, solo pásalo al objetivo lat & lon span. :

public void slowZoom(int latE6spanTarget, int lonE6spanTarget) { 
    final float initialLatE6span = mapView.getLatitudeSpan(); 
    final float initialLonE6span = mapView.getLongitudeSpan(); 
    final float latSpanChange = (float)(latE6spanTarget - initialLatE6span); 
    final float lonSpanChange = (float)(lonE6spanTarget - initialLonE6span); 
    Tween tween = new Tween(new Tween.TweenCallback() { 
     public void onTick(float time, long duration) { 
      float latSpan = Tween.strongEaseIn(time, initialLatE6span, latSpanChange, duration); 
      float lonSpan = Tween.strongEaseIn(time, initialLonE6span, lonSpanChange, duration); 
      mapView.getController().zoomToSpan((int)latSpan, (int)lonSpan); 
     } 
     public void onFinished() { 
     } 
    }); 
    tween.start(5000); 
} 
+0

Gracias Reuben! Lo he intentado pero en cada tic (en la devolución de llamada en Tick() no actualiza la vista de mapa, lo que creo que este método haría mapView.getController(). ZoomToSpan ((int) latSpan, (int) lonSpan); Por ahora se ve en el teléfono como hace una pausa de 5 segundos y luego se acerca al último nivel. ¿Algunas ideas? –

+1

Oh infierno, apuesto a que zoomToSpan comienza su propia animación ... eso es muy irritante. Lo siento mucho. Si solo pudieras establecer un nivel de zoom de punto flotante al instante, funcionaría ... es extraño cuán débiles son las clases de Google Maps. –

8

Una manera más sencilla es tomar ventaja del método MapController.zoomIn() que proporciona una cierta animación simple para el zoom un nivel de paso.

Aquí hay algo de código:

// a Quick runnable to zoom in 
    int zoomLevel = mapView.getZoomLevel(); 
    int targetZoomLevel = 18; 

    long delay = 0; 
    while (zoomLevel++ < targetZoomLevel) { 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mapController.zoomIn(); 
      } 
     }, delay); 

     delay += 350; // Change this to whatever is good on the device 
    } 

Lo que hace es crear una secuencia de runnables retraso cada uno de los cuales llamar zoomIn 350 ms() después de la anterior.

Esto supone que tiene un controlador asociado a su hilo principal interfaz de usuario llamada 'manejador'

:-)

+0

También podría agregar un retraso mayor a medida que se acerca al nivel 18 para dar la sensación de desaceleración. –

+0

En cuanto al comentario de WarrenFaith sobre el ancho de banda, lo anterior no difiere del usuario al acercar y alejar manualmente usando los botones en la pantalla. Con un retraso de 350 obtengo un zoom continuo, pero no se muestra la imagen. Creo que MapView es lo suficientemente inteligente como para esperar hasta que toda la actividad se haya detenido antes de solicitar fichas. Pero IDK seguro. –

Cuestiones relacionadas