Rotation de MapView sur Android
j'écris une application Android dont l'une des caractéristiques est que la carte va tourner selon la boussole (c.-à-d. si le téléphone pointe vers l'est, la carte sera orientée de sorte que le côté est de la carte est au-dessus). Les réponses précédentes que j'ai trouvées suggéraient d'écrire la méthode onDraw() dans mapView, cependant, l'api a changé la méthode en finale pour qu'elle ne puisse pas être réécrite. En conséquence, j'ai essayé d'écraser le dispatchDraw()
méthode donc:
Remarque:
- compass est un booléen que si vrai, tourner la vue
- bearing est une variable float qui a les degrés que la vue doit tourner
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();
}
5 réponses
grâce aux réponses de pheelicks et Nikita Koksharov, j'arrive à activer/désactiver la rotation d'un mapview selon la boussole.
vous aurez D'abord besoin de la deux intérieure classe MapViewCompassDemo.java trouvé à: Android_SDK_ Outils\add-ons\addon-google_apis-google-#\samples\MapsDemo\src\com\exemple\android\api\view\
RotateView
SmoothCanvas
extraire la classe intérieure RotateView à RotateView.java et ajouter SmoothCanvas comme une classe intérieure de RotateView.java au lieu 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>
The 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
}
}
mise à Jour: Rotation de Google MapView avec Compass exemple de projet:https://www.dropbox.com/sh/c1encbc2lr63qd9/6C1C4hsrlT
Dans la doc:
protected void dispatchDraw (Canvas canvas)
appelé par draw pour dessiner les vues de l'enfant. Ceci peut être dépassé par les classes dérivées pour gagner le contrôle juste avant que ses enfants soient dessinés (mais après que son propre point de vue ait été dessiné).
donc l'annulation de dispatchDraw n'est pas bon puisque la vue de carte principale a déjà été dessinée
Une solution pourrait être d'ajouter la MapView comme un enfant d'un autre CustomView (une sous-classe de ViewGroup) et ensuite utiliser la méthode dispatchDraw de CustomView pour dessiner la rotation de MapView (maintenant un enfant). Donc, en xml, vous feriez quelque chose comme:
<?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>
Il devrait être quelque chose comme ceci:
@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();
}
}
regardez les exemples de MapsDemo dans ANDROID_SDK\add-ons\addon-google_apis-google_inc_-7\samples\MapsDemo
. Il a la démo de la carte de rotation.
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));
}