Compass not working properly in osmdroid
Asked Answered
C

0

0

I am using a plasio turbo x to test my osmdroid sample. I am also testing using a moto g. In moto g the map rotation which is according to the compass head up is working fine, but in plasio one the compass starts to spin and map also spins, they don't get stable. You can see the logcat here(it is very big, stackoverflow not letting me add it here).

Following is my class in which I have used compass:

public class MainActivity extends FragmentActivity implements LocationListener, IOrientationConsumer,MapEventsReceiver {
    private CompassOverlay mCompassOverlay = null;
    private MyLocationNewOverlay mLocationOverlay;
    IOrientationProvider compass = null;
    int deviceOrientation = 0;
    MapView mMapView;
    float gpsspeed;
    float gpsbearing;
    float lat = 0;
    float lon = 0;
    float alt = 0;
    long timeOfFix = 0; 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = getIntent();
        final double lat1 = Double.parseDouble(intent.getStringExtra("lat1"));
        final double long1 = Double.parseDouble(intent.getStringExtra("long1"));
        final double lat2 = 25.633;
        final double long2 = 71.094; 
        //important! set your user agent to prevent getting banned from the osm servers
        org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants.setUserAgentValue(BuildConfig.APPLICATION_ID);

        mMapView = (MapView) findViewById(R.id.map);
        mMapView.setTileSource(TileSourceFactory.MAPNIK);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),
                mMapView);
        mCompassOverlay.enableCompass();
        mMapView.getOverlays().add(this.mCompassOverlay);

        addOverlays();

        GeoPoint startPoint = new GeoPoint(lat1, long1);
        IMapController mapController = mMapView.getController();
        mapController.setZoom(9);
        mapController.setCenter(startPoint);
        Marker startMarker = new Marker(mMapView);
        startMarker.setPosition(startPoint);
        startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
        mMapView.getOverlays().add(startMarker);

        RoadManager roadManager = new OSRMRoadManager(this);
        ArrayList<GeoPoint> waypoints = new ArrayList<GeoPoint>();
        waypoints.add(startPoint);
        GeoPoint endPoint = new GeoPoint(lat2, long2);
        Marker endMarker = new Marker(mMapView);
        endMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
        mMapView.getOverlays().add(endMarker);
        waypoints.add(endPoint);
        Road road = roadManager.getRoad(waypoints);
        Polyline roadOverlay = RoadManager.buildRoadOverlay(road);
        mMapView.getOverlays().add(roadOverlay);
        mMapView.invalidate();

    }

    public void addOverlays() {
        mLocationOverlay = new MyLocationNewOverlay(mMapView);
        mLocationOverlay.setEnableAutoStop(false);
        mLocationOverlay.enableFollowLocation();
        mLocationOverlay.enableMyLocation();
        this.mMapView.getOverlayManager().add(mLocationOverlay);
        mMapView.setBuiltInZoomControls(true);
        mMapView.setMultiTouchControls(true);
        mMapView.setTilesScaledToDpi(true);
    }

    @Override
    protected void onResume() {
        super.onResume();

        //lock the device in current screen orientation
        int orientation;
        int rotation = ((WindowManager) this.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;
        }

        this.setRequestedOrientation(orientation);


        LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        try { 
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                return;
            }
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (LocationListener) this);
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, (LocationListener) this);
        } catch (Exception ex) {
        }
        compass = new InternalCompassOrientationProvider(this);
        compass.startOrientationProvider(this);
        mMapView.getController().zoomTo(14);

    }

    @Override
    public void onLocationChanged(Location location) {
        if (mMapView == null)
            return;
        //after the first fix, schedule the task to change the icon
        //mMapView.getController().setCenter(new GeoPoint(location.getLatitude(), location.getLongitude()));
        mMapView.invalidate();
        gpsbearing = location.getBearing();
        gpsspeed = location.getSpeed();
        lat = (float) location.getLatitude();
        lon = (float) location.getLongitude();
        alt = (float) location.getAltitude(); //meters
        timeOfFix = location.getTime();
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }

    @Override
    protected void onPause() {
        super.onPause();
        compass.stopOrientationProvider();
        LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            lm.removeUpdates(this);
        } catch (Exception ex) {
        }

        //unlock the orientation
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }


    Float trueNorth = 0f;

    @Override
    public void onOrientationChanged(final float orientationToMagneticNorth, IOrientationProvider source) {

        GeomagneticField gf = new GeomagneticField(lat, lon, alt, timeOfFix);
        trueNorth = orientationToMagneticNorth + gf.getDeclination();
        gf=null;
        synchronized (trueNorth) {
            if (trueNorth > 360.0f) {
                trueNorth = trueNorth - 360.0f;
            }

            //use gps bearing instead of the compass
            if (gpsspeed > 0.01f) {
                float t = (360 - gpsbearing - this.deviceOrientation);
                if (t < 0) {
                    t += 360;
                }
                if (t > 360) {
                    t -= 360;
                }
                mMapView.setMapOrientation(t);
            } else {
                //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;
                }
                mMapView.setMapOrientation(t);
            }

            this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (this!=null ) {
                        Toast.makeText(MainActivity.this, "GPS Speed: " + gpsspeed + "m/s  GPS Bearing: " + gpsbearing +
                                "\nDevice Orientation: " + (int) deviceOrientation + "  Compass heading: " + (int) orientationToMagneticNorth + "\n" +
                                "True north: " + trueNorth.intValue() + " Map Orientation: " + (int) mMapView.getMapOrientation() + "\n", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

    @Override
    public boolean singleTapConfirmedHelper(GeoPoint geoPoint) {
        return false;
    }

    @Override
    public boolean longPressHelper(GeoPoint geoPoint) {
        return false;
    }
}
Cytogenesis answered 18/10, 2016 at 15:23 Comment(10)
I don't see anything wrong with the logcat. try downloading any other compass application. it's possible that there's a hardware problem on that devicePeerless
@Peerless the compass feature in official osmdroid app from google play store works fine, and I used the same code in my class too. I have edited my question to include the class, please have a look.Cytogenesis
@Peerless can you please tell what could be the problem?Cytogenesis
it's possible that the gps bearing is fighting against the compass bearing.Peerless
I just put your test code in the sample app, works fine. time for you to start up the debuggerPeerless
@Peerless can you tell me a little what to look for in the debugger?Cytogenesis
the algorithm is basically "use the compass when stationary or no gps, otherwise use the gps bearing" Something isn't right on that device or the algorithm is brokenPeerless
github.com/osmdroid/osmdroid/issues/453Peerless
@Peerless what would happen next?Cytogenesis
@Peerless we tried compass in another app called Fishing points with the same device, the compass is working fine in that one as can be seen here ,but the compass we used in our app is not :- link. Could you guide is why could this be happening, as you have also tried the code we have used, so why could compass in one app be working and in osm not?Cytogenesis

© 2022 - 2024 — McMap. All rights reserved.