Skip to content

Commit

Permalink
mapbox#1940 - Initial migration of Compass from TestApp to SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
bleege committed Aug 5, 2015
1 parent 54ae508 commit b5ed8e4
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
Expand All @@ -21,6 +27,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.ScaleGestureDetector;
import android.util.AttributeSet;
import android.view.InputDevice;
Expand Down Expand Up @@ -119,6 +126,20 @@ public class MapView extends FrameLayout implements LocationListener {
private ImageView mGpsMarker;
private Location mGpsLocation;

// Used for compass
private ImageView mCompassView;
private SensorManager mSensorManager;
private Sensor mSensorAccelerometer;
private Sensor mSensorMagneticField;
private CompassListener mCompassListener;
private float[] mValuesAccelerometer = new float[3];
private float[] mValuesMagneticField = new float[3];
private float[] mMatrixR = new float[9];
private float[] mMatrixI = new float[9];
private float[] mMatrixValues = new float[3];
private float mCompassBearing;
private boolean mCompassValid = false;

// Used to manage Event Listeners
private ArrayList<OnMapChangedListener> mOnMapChangedListener;

Expand Down Expand Up @@ -254,6 +275,23 @@ private void initialize(Context context, AttributeSet attrs) {
.setSmallestDisplacement(1)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

// Setup Compass
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorMagneticField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mCompassListener = new CompassListener();

mCompassView = new ImageView(mContext);
mCompassView.setImageDrawable(getResources().getDrawable(R.drawable.compass));
mCompassView.setContentDescription(getResources().getString(R.string.compassContentDescription));
LayoutParams lp = new FrameLayout.LayoutParams((int)(48 * mScreenDensity), (int)(48 * mScreenDensity));
lp.gravity = Gravity.TOP | Gravity.END;
int tenDp = (int)(10 * mScreenDensity);
lp.setMargins(tenDp, tenDp, tenDp, tenDp);
mCompassView.setLayoutParams(lp);
addView(mCompassView);
mCompassView.setOnClickListener(new CompassOnClickListener());

// Setup Support For Listener Tracking
// MapView's internal listener is setup in onCreate()
mOnMapChangedListener = new ArrayList<OnMapChangedListener>();
Expand Down Expand Up @@ -1446,18 +1484,75 @@ private void toggleGps(boolean enableGps) {
mLocationClient.connect();
updateLocation(LocationServices.FusedLocationApi.getLastLocation());
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationRequest, this);
mSensorManager.registerListener(mCompassListener, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(mCompassListener, mSensorMagneticField, SensorManager.SENSOR_DELAY_UI);
}
} else {
if (mIsGpsOn) {
mIsGpsOn = false;
LocationServices.FusedLocationApi.removeLocationUpdates(this);
mLocationClient.disconnect();
mGpsLocation = null;
mSensorManager.unregisterListener(mCompassListener, mSensorAccelerometer);
mSensorManager.unregisterListener(mCompassListener, mSensorMagneticField);
}
}
updateMap();
}

// This class handles sensor updates to calculate compass bearing
private class CompassListener implements SensorEventListener {

@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, mValuesAccelerometer, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, mValuesMagneticField, 0, 3);
break;
}

boolean valid = SensorManager.getRotationMatrix(mMatrixR, mMatrixI,
mValuesAccelerometer,
mValuesMagneticField);

if (valid) {
SensorManager.getOrientation(mMatrixR, mMatrixValues);
//mAzimuthRadians.putValue(mMatrixValues[0]);
//mAzimuth = Math.toDegrees(mAzimuthRadians.getAverage());

Location mGpsLocation = getMyLocation();
if (mGpsLocation != null) {
GeomagneticField geomagneticField = new GeomagneticField(
(float) mGpsLocation.getLatitude(),
(float) mGpsLocation.getLongitude(),
(float) mGpsLocation.getAltitude(),
System.currentTimeMillis());
mCompassBearing = (float) Math.toDegrees(mMatrixValues[0]) + geomagneticField.getDeclination();
mCompassValid = true;
}
}

updateMap();
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO: ignore unreliable stuff
}
}

// Called when someone presses the compass
private class CompassOnClickListener implements View.OnClickListener {

@Override
public void onClick(View view) {
resetNorth();
}
}

