2013-01-14 12 views
19

Se apri l'app Google Maps, nella parte superiore destra dello schermo è presente un pulsante che puoi premere per centrare la mappa sulla posizione corrente. L'icona del pulsante cambia. Se si preme di nuovo lo stesso pulsante, la mappa viene ruotata automaticamente in base alla direzione della bussola. In altre parole, la mappa diventa egocentrica (al contrario di AKA allocentric, sempre in alto a nord).Le mappe Android ruotano automaticamente

Google ha recentemente lanciato le mappe API V2 per Android e sicuramente mi piace più di quella vecchia. Per impostazione predefinita, le mappe Android V2 includeranno il pulsante "centro sul luogo". Tuttavia, premendolo più di una volta non si abilita la rotazione automatica; cerca semplicemente di centrare nuovamente la mappa sulla tua posizione.

Qualcuno sa come posso ruotare automaticamente la mappa utilizzando le mappe API v2 proprio come fa l'app di google maps? Devo implementare questa funzionalità da solo o è nell'API e non lo vedo? Apprezzo tutto l'aiuto.

+0

che era disponibile ... io non sapevo nemmeno di quella funzione, grazie. Per me, funziona benissimo (v7) –

+0

lui, voglio fare la stessa cosa, si prega di condividere la vostra soluzione, se avete fatto questo. –

risposta

22

Ok ecco come penso che dovrebbe essere fatto un anno dopo. Per favore correggimi se trovi qualche problema.

La maggior parte del codice seguente si occupa di una discrepanza tra i sistemi di coordinate. Sto usando un sensore vettoriale di rotazione. Dai documenti: Y is tangential to the ground at the device's current location and points towards magnetic north. Il rilevamento nelle mappe di google, d'altra parte, sembra indicare il nord vero. this page shows how the conversion is done

1) ottenere la declinazione corrente dalla posizione GPS corrente

@Override 
public void onLocationChanged(Location location) { 
    GeomagneticField field = new GeomagneticField(
      (float)location.getLatitude(), 
      (float)location.getLongitude(), 
      (float)location.getAltitude(), 
      System.currentTimeMillis() 
     ); 

    // getDeclination returns degrees 
    mDeclination = field.getDeclination(); 
} 

2) Calcolare il cuscinetto dalla declinazione e nord magnetico

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
     SensorManager.getRotationMatrixFromVector(
       mRotationMatrix , event.values); 
     float[] orientation = new float[3]; 
     SensorManager.getOrientation(mRotationMatrix, orientation); 
     float bearing = Math.toDegrees(orientation[0]) + mDeclination; 
     updateCamera(bearing); 
    } 
} 

3) aggiornamento mappe

private void updateCamera(float bearing) { 
    CameraPosition oldPos = mMap.getCameraPosition(); 

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing).build(); 
      mMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos)); 
} 
+1

mRotationMatrix? – Anthone

+1

'galleggiante privato [] mRotationMatrix = new float [16];' ' getRotationMatrixFromVector' popolerà' mRotationMatrix' in base ai valori in caso. –

+0

Questo crea effetto di sfarfallamento sulla carta, come posso limitare la rotazione – Bytecode

1

È possibile registrando la tua applicazione con Sensor Listener per Orientamento e allineamento dell'angolo rispetto al nord vero su onSensorChanged e aggiornamento della telecamera di conseguenza. L'angolo può essere utilizzato per il rilevamento. Il seguente codice può essere utilizzato:

Instead of using Sensor.TYPE_ORIENTATION try using getOrinetation api. Sensor.TYPE_ORIENTATION 
has been deprecated. 

@Override 
protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 
    if (sensorManager != null) 
     sensorManager.registerListener(this, 
       sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
       SensorManager.SENSOR_DELAY_GAME); 
} 

public void onSensorChanged(SensorEvent event) { 

    float degree = Math.round(event.values[0]); 

    Log.d(TAG, "Degree ---------- " + degree); 

    updateCamera(degree); 

} 

private void updateCamera(float bearing) { 
    CameraPosition oldPos = googleMap.getCameraPosition(); 

    CameraPosition pos = CameraPosition.builder(oldPos).bearing(bearing) 
      .build(); 

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(pos)); 

} 
5

ho implementato con successo aleph_null soluzione e qui mi aggiungerà alcuni dettagli che non sono menzionati nella soluzione accettata:

Per la soluzione di cui sopra per lavorare è necessario implementare interfaccia android.hardware.SensorEventListener.

È necessario anche registrarsi per il SensorEventListener nei vostri metodi onResume e OnPause come segue:

@Override 
    protected void onResume() { 
    super.onResume(); 
    mSensorManager.registerListener(this, 
      mRotVectSensor, 
      SensorManager.SENSOR_STATUS_ACCURACY_LOW); 
    } 

@Override 
protected void onPause() { 
    // unregister listener 
    super.onPause(); 
    mSensorManager.unregisterListener(this); 
} 

Nota a "@Bytecode": per evitare lo sfarfallio, utilizzare il valore basso per il periodo di campionamento, qualcosa come SensorManager .SENSOR_STATUS_ACCURACY_LOW.

Ho notato anche che il sensore invia più dati di quanti il ​​dispositivo sia in grado di gestire e, di conseguenza, la fotocamera della mappa inizia a muoversi in un modo strano!

Per controllare la quantità di dati gestiti da onSensorChanged, suggerisco la seguente implementazione:

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 
     SensorManager.getRotationMatrixFromVector(
       mRotationMatrix, event.values); 
     float[] orientation = new float[3]; 
     SensorManager.getOrientation(mRotationMatrix, orientation); 
     if (Math.abs(Math.toDegrees(orientation[0]) - angle) > 0.8) { 
      float bearing = (float) Math.toDegrees(orientation[0]) + mDeclination; 
      updateCamera(bearing); 
     } 
     angle = Math.toDegrees(orientation[0]); 
    } 
} 
+0

'mRotVectSensor'? – theapache64

+0

dove è definito l'angolo – suulisin