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.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.hardware.GeomagneticField;
|
||||||
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.Surface;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
@ -21,21 +23,32 @@ import org.osmdroid.config.Configuration;
|
||||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
||||||
import org.osmdroid.util.GeoPoint;
|
import org.osmdroid.util.GeoPoint;
|
||||||
import org.osmdroid.views.MapView;
|
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.GpsMyLocationProvider;
|
||||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
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.IServiceGps;
|
||||||
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
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";
|
public static final String TAG = "MainActivity";
|
||||||
|
|
||||||
private MyLocationNewOverlay mLocationOverlay;
|
private MyLocationNewOverlay mLocationOverlay;
|
||||||
|
private IOrientationProvider compass = null;
|
||||||
private IServiceGps serviceGps = null;
|
private IServiceGps serviceGps = null;
|
||||||
|
|
||||||
Context ctx = null;
|
private Context ctx = null;
|
||||||
MapView map = 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;
|
private final int REQUEST_CODE_ASK_PERMISSION = 123;
|
||||||
|
|
||||||
|
|
@ -70,20 +83,9 @@ public class MainActivity extends AppCompatActivity {
|
||||||
checkPermissions();
|
checkPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serviceGps == null) {
|
|
||||||
serviceGps = new ServiceGps();
|
|
||||||
}
|
|
||||||
|
|
||||||
//load/initialize the osmdroid configuration, this can be done
|
//load/initialize the osmdroid configuration, this can be done
|
||||||
ctx = getApplicationContext();
|
ctx = getApplicationContext();
|
||||||
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
|
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);
|
setContentView(R.layout.main);
|
||||||
|
|
||||||
// Keep screen ON
|
// Keep screen ON
|
||||||
|
|
@ -102,50 +104,92 @@ public class MainActivity extends AppCompatActivity {
|
||||||
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
||||||
mapController.setCenter(startPoint);
|
mapController.setCenter(startPoint);
|
||||||
|
|
||||||
|
// Current position on the map
|
||||||
final DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
|
|
||||||
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
||||||
map.getOverlays().add(this.mLocationOverlay);
|
map.getOverlays().add(this.mLocationOverlay);
|
||||||
mLocationOverlay.enableMyLocation();
|
mLocationOverlay.enableMyLocation();
|
||||||
mLocationOverlay.enableFollowLocation();
|
mLocationOverlay.enableFollowLocation();
|
||||||
mLocationOverlay.setOptionsMenuEnabled(true);
|
mLocationOverlay.setOptionsMenuEnabled(true);
|
||||||
|
|
||||||
|
if (serviceGps == null) {
|
||||||
|
serviceGps = new ServiceGps();
|
||||||
|
((Observable) serviceGps).addObserver(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onResume(){
|
public void onResume(){
|
||||||
super.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) serviceGps).setLocationManager((LocationManager) getSystemService(ctx.LOCATION_SERVICE));
|
||||||
serviceGps.start();
|
serviceGps.start();
|
||||||
|
|
||||||
mLocationOverlay.enableFollowLocation();
|
mLocationOverlay.enableFollowLocation();
|
||||||
mLocationOverlay.enableMyLocation();
|
mLocationOverlay.enableMyLocation();
|
||||||
|
|
||||||
//this will refresh the osmdroid configuration on resuming.
|
if (compass == null) {
|
||||||
//if you make changes to the configuration, use
|
compass = new InternalCompassOrientationProvider(this);
|
||||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
}
|
||||||
//Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this));
|
compass.startOrientationProvider(this);
|
||||||
|
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
map.onResume(); //needed for compass, my location overlays, v6.0.0 and up
|
map.onResume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onPause(){
|
public void onPause(){
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
|
||||||
mLocationOverlay.disableFollowLocation();
|
private void pause() {
|
||||||
mLocationOverlay.disableMyLocation();
|
if (compass != null) {
|
||||||
|
compass.stopOrientationProvider();
|
||||||
//this will refresh the osmdroid configuration on resuming.
|
compass.destroy();
|
||||||
//if you make changes to the configuration, use
|
compass = null;
|
||||||
//SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
}
|
||||||
//Configuration.getInstance().save(this, prefs);
|
if (mLocationOverlay != null) {
|
||||||
|
mLocationOverlay.disableFollowLocation();
|
||||||
|
mLocationOverlay.disableMyLocation();
|
||||||
|
}
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
map.onPause(); //needed for compass, my location overlays, v6.0.0 and up
|
map.onPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
|
pause();
|
||||||
if (serviceGps != null) {
|
if (serviceGps != null) {
|
||||||
serviceGps.stop();
|
serviceGps.stop();
|
||||||
}
|
}
|
||||||
|
|
@ -187,4 +231,67 @@ public class MainActivity extends AppCompatActivity {
|
||||||
break;
|
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.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
import fr.chteufleur.mytrackingdog.MainActivity;
|
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";
|
private static final String TAG = "ServiceGps";
|
||||||
|
public static final String NOTIF_NEW_LOCATION = "fr.chteufleur.mytrackingdog.services.servicegps.newlocation";
|
||||||
|
|
||||||
private LocationManager locationManager;
|
private LocationManager locationManager;
|
||||||
private Location currentLocation = null;
|
private Location currentLocation = null;
|
||||||
|
|
||||||
|
|
@ -22,6 +26,24 @@ public class ServiceGps implements IServiceGps, LocationListener {
|
||||||
return currentLocation;
|
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
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
|
|
@ -41,6 +63,8 @@ public class ServiceGps implements IServiceGps, LocationListener {
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChanged(Location location) {
|
public void onLocationChanged(Location location) {
|
||||||
currentLocation = location;
|
currentLocation = location;
|
||||||
|
setChanged();
|
||||||
|
notifyObservers(NOTIF_NEW_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue