Orientate the map to fit the current orientation.
This commit is contained in:
parent
05f03941da
commit
645f21b4b3
|
|
@ -2,17 +2,19 @@ package fr.chteufleur.mytrackingdog;
|
|||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.GeomagneticField;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
|
@ -21,21 +23,32 @@ import org.osmdroid.config.Configuration;
|
|||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
||||
import org.osmdroid.util.GeoPoint;
|
||||
import org.osmdroid.views.MapView;
|
||||
import org.osmdroid.views.overlay.compass.IOrientationConsumer;
|
||||
import org.osmdroid.views.overlay.compass.IOrientationProvider;
|
||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
||||
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
|
||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.services.IServiceGps;
|
||||
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
public class MainActivity extends AppCompatActivity implements IOrientationConsumer, Observer {
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
private MyLocationNewOverlay mLocationOverlay;
|
||||
private IOrientationProvider compass = null;
|
||||
private IServiceGps serviceGps = null;
|
||||
|
||||
Context ctx = null;
|
||||
MapView map = null;
|
||||
private Context ctx = null;
|
||||
private MapView map = null;
|
||||
|
||||
private Float trueNorth = 0f;
|
||||
private int deviceOrientation = 0;
|
||||
private boolean zoomed = false;
|
||||
|
||||
private final int REQUEST_CODE_ASK_PERMISSION = 123;
|
||||
|
||||
|
|
@ -70,20 +83,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
checkPermissions();
|
||||
}
|
||||
|
||||
if (serviceGps == null) {
|
||||
serviceGps = new ServiceGps();
|
||||
}
|
||||
|
||||
//load/initialize the osmdroid configuration, this can be done
|
||||
ctx = getApplicationContext();
|
||||
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
|
||||
//setting this before the layout is inflated is a good idea
|
||||
//it 'should' ensure that the map has a writable location for the map cache, even without permissions
|
||||
//if no tiles are displayed, you can try overriding the cache path using Configuration.getInstance().setCachePath
|
||||
//see also StorageUtils
|
||||
//note, the load method also sets the HTTP User Agent to your application's package name, abusing osm's tile servers will get you banned based on this string
|
||||
|
||||
//inflate and create the map
|
||||
setContentView(R.layout.main);
|
||||
|
||||
// Keep screen ON
|
||||
|
|
@ -102,50 +104,92 @@ public class MainActivity extends AppCompatActivity {
|
|||
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
||||
mapController.setCenter(startPoint);
|
||||
|
||||
|
||||
final DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
|
||||
// Current position on the map
|
||||
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
||||
map.getOverlays().add(this.mLocationOverlay);
|
||||
mLocationOverlay.enableMyLocation();
|
||||
mLocationOverlay.enableFollowLocation();
|
||||
mLocationOverlay.setOptionsMenuEnabled(true);
|
||||
|
||||
if (serviceGps == null) {
|
||||
serviceGps = new ServiceGps();
|
||||
((Observable) serviceGps).addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(){
|
||||
super.onResume();
|
||||
|
||||
//hack for x86
|
||||
if (!"Android-x86".equalsIgnoreCase(Build.BRAND)) {
|
||||
//lock the device in current screen orientation
|
||||
int orientation;
|
||||
int rotation = ((WindowManager) getSystemService(
|
||||
Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_0:
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
this.deviceOrientation = 0;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
this.deviceOrientation = 90;
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
this.deviceOrientation = 180;
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
break;
|
||||
default:
|
||||
this.deviceOrientation = 270;
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
break;
|
||||
}
|
||||
|
||||
setRequestedOrientation(orientation);
|
||||
}
|
||||
|
||||
((ServiceGps) serviceGps).setLocationManager((LocationManager) getSystemService(ctx.LOCATION_SERVICE));
|
||||
serviceGps.start();
|
||||
|
||||
mLocationOverlay.enableFollowLocation();
|
||||
mLocationOverlay.enableMyLocation();
|
||||
|
||||
//this will refresh the osmdroid configuration on resuming.
|
||||
//if you make changes to the configuration, use
|
||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
//Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this));
|
||||
if (compass == null) {
|
||||
compass = new InternalCompassOrientationProvider(this);
|
||||
}
|
||||
compass.startOrientationProvider(this);
|
||||
|
||||
if (map != null) {
|
||||
map.onResume(); //needed for compass, my location overlays, v6.0.0 and up
|
||||
map.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause(){
|
||||
super.onPause();
|
||||
pause();
|
||||
}
|
||||
|
||||
mLocationOverlay.disableFollowLocation();
|
||||
mLocationOverlay.disableMyLocation();
|
||||
|
||||
//this will refresh the osmdroid configuration on resuming.
|
||||
//if you make changes to the configuration, use
|
||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
//Configuration.getInstance().save(this, prefs);
|
||||
private void pause() {
|
||||
if (compass != null) {
|
||||
compass.stopOrientationProvider();
|
||||
compass.destroy();
|
||||
compass = null;
|
||||
}
|
||||
if (mLocationOverlay != null) {
|
||||
mLocationOverlay.disableFollowLocation();
|
||||
mLocationOverlay.disableMyLocation();
|
||||
}
|
||||
if (map != null) {
|
||||
map.onPause(); //needed for compass, my location overlays, v6.0.0 and up
|
||||
map.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
pause();
|
||||
if (serviceGps != null) {
|
||||
serviceGps.stop();
|
||||
}
|
||||
|
|
@ -187,4 +231,67 @@ public class MainActivity extends AppCompatActivity {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOrientationChanged(float orientationToMagneticNorth, IOrientationProvider source) {
|
||||
//note, on devices without a compass this never fires...
|
||||
Location location = ((ServiceGps) serviceGps).getCurrentLocation();
|
||||
if (location == null) {
|
||||
return ;
|
||||
}
|
||||
|
||||
float gpsspeed = location.getSpeed();
|
||||
float lat = (float) location.getLatitude();
|
||||
float lon = (float) location.getLongitude();
|
||||
float alt = (float) location.getAltitude();
|
||||
long timeOfFix = location.getTime();
|
||||
|
||||
//only use the compass bit if we aren't moving, since gps is more accurate when we are moving
|
||||
if (gpsspeed < 0.01) {
|
||||
GeomagneticField gf = new GeomagneticField(lat, lon, alt, timeOfFix);
|
||||
trueNorth = orientationToMagneticNorth + gf.getDeclination();
|
||||
gf = null;
|
||||
synchronized (trueNorth) {
|
||||
if (trueNorth > 360.0f) {
|
||||
trueNorth = trueNorth - 360.0f;
|
||||
}
|
||||
float actualHeading = 0f;
|
||||
|
||||
//this part adjusts the desired map rotation based on device orientation and compass heading
|
||||
float t = (360 - trueNorth - this.deviceOrientation);
|
||||
if (t < 0) {
|
||||
t += 360;
|
||||
}
|
||||
if (t > 360) {
|
||||
t -= 360;
|
||||
}
|
||||
actualHeading = t;
|
||||
//help smooth everything out
|
||||
t = (int) t;
|
||||
t = t / 5;
|
||||
t = (int) t;
|
||||
t = t * 5;
|
||||
map.setMapOrientation(t);
|
||||
if (!zoomed) {
|
||||
IMapController mapController = map.getController();
|
||||
mapController.setZoom(20.0);
|
||||
zoomed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(Observable observable, Object o) {
|
||||
if (observable == serviceGps) {
|
||||
if (o instanceof String && (String) o == ServiceGps.NOTIF_NEW_LOCATION) {
|
||||
float orientation = ((ServiceGps) serviceGps).getOrientation(deviceOrientation);
|
||||
if (orientation >= 0) {
|
||||
map.setMapOrientation(orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,15 @@ import android.location.LocationManager;
|
|||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Observable;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.MainActivity;
|
||||
|
||||
public class ServiceGps implements IServiceGps, LocationListener {
|
||||
public class ServiceGps extends Observable implements IServiceGps, LocationListener {
|
||||
|
||||
private static final String TAG = "ServiceGps";
|
||||
public static final String NOTIF_NEW_LOCATION = "fr.chteufleur.mytrackingdog.services.servicegps.newlocation";
|
||||
|
||||
private LocationManager locationManager;
|
||||
private Location currentLocation = null;
|
||||
|
||||
|
|
@ -22,6 +26,24 @@ public class ServiceGps implements IServiceGps, LocationListener {
|
|||
return currentLocation;
|
||||
}
|
||||
|
||||
public float getOrientation(int deviceOrientation) {
|
||||
float ret = -1;
|
||||
if (currentLocation != null && currentLocation.getSpeed() >= 0.01) {
|
||||
ret = (360 - currentLocation.getBearing() - deviceOrientation);
|
||||
if (ret < 0) {
|
||||
ret += 360;
|
||||
}
|
||||
if (ret > 360) {
|
||||
ret -= 360;
|
||||
}
|
||||
//help smooth everything out
|
||||
ret = (int) ret;
|
||||
ret = ret / 5;
|
||||
ret = (int) ret;
|
||||
ret = ret * 5;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
|
@ -41,6 +63,8 @@ public class ServiceGps implements IServiceGps, LocationListener {
|
|||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
currentLocation = location;
|
||||
setChanged();
|
||||
notifyObservers(NOTIF_NEW_LOCATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in New Issue