Android Maps v2 rotate mapView with compass
OK, i figured it out myself. first you need to calculate the bearing from the compass.
then the Maps api-2 camera can be rotated.
public void updateCamera(float bearing) {
CameraPosition currentPlace = new CameraPosition.Builder()
.target(new LatLng(centerLatitude, centerLongitude))
.bearing(bearing).tilt(65.5f).zoom(18f).build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(currentPlace));
}
set SensorListener
in your code and call this method in onSensorChanged
event. i have added a tilt value so the map will rotate in 3D.
Android Rotating MapView
Keep in mind that it's not an ideal approach, because the text on the map is a static image and will rotate along with the map tiles (at some point it will be upside down).
Here's an example of how to put the MapView
into your own Layout
widget and rotate it. I've done it with the OpenStreetMaps, but it should be quite the same for Google Maps.
First create the "rotating" Layout
widget
package com.eli.util;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;
public class RotatingLinearLayout extends LinearLayout {
private final int mDiagonal;
private float mBearing;
public RotatingLinearLayout(final Context pContext, final AttributeSet pAttrs) {
super(pContext, pAttrs);
final DisplayMetrics dm = pContext.getResources().getDisplayMetrics();
mDiagonal = (int) Math.hypot(dm.widthPixels, dm.heightPixels);
}
public void setBearing(final float pBearing) {
mBearing = pBearing;
}
@Override
protected void dispatchDraw(final Canvas pCanvas) {
pCanvas.rotate(-mBearing, getWidth() >> 1, getHeight() >> 1);
super.dispatchDraw(pCanvas);
}
@Override
protected void onMeasure(final int pWidthMeasureSpec,
final int pHeightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(pWidthMeasureSpec);
final int heightMode = MeasureSpec.getMode(pHeightMeasureSpec);
super.onMeasure(MeasureSpec.makeMeasureSpec(mDiagonal, widthMode), MeasureSpec.makeMeasureSpec(mDiagonal, heightMode));
}
}
Surround by it your MapView
in the layout.xml
<com.eli.util.RotatingLinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/rotating_layout">
<org.osmdroid.views.MapView
android:id="@+id/map_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"/>
</com.eli.util.RotatingLinearLayout>
Now, every time you receive a geo fix, update the bearing of the rotating layout and it should turn.
How to rotate MapView in MapBox GL?
The default MapView
will use a SurfaceView, this kind of transformation is only supported using TextureView as rendering surface. To enable this, you either set this up with xml attrs as mapbox_renderTextureMode=true
or by using MapboxMapOptions#textureMode(true)
programatically.
Rotate MapView in osmdroid by route
I've found a solution. This method calculates me a correct degree to rotate my map. I cut my route to straight lines. When current location is near next line, I call this method
public double rotateToNextCheckPoint() {
int lineId = OfferPreference.getInstance().getCurrentLineId();
if (rotates != null && lineId >= 0 && road.mRouteHigh.size() > 0) {
if (lineId < (rotates.size() - 1)) {
GeoPoint nextPoint = rotates.get(lineId).getLast();
GeoPoint currPoint = rotates.get(lineId).getFirst();
if (nextPoint == null || currPoint == null) {
return 0;
}
double lat1 = Math.toRadians(currPoint.getLatitude());
double lon1 = Math.toRadians(currPoint.getLongitude());
double lat2 = Math.toRadians(nextPoint.getLatitude());
double lon2 = Math.toRadians(nextPoint.getLongitude());
double cos1 = Math.cos(lat1);
double cos2 = Math.cos(lat2);
double sin1 = Math.sin(lat1);
double sin2 = Math.sin(lat2);
double delta = lon2 - lon1;
double deltaCos = Math.cos(delta);
double deltaSin = Math.sin(delta);
double x = (cos1 * sin2) - (sin1 * cos2 * deltaCos);
double y = deltaSin * cos2;
double z = Math.toDegrees(Math.atan((-y / x)));
if (x < 0) {
z += 180;
}
double z2 = (z + 180) % 360 - 180;
z2 = -Math.toRadians(z2);
double angleRad = z2 - (Math.PI * 2 * Math.floor(z2 / (2 * Math.PI)));
double angle = Math.toDegrees(angleRad);
rotationGestureOverlay.onRotate(-(float) angle, false);
return angle;
}
}
return 0;
}
How to rotate mapview to moving direction
You can get bearing from the location, that you received from the LocationManager
and set it to the CameraPosition
, like this:
Location location = googleMap.getMyLocation();
if (location != null) {
CameraPosition position = CameraPosition.builder()
.bearing(location.getBearing())
.target(new LatLng(location.getLatitude(), location.getLongitude()))
.zoom(googleMap.getCameraPosition().zoom)
.tilt(googleMap.getCameraPosition().tilt)
.build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(position));
}
Then your camera will rotate to your direction;
Related Topics
When Exactly Are Onsaveinstancestate() and Onrestoreinstancestate() Called
How to Listen for Preference Changes Within a Preferencefragment
How to Draw a Circle with Animation in Android with Circle Size Based on a Value
How to Get Ndk-Gdb Working on Android
Java.Lang.Illegalstateexception: Fragment Not Attached to Activity
Fcm (Firebase Cloud Messaging) Push Notification with ASP.NET
How to Start an Android Application from the Command Line
How to Capture and Save an Image Using Custom Camera in Android
Android - Swipe to Delete Recyclerview
Android: How to Convert Whole Imageview to Bitmap
Missing Styles. Is the Correct Theme Chosen for This Layout
Using JSON File in Android App Resources
Position of Dialogfragment in Android
Padding Between Actionbar's Home Icon and Title
Access Pictures from Pictures App in My Android App
Android - Apply Selectableitembackground in Xml with Support V7
Android Retrofit - Onprogressupdate for Showing Progress Notification