/**
* LOST's LocationListener Callback
* @param location New Location
Expand All @@ -1476,9 +1571,18 @@ private void updateLocation(Location location) {
}
}

// Rotates an ImageView - does not work if the ImageView has padding, use margins
private void rotateImageView(ImageView imageView, float angle) {
Matrix matrix = new Matrix();
matrix.setScale((float) imageView.getWidth() / (float) imageView.getDrawable().getIntrinsicWidth(), (float) imageView.getHeight() / (float) imageView.getDrawable().getIntrinsicHeight());
matrix.postRotate(angle, (float) imageView.getWidth() / 2.0f, (float) imageView.getHeight() / 2.0f);
imageView.setImageMatrix(matrix);
imageView.setScaleType(ImageView.ScaleType.MATRIX);
}

// Updates the UI to match the current map's position
private void updateMap() {
// rotateImageView(mCompassView, (float) mapView.getDirection());
rotateImageView(mCompassView, (float) getDirection());

if (isMyLocationEnabled() && mGpsLocation != null) {
if (mGpsMarker == null) {
Expand All @@ -1499,10 +1603,11 @@ private void updateMap() {
lp.leftMargin = (int) (screenLocation.x - iconSize / 2.0f);
lp.topMargin = getHeight() - (int) (screenLocation.y + iconSize / 2.0f);
mGpsMarker.setLayoutParams(lp);
// rotateImageView(mGpsMarker, 0.0f);
rotateImageView(mGpsMarker, 0.0f);
mGpsMarker.requestLayout();

/*
// Used For User Location Bearing UI
if (mGpsLocation.hasBearing() || mCompassValid) {
mGpsMarker.setImageResource(R.drawable.direction_arrow);
float iconSize = 54.0f * mScreenDensity;
Expand All @@ -1513,7 +1618,7 @@ private void updateMap() {
float bearing = mGpsLocation.hasBearing() ? mGpsLocation.getBearing() : mCompassBearing;
rotateImageView(mGpsMarker, bearing);
mGpsMarker.requestLayout();
} else {
}
*/
} else {
mGpsMarker.setVisibility(View.INVISIBLE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package com.mapbox.mapboxgl.testapp;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.hardware.GeomagneticField;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
Expand All @@ -23,7 +15,6 @@
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import com.crashlytics.android.Crashlytics;
Expand Down Expand Up @@ -60,7 +51,6 @@ public class MainActivity extends ActionBarActivity {
// Used for the UI
private MapView mapView;
private TextView mFpsTextView;
private ImageView mCompassView;
private FrameLayout mMapFrameLayout;
private float mDensity;
private Spinner mClassSpinner;
Expand All @@ -70,19 +60,6 @@ public class MainActivity extends ActionBarActivity {
// Used for GPS
private MenuItem mGpsMenuItem;

// Used for compass
private SensorManager mSensorManager;
private Sensor mSensorAccelerometer;
private Sensor mSensorMagneticField;
private CompassListener mCompassListener;
private float[] mValuesAccelerometer = new float[3];
private float[] mValuesMagneticField = new float[3];
private float[] mMatrixR = new float[9];
private float[] mMatrixI = new float[9];
private float[] mMatrixValues = new float[3];
private float mCompassBearing;
private boolean mCompassValid = false;

// Used for markers
private boolean mIsMarkersOn = false;

Expand Down Expand Up @@ -142,9 +119,6 @@ public boolean onTouch(View v, MotionEvent event) {
mFpsTextView = (TextView) findViewById(R.id.view_fps);
mFpsTextView.setText("");

mCompassView = (ImageView) findViewById(R.id.view_compass);
mCompassView.setOnClickListener(new CompassOnClickListener());

mMapFrameLayout = (FrameLayout) findViewById(R.id.layout_map);
// Add a toolbar as the action bar
Toolbar mainToolbar = (Toolbar) findViewById(R.id.toolbar_main);
Expand All @@ -163,11 +137,6 @@ public boolean onTouch(View v, MotionEvent event) {
mOutdoorsClassAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
R.array.outdoors_class_list, android.R.layout.simple_spinner_dropdown_item);

mSensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorMagneticField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mCompassListener = new CompassListener();

if (savedInstanceState != null) {
mapView.setMyLocationEnabled(savedInstanceState.getBoolean(STATE_IS_GPS_ON, false));
}
Expand Down Expand Up @@ -296,17 +265,13 @@ private void toggleGps(boolean enableGps) {
if (mGpsMenuItem != null) {
mGpsMenuItem.setIcon(R.drawable.ic_action_location_found);
}
mSensorManager.registerListener(mCompassListener, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(mCompassListener, mSensorMagneticField, SensorManager.SENSOR_DELAY_UI);
}
} else {
if (mapView.isMyLocationEnabled()) {
mapView.setMyLocationEnabled(enableGps);
if (mGpsMenuItem != null) {
mGpsMenuItem.setIcon(R.drawable.ic_action_location_searching);
}
mSensorManager.unregisterListener(mCompassListener, mSensorAccelerometer);
mSensorManager.unregisterListener(mCompassListener, mSensorMagneticField);
}
}
}
Expand Down Expand Up @@ -387,50 +352,6 @@ private void removeAnnotations() {
mapView.removeAnnotations();
}

// This class handles sensor updates to calculate compass bearing
private class CompassListener implements SensorEventListener {

@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
System.arraycopy(event.values, 0, mValuesAccelerometer, 0, 3);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
System.arraycopy(event.values, 0, mValuesMagneticField, 0, 3);
break;
}

boolean valid = SensorManager.getRotationMatrix(mMatrixR, mMatrixI,
mValuesAccelerometer,
mValuesMagneticField);

if (valid) {
SensorManager.getOrientation(mMatrixR, mMatrixValues);
//mAzimuthRadians.putValue(mMatrixValues[0]);
//mAzimuth = Math.toDegrees(mAzimuthRadians.getAverage());

Location mGpsLocation = mapView.getMyLocation();
if (mGpsLocation != null) {
GeomagneticField geomagneticField = new GeomagneticField(
(float) mGpsLocation.getLatitude(),
(float) mGpsLocation.getLongitude(),
(float) mGpsLocation.getAltitude(),
System.currentTimeMillis());
mCompassBearing = (float) Math.toDegrees(mMatrixValues[0]) + geomagneticField.getDeclination();
mCompassValid = true;
}
}

updateMap();
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO: ignore unreliable stuff
}
}

// This class handles style change events
private class StyleSpinnerListener implements AdapterView.OnItemSelectedListener {

Expand Down Expand Up @@ -574,18 +495,10 @@ public void onFpsChanged(double fps) {
}
}

// Rotates an ImageView - does not work if the ImageView has padding, use margins
private void rotateImageView(ImageView imageView, float angle) {
Matrix matrix = new Matrix();
matrix.setScale((float) imageView.getWidth() / (float) imageView.getDrawable().getIntrinsicWidth(), (float) imageView.getHeight() / (float) imageView.getDrawable().getIntrinsicHeight());
matrix.postRotate(angle, (float) imageView.getWidth() / 2.0f, (float) imageView.getHeight() / 2.0f);
imageView.setImageMatrix(matrix);
imageView.setScaleType(ImageView.ScaleType.MATRIX);
}

// Updates the UI to match the current map's position
private void updateMap() {
rotateImageView(mCompassView, (float) mapView.getDirection());
// rotateImageView(mCompassView, (float) mapView.getDirection());

/*
if (mGpsLocation != null) {
Expand Down Expand Up @@ -628,12 +541,4 @@ public void onMapChanged() {
}
}

// Called when someone presses the compass
private class CompassOnClickListener implements View.OnClickListener {

@Override
public void onClick(View view) {
mapView.resetNorth();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,6 @@
android:layout_height="match_parent"
/>

<ImageView
android:id="@+id/view_compass"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end|top"
android:layout_margin="10dp"
android:contentDescription="@string/compass_desc"
android:src="@drawable/compass"/>

<TextView
android:id="@+id/view_fps"
android:layout_width="wrap_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

<string name="label_fps">FPS:</string>

<string name="compass_desc">Map compass. Click to reset the map rotation to North.</string>

<string-array name="style_list">
<item>Mapbox Streets</item>
<item>Emerald</item>
Expand Down

0 comments on commit b5ed8e4

Please sign in to comment.