android google-maps map rotation android-mapview

Rotar MapView en Android



google-maps rotation (5)

De los documentos:

void protegido dispatchDraw (lienzo de lona)

Llamado por sorteo para dibujar las vistas del niño. Esto puede ser anulado por clases derivadas para ganar control justo antes de que se dibujen sus hijos (pero después de que se haya dibujado su propia vista).

Así que sobrescribir dispatchDraw no es bueno ya que la vista del mapa principal ya ha sido dibujada

Una solución podría ser agregar MapView como un elemento secundario de otra CustomView (una subclase de ViewGroup) y luego usar el método dispatchDraw de CustomView para dibujar el MapView (ahora un elemento secundario) girado. Así que en xml harías algo como:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.example.CustomView android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="XXXXXXXXXXXXXXXXX"/> </com.example.CustomView> </RelativeLayout>

Estoy escribiendo una aplicación para Android donde una de las características es que el mapa girará de acuerdo con la brújula (es decir, si el teléfono apunta al este, el mapa estará orientado de modo que el lado este del mapa esté en la parte superior). Las respuestas anteriores que he encontrado sugeridas sobre la escritura del método onDraw () en mapView, sin embargo, la API cambió el método a final por lo que no se puede sobrescribir. Como resultado, he tratado de sobrescribir el método dispatchDraw() manera:

Nota:

-compass es un booleano que, si es verdadero, rota la vista

La orientación es una variable flotante que tiene los grados que la vista debe rotar.

protected void dispatchDraw(Canvas canvas) { canvas.save(); if (compass) { final float w = this.getWidth(); final float h = this.getHeight(); final float scaleFactor = (float)(Math.sqrt(h * h + w * w) / Math.min(w, h)); final float centerX = w / 2.0f; final float centerY = h / 2.0f; canvas.rotate(bearing, centerX, centerY); canvas.scale(scaleFactor, scaleFactor, centerX, centerY); } super.dispatchDraw(canvas); canvas.restore(); }


Debería ser algo como esto:

@Override protected void dispatchDraw(Canvas canvas) { canvas.save(Canvas.MATRIX_SAVE_FLAG); if (compass) { // rotate the canvas with the pivot on the center of the screen canvas.rotate(-azimuth, getWidth() * 0.5f, getHeight() * 0.5f); super.dispatchDraw(canvas); canvas.restore(); } }


Eche un vistazo a los ejemplos de ANDROID_SDK/add-ons/addon-google_apis-google_inc_-7/samples/MapsDemo en ANDROID_SDK/add-ons/addon-google_apis-google_inc_-7/samples/MapsDemo . Cuenta con mapa de rotación demo.


Gracias a las respuestas de pheelicks y Nikita Koksharov, logro activar / desactivar la rotación de una vista de mapa según la brújula.

Primero necesitará las dos clases internas de MapViewCompassDemo.java que se encuentran en: Android_SDK_ Tools / add-ons / addon-google_apis-google - # / samples / MapsDemo / src / com / example / android / apis / view /

RotateView SmoothCanvas

Extraiga la clase interna RotateView a RotateView.java y agregue SmoothCanvas como una clase interna de RotateView.java en lugar de MapViewCompassDemo.java

public class RotateView extends ViewGroup implements SensorListener { ... static final class SmoothCanvas extends Canvas { ... }//end SmoothCanvas }//end RotateView

maplayout.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map_layout_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/rotating_view" android:layout_width="match_parent" android:layout_height="match_parent" > <com.google.android.maps.MapView android:id="@+id/map_view" android:layout_width="match_parent" android:layout_height="match_parent" android:apiKey="##### YOUR MAP KEY HERE ######" android:clickable="true" /> </LinearLayout> <ToggleButton android:id="@+id/button_compass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:onClick="onClick" android:textOff="compass off" android:textOn="compass on" /> </RelativeLayout>

El MapActivity

/** * Example activity on how to display a google map view rotation with compass * To make it work you need to add: * - <uses-library android:name="com.google.android.maps" /> in the manifest.xml file * - Your Android Maps API Key from https://developers.google.com/android/maps-api- signup * - Set the project build target to "Google APIs" * - Extract/Add the two inner classes RotateView and SmoothCanvas of MapViewCompassDemo.java found at: * ../Android/Android SDK Tools/add-ons/addon-google_apis-google-#/samples/MapsDemo/src/com/example/android/apis/view/ * * @author hsigmond - touchboarder.com - * */ public class MapViewRotationWithCompass extends MapActivity { private MapView mMapView; private MyLocationOverlay mMyLocationOverlay = null; private boolean mModeCompass = false; private SensorManager mSensorManager; private LinearLayout mRotateViewContainer; private RotateView mRotateView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.maplayout); mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mRotateViewContainer = (LinearLayout) findViewById(R.id.rotating_view); mRotateView = new RotateView(this); // Sign Up for the Android Maps API at: // https://developers.google.com/android/maps-api-signup // Add the Android Maps API key to the MapView in the maplayout.xml file mMapView = (MapView) findViewById(R.id.map_view); mMyLocationOverlay = new MyLocationOverlay(this, mMapView); } @SuppressWarnings("deprecation") public void onClick(View v) { switch (v.getId()) { case R.id.button_compass: if (mMyLocationOverlay.isCompassEnabled()) { mSensorManager.unregisterListener(mRotateView); mRotateView.removeAllViews(); mRotateViewContainer.removeAllViews(); mRotateViewContainer.addView(mMapView); mMyLocationOverlay.disableCompass(); mModeCompass = false; } else { mRotateViewContainer.removeAllViews(); mRotateView.removeAllViews(); mRotateView.addView(mMapView); mRotateViewContainer.addView(mRotateView); mMapView.setClickable(true); mSensorManager.registerListener(mRotateView, SensorManager.SENSOR_ORIENTATION, SensorManager.SENSOR_DELAY_UI); mMyLocationOverlay.enableCompass(); mModeCompass = true; } break; } } @SuppressWarnings("deprecation") @Override public void onResume() { super.onResume(); if (mModeCompass) { mMyLocationOverlay.enableCompass(); mSensorManager.registerListener(mRotateView, SensorManager.SENSOR_ORIENTATION, SensorManager.SENSOR_DELAY_UI); } } @Override public void onPause() { super.onPause(); mMyLocationOverlay.disableCompass(); } @SuppressWarnings("deprecation") @Override protected void onStop() { mSensorManager.unregisterListener(mRotateView); super.onStop(); } @Override protected boolean isRouteDisplayed() { return (false);// Don''t display a route } }

Actualización: Rotación de Google MapView con Compass Ejemplo de proyecto: https://www.dropbox.com/sh/c1encbc2lr63qd9/6C1C4hsrlT


This answer applies to Google Maps api v2. It is possible by registering your application with Sensor Listener for Orientation and get the angle relative to true north inside onSensorChanged and update camera accordingly. Angle can be used for bearing. Following code can be used: 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)); }