mapbox / mapbox-gl-native

Interactive, thoroughly customizable maps in native Android, iOS, macOS, Node.js, and Qt applications, powered by vector tiles and OpenGL
https://mapbox.com/mobile
Other
4.37k stars 1.33k forks source link

Location component puck drifts on its own with no user movement after the map has been initialised for a few minutes #16652

Closed AaronConvery closed 1 year ago

AaronConvery commented 2 years ago

Platform: Android Studio Java Mapbox SDK version: 9.1.0

Steps to trigger behavior

I can't manually produce the bug it just happens on its own after the map loads

Expected behavior

The location to remain accurate as it is on startup and not drift without any real user movement

Actual behavior

The location is accurate and then the puck drifts randomly around the nearby locations and the location radius randomly grows large and back down

See main activity below

public class LocationComponentActivity extends AppCompatActivity implements OnMapReadyCallback, PermissionsListener, LocationListener {

public MapboxMap mapboxMap;
private MapView mapView;
FusedLocationProviderClient mFusedLocationClient;
private PermissionsManager permissionsManager;
int PERMISSION_ID = 44;

List<Feature> featureList = new ArrayList();
List<Point> routeCoordinates = new ArrayList<Point>();
ArrayList<String> arrLoc = new ArrayList<String>();

private Button LocationButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Mapbox.getInstance(this, "pk.eyJ1IjoiYWFyb25jb252ZXJ5IiwiYSI6ImNsN2l6ZHptMTB0YnYzcHBid2hrY2Q5cXUifQ.vMh6oO3R5sWWPPxklfrHRA");

    setContentView(R.layout.activity_main);

    mapView = findViewById(R.id.mapView);
    mapView.onCreate(savedInstanceState);
    mapView.getMapAsync(this);

    findViewById(R.id.locationButton).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();

            if (lastKnownLocation != null) {

                CameraPosition position = new CameraPosition.Builder()
                        .target(new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude())) // Sets the new camera position
                        .zoom(16)
                        .bearing(0)
                        .tilt(0)
                        .build(); // Creates a CameraPosition from the builder

                mapboxMap.animateCamera(CameraUpdateFactory
                        .newCameraPosition(position), 7000);
            }
        }
    });
}

@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap) {
    LocationComponentActivity.this.mapboxMap = mapboxMap;
    mapboxMap.setStyle(Style.OUTDOORS,
            new Style.OnStyleLoaded() {
                @Override
                public void onStyleLoaded(@NonNull Style style) {
                    enableLocationComponent(style);

                }
            });
}

@SuppressWarnings( {"MissingPermission"})
public void enableLocationComponent(@NonNull Style loadedMapStyle) {
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {
        // Get an instance of the LocationComponent.
        LocationComponent locationComponent = mapboxMap.getLocationComponent();

        // Activate the LocationComponent
        locationComponent.activateLocationComponent(
                LocationComponentActivationOptions.builder(this, loadedMapStyle).build());

        // Enable the LocationComponent so that it's actually visible on the map
        locationComponent.setLocationComponentEnabled(true);

        // Set the LocationComponent's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        // Set the LocationComponent's render mode
        locationComponent.setRenderMode(RenderMode.NORMAL);

        //Set the zoom level
        locationComponent.zoomWhileTracking(17);

        locationComponent.getLastKnownLocation();

        LocationComponentActivationOptions
                .builder(this, loadedMapStyle)
                .useDefaultLocationEngine(true)
                .locationEngineRequest(new LocationEngineRequest.Builder(750)
                        .setFastestInterval(750)
                        .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
                        .build())
                        .build();

    } else {
        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        mapboxMap.getStyle(new Style.OnStyleLoaded() {
            @Override
            public void onStyleLoaded(@NonNull Style style) {
                enableLocationComponent(style);
            }
        });
    } else {
        Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();
        finish();
    }
}

// show location as string to 2 decimal places
private String hereLocation(Location location) {
    return "Y:" + String.format("%.2f", location.getLatitude()) + "\nX: " + String.format("%.2f", location.getLongitude());
}

private void updateLocationCoordinates(Location location) {

    // Add point to pointlist
    routeCoordinates.add(Point.fromLngLat(location.getLongitude(), location.getLatitude()));
}

@Override
public void onLocationChanged(@NonNull Location location) {

    //Store location in array
    arrLoc.add(hereLocation(location));

    //LineString lineString = LineString.fromLngLats(routeCoordinates);

    Feature multiPointFeature = Feature.fromGeometry(MultiPoint.fromLngLats(routeCoordinates));

    FeatureCollection featureCollectionFromSingleFeature = FeatureCollection.fromFeature(multiPointFeature);

}

private void drawLines(@NonNull FeatureCollection featureCollection) {
    if (mapboxMap != null) {
        mapboxMap.getStyle(style -> {
            if (featureCollection.features() != null) {
                if (featureCollection.features().size() > 0) {
                    style.addSource(new GeoJsonSource("line-source", featureCollection));

                    // The layer properties for our line. This is where we make the line dotted, set the
                    // color, etc.
                    style.addLayer(new LineLayer("linelayer", "line-source")
                            .withProperties(PropertyFactory.lineCap(Property.LINE_CAP_SQUARE),
                                    PropertyFactory.lineJoin(Property.LINE_JOIN_MITER),
                                    PropertyFactory.lineOpacity(.7f),
                                    PropertyFactory.lineWidth(7f),
                                    PropertyFactory.lineColor(Color.parseColor("#3bb2d0"))));
                }
            }
        });
    }
}

}