From 3215831d26fa25695db84e1d84e0e4c719331f6a Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Wed, 5 Aug 2015 10:53:02 -0500 Subject: [PATCH] #1940 - Initial migration of Compass from TestApp to SDK --- .../com/mapbox/mapboxgl/views/MapView.java | 111 +++++++++++++++++- .../src/main/res/drawable-mdpi/compass.png | Bin .../src/main/res/values/strings.xml | 4 + .../mapbox/mapboxgl/testapp/MainActivity.java | 97 +-------------- .../src/main/res/layout/activity_main.xml | 9 -- .../src/main/res/values/strings.xml | 2 - 6 files changed, 113 insertions(+), 110 deletions(-) rename android/java/{MapboxGLAndroidSDKTestApp => MapboxGLAndroidSDK}/src/main/res/drawable-mdpi/compass.png (100%) create mode 100644 android/java/MapboxGLAndroidSDK/src/main/res/values/strings.xml diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java index 1b3ad5ba6bd..c4f5a354842 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java @@ -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; @@ -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; @@ -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 mOnMapChangedListener; @@ -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(); @@ -1446,6 +1484,8 @@ 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) { @@ -1453,11 +1493,66 @@ private void toggleGps(boolean enableGps) { 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 @@ -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) { @@ -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; @@ -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); diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/compass.png b/android/java/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/compass.png similarity index 100% rename from android/java/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/compass.png rename to android/java/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/compass.png diff --git a/android/java/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/android/java/MapboxGLAndroidSDK/src/main/res/values/strings.xml new file mode 100644 index 00000000000..df022a4679a --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Map compass. Click to reset the map rotation to North. + diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java index 0f6ed63c1a2..6b407acbd2d 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/testapp/MainActivity.java @@ -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; @@ -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; @@ -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; @@ -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; @@ -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); @@ -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)); } @@ -296,8 +265,6 @@ 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()) { @@ -305,8 +272,6 @@ private void toggleGps(boolean enableGps) { if (mGpsMenuItem != null) { mGpsMenuItem.setIcon(R.drawable.ic_action_location_searching); } - mSensorManager.unregisterListener(mCompassListener, mSensorAccelerometer); - mSensorManager.unregisterListener(mCompassListener, mSensorMagneticField); } } } @@ -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 { @@ -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) { @@ -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(); - } - } } diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_main.xml b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_main.xml index d6330d036d0..0cf914a0668 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_main.xml +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_main.xml @@ -47,15 +47,6 @@ android:layout_height="match_parent" /> - - FPS: - Map compass. Click to reset the map rotation to North. - Mapbox Streets Emerald