Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add location tracking mode #21

Merged
merged 4 commits into from
Feb 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions android/src/main/java/com/mapbox/mapboxgl/Convert.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ static void interpretMapboxMapOptions(Object o, MapboxMapOptionsSink sink) {
if (myLocationEnabled != null) {
sink.setMyLocationEnabled(toBoolean(myLocationEnabled));
}
final Object myLocationTrackingMode = data.get("myLocationTrackingMode");
if (myLocationTrackingMode != null) {
sink.setMyLocationTrackingMode(toInt(myLocationTrackingMode));
}
}

// static void interpretMarkerOptions(Object o, MarkerOptionsSink sink) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class MapboxMapBuilder implements MapboxMapOptionsSink {
.attributionEnabled(false);
private boolean trackCameraPosition = false;
private boolean myLocationEnabled = false;
private int myLocationTrackingMode = 0;
private String styleString = Style.MAPBOX_STREETS;

MapboxMapController build(
Expand All @@ -31,6 +32,7 @@ MapboxMapController build(
new MapboxMapController(id, context, state, registrar, options, styleString);
controller.init();
controller.setMyLocationEnabled(myLocationEnabled);
controller.setMyLocationTrackingMode(myLocationTrackingMode);
controller.setTrackCameraPosition(trackCameraPosition);
return controller;
}
Expand Down Expand Up @@ -96,4 +98,10 @@ public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
public void setMyLocationEnabled(boolean myLocationEnabled) {
this.myLocationEnabled = myLocationEnabled;
}

@Override
public void setMyLocationTrackingMode(int myLocationTrackingMode) {
this.myLocationTrackingMode = myLocationTrackingMode;
}

}
43 changes: 38 additions & 5 deletions android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
import com.mapbox.mapboxsdk.location.OnCameraTrackingChangedListener;
import com.mapbox.mapboxsdk.location.modes.CameraMode;
import com.mapbox.mapboxsdk.location.modes.RenderMode;
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
Expand Down Expand Up @@ -71,6 +73,7 @@ final class MapboxMapController
MapboxMapOptionsSink,
MethodChannel.MethodCallHandler,
com.mapbox.mapboxsdk.maps.OnMapReadyCallback,
OnCameraTrackingChangedListener,
//OnMarkerTappedListener,
PlatformView {
private static final String TAG = "MapboxMapController";
Expand All @@ -83,6 +86,7 @@ final class MapboxMapController
private MapboxMap mapboxMap;
private boolean trackCameraPosition = false;
private boolean myLocationEnabled = false;
private int myLocationTrackingMode = 0;
private boolean disposed = false;
private final float density;
private MethodChannel.Result mapReadyResult;
Expand Down Expand Up @@ -249,11 +253,16 @@ public void onStyleLoaded(@NonNull Style style) {
@SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
if (hasLocationPermission()) {
LocationComponentOptions locationComponentOptions = LocationComponentOptions.builder(context)
.trackingGesturesManagement(true)
.build();
locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(context, mapboxMap.getStyle());
locationComponent.activateLocationComponent(context, mapboxMap.getStyle(), locationComponentOptions);
locationComponent.setLocationComponentEnabled(true);
locationComponent.setCameraMode(CameraMode.TRACKING);
locationComponent.setRenderMode(RenderMode.COMPASS);
updateMyLocationTrackingMode();
setMyLocationTrackingMode(this.myLocationTrackingMode);
locationComponent.addOnCameraTrackingChangedListener(this);
} else {
Log.e(TAG, "missing location permissions");
}
Expand Down Expand Up @@ -385,6 +394,15 @@ public void onCameraIdle() {
methodChannel.invokeMethod("camera#onIdle", Collections.singletonMap("map", id));
}

@Override
public void onCameraTrackingChanged(int currentMode) {
}

@Override
public void onCameraTrackingDismissed() {
methodChannel.invokeMethod("map#onCameraTrackingDismissed",new HashMap<>());
}

// @Override
// public void onMarkerTapped(Marker marker) {
// final Map<String, Object> arguments = new HashMap<>(2);
Expand Down Expand Up @@ -538,12 +556,27 @@ public void setMyLocationEnabled(boolean myLocationEnabled) {
}
}

@Override
public void setMyLocationTrackingMode(int myLocationTrackingMode) {
if (this.myLocationTrackingMode == myLocationTrackingMode) {
return;
}
this.myLocationTrackingMode = myLocationTrackingMode;
if (mapboxMap != null && locationComponent != null) {
updateMyLocationTrackingMode();
}
}

private void updateMyLocationEnabled() {
// if (locationComponent != null) {
// locationComponent.setLocationComponentEnabled(this.myLocationEnabled);
// }
//TODO: call location initialization if changed to true and not initialized yet.;
//Show/Hide use location as needed
}

private void updateMyLocationTrackingMode() {
int[] mapboxTrackingModes = new int[]{ CameraMode.NONE, CameraMode.TRACKING, CameraMode.TRACKING_COMPASS, CameraMode.TRACKING_GPS };
locationComponent.setCameraMode(mapboxTrackingModes[this.myLocationTrackingMode]);
}

private boolean hasLocationPermission() {
return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ interface MapboxMapOptionsSink {
void setZoomGesturesEnabled(boolean zoomGesturesEnabled);

void setMyLocationEnabled(boolean myLocationEnabled);

void setMyLocationTrackingMode(int myLocationTrackingMode);
}
21 changes: 21 additions & 0 deletions example/lib/map_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class MapUiBodyState extends State<MapUiBody> {
bool _tiltGesturesEnabled = true;
bool _zoomGesturesEnabled = true;
bool _myLocationEnabled = true;
MyLocationTrackingMode _myLocationTrackingMode = MyLocationTrackingMode.Tracking;

@override
void initState() {
Expand All @@ -71,6 +72,19 @@ class MapUiBodyState extends State<MapUiBody> {
super.dispose();
}

Widget _myLocationTrackingModeCycler() {
final MyLocationTrackingMode nextType =
MyLocationTrackingMode.values[(_myLocationTrackingMode.index + 1) % MyLocationTrackingMode.values.length];
return FlatButton(
child: Text('change to $nextType'),
onPressed: () {
setState(() {
_myLocationTrackingMode = nextType;
});
},
);
}

Widget _compassToggler() {
return FlatButton(
child: Text('${_compassEnabled ? 'disable' : 'enable'} compasss'),
Expand Down Expand Up @@ -195,12 +209,18 @@ class MapUiBodyState extends State<MapUiBody> {
tiltGesturesEnabled: _tiltGesturesEnabled,
zoomGesturesEnabled: _zoomGesturesEnabled,
myLocationEnabled: _myLocationEnabled,
myLocationTrackingMode: _myLocationTrackingMode,
onMapClick: (point, latLng) async {
print("${point.x},${point.y} ${latLng.latitude}/${latLng.longitude}");
List features = await mapController.queryRenderedFeatures(point, [],null);
if (features.length>0) {
print(features[0]);
}
},
onCameraTrackingDismissed: () {
this.setState(() {
_myLocationTrackingMode = MyLocationTrackingMode.None;
});
}
);

Expand Down Expand Up @@ -230,6 +250,7 @@ class MapUiBodyState extends State<MapUiBody> {
Text('camera tilt: ${_position.tilt}'),
Text(_isMoving ? '(Camera moving)' : '(Camera idle)'),
_compassToggler(),
_myLocationTrackingModeCycler(),
_latLngBoundsToggler(),
_setStyleToSatellite(),
_zoomBoundsToggler(),
Expand Down
58 changes: 36 additions & 22 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ part of mapbox_gl;

typedef void OnMapClickCallback(Point<double> point, LatLng coordinates);

typedef void OnCameraTrackingDismissedCallback();

/// Controller for a single MapboxMap instance running on the host platform.
///
/// Change listeners are notified upon changes to any of
Expand All @@ -20,7 +22,8 @@ typedef void OnMapClickCallback(Point<double> point, LatLng coordinates);
/// Marker tap events can be received by adding callbacks to [onMarkerTapped].
class MapboxMapController extends ChangeNotifier {
MapboxMapController._(
this._id, MethodChannel channel, CameraPosition initialCameraPosition, {this.onMapClick})
this._id, MethodChannel channel, CameraPosition initialCameraPosition,
{this.onMapClick, this.onCameraTrackingDismissed})
: assert(_id != null),
assert(channel != null),
_channel = channel {
Expand All @@ -29,18 +32,24 @@ class MapboxMapController extends ChangeNotifier {
}

static Future<MapboxMapController> init(
int id, CameraPosition initialCameraPosition, {OnMapClickCallback onMapClick}) async {
int id, CameraPosition initialCameraPosition,
{OnMapClickCallback onMapClick,
OnCameraTrackingDismissedCallback onCameraTrackingDismissed}) async {
assert(id != null);
final MethodChannel channel =
MethodChannel('plugins.flutter.io/mapbox_maps_$id');
await channel.invokeMethod('map#waitForMap');
return MapboxMapController._(id, channel, initialCameraPosition, onMapClick: onMapClick);
return MapboxMapController._(id, channel, initialCameraPosition,
onMapClick: onMapClick,
onCameraTrackingDismissed: onCameraTrackingDismissed);
}

final MethodChannel _channel;

final OnMapClickCallback onMapClick;

final OnCameraTrackingDismissedCallback onCameraTrackingDismissed;

/// Callbacks to receive tap events for markers placed on this map.
final ArgumentCallbacks<Marker> onMarkerTapped = ArgumentCallbacks<Marker>();

Expand Down Expand Up @@ -103,6 +112,11 @@ class MapboxMapController extends ChangeNotifier {
onMapClick(Point<double>(x, y), LatLng(lat, lng));
}
break;
case 'map#onCameraTrackingDismissed':
if (onCameraTrackingDismissed != null) {
onCameraTrackingDismissed();
}
break;
default:
throw MissingPluginException();
}
Expand Down Expand Up @@ -246,23 +260,23 @@ class MapboxMapController extends ChangeNotifier {
}
}

Future<List> queryRenderedFeaturesInRect(Rect rect, List<String> layerIds, String filter) async {
try {
final Map<Object, Object> reply = await _channel.invokeMethod(
'map#queryRenderedFeatures',
<String, Object>{
'left': rect.left,
'top': rect.top,
'right': rect.right,
'bottom': rect.bottom,
'layerIds': layerIds,
'filter': filter,
},
);
return reply['features'];
} on PlatformException catch (e) {
return new Future.error(e);
}
}

Future<List> queryRenderedFeaturesInRect(
Rect rect, List<String> layerIds, String filter) async {
try {
final Map<Object, Object> reply = await _channel.invokeMethod(
'map#queryRenderedFeatures',
<String, Object>{
'left': rect.left,
'top': rect.top,
'right': rect.right,
'bottom': rect.bottom,
'layerIds': layerIds,
'filter': filter,
},
);
return reply['features'];
} on PlatformException catch (e) {
return new Future.error(e);
}
}
}
21 changes: 18 additions & 3 deletions lib/src/mapbox_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class MapboxMap extends StatefulWidget {
this.tiltGesturesEnabled = true,
this.trackCameraPosition = false,
this.myLocationEnabled = false,
this.myLocationTrackingMode = MyLocationTrackingMode.Tracking,
this.onMapClick,
this.onCameraTrackingDismissed,
}) : assert(initialCameraPosition != null);

final MapCreatedCallback onMapCreated;
Expand All @@ -34,7 +36,7 @@ class MapboxMap extends StatefulWidget {

/// Geographical bounding box for the camera target.
final CameraTargetBounds cameraTargetBounds;

/// Style URL or Style JSON
/// Can be a MapboxStyle constant, any Mapbox Style URL,
/// or a StyleJSON (https://docs.mapbox.com/mapbox-gl-js/style-spec/)
Expand Down Expand Up @@ -85,6 +87,9 @@ class MapboxMap extends StatefulWidget {
/// when the map tries to turn on the My Location layer.
final bool myLocationEnabled;

/// The mode used to track the user location on the map
final MyLocationTrackingMode myLocationTrackingMode;

/// Which gestures should be consumed by the map.
///
/// It is possible for other gesture recognizers to be competing with the map on pointer
Expand All @@ -98,6 +103,9 @@ class MapboxMap extends StatefulWidget {

final OnMapClickCallback onMapClick;

/// Called when the location tracking mode changes, such as when the user moves the map
final OnCameraTrackingDismissedCallback onCameraTrackingDismissed;

@override
State createState() => _MapboxMapState();
}
Expand Down Expand Up @@ -161,8 +169,10 @@ class _MapboxMapState extends State<MapboxMap> {
}

Future<void> onPlatformViewCreated(int id) async {
final MapboxMapController controller =
await MapboxMapController.init(id, widget.initialCameraPosition, onMapClick: widget.onMapClick);
final MapboxMapController controller = await MapboxMapController.init(
id, widget.initialCameraPosition,
onMapClick: widget.onMapClick,
onCameraTrackingDismissed: widget.onCameraTrackingDismissed);
_controller.complete(controller);
if (widget.onMapCreated != null) {
widget.onMapCreated(controller);
Expand All @@ -186,6 +196,7 @@ class _MapboxMapOptions {
this.trackCameraPosition,
this.zoomGesturesEnabled,
this.myLocationEnabled,
this.myLocationTrackingMode,
});

static _MapboxMapOptions fromWidget(MapboxMap map) {
Expand All @@ -200,6 +211,7 @@ class _MapboxMapOptions {
trackCameraPosition: map.trackCameraPosition,
zoomGesturesEnabled: map.zoomGesturesEnabled,
myLocationEnabled: map.myLocationEnabled,
myLocationTrackingMode: map.myLocationTrackingMode,
);
}

Expand All @@ -223,6 +235,8 @@ class _MapboxMapOptions {

final bool myLocationEnabled;

final MyLocationTrackingMode myLocationTrackingMode;

Map<String, dynamic> toMap() {
final Map<String, dynamic> optionsMap = <String, dynamic>{};

Expand All @@ -242,6 +256,7 @@ class _MapboxMapOptions {
addIfNonNull('zoomGesturesEnabled', zoomGesturesEnabled);
addIfNonNull('trackCameraPosition', trackCameraPosition);
addIfNonNull('myLocationEnabled', myLocationEnabled);
addIfNonNull('myLocationTrackingMode', myLocationTrackingMode?.index);
return optionsMap;
}

Expand Down
8 changes: 8 additions & 0 deletions lib/src/ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ class MapboxStyles {
static const String TRAFFIC_NIGHT = "mapbox://styles/mapbox/traffic-night-v2";
}

/// The camera mode, which determines how the map camera will track the rendered location.
enum MyLocationTrackingMode {
None,
Tracking,
TrackingCompass,
TrackingGPS,
}

/// Bounds for the map camera target.
// Used with [MapboxMapOptions] to wrap a [LatLngBounds] value. This allows
// distinguishing between specifying an unbounded target (null `LatLngBounds`)
Expand Down