Skip to content

Commit

Permalink
Merge pull request flutter-mapbox-gl#21 from tobrun/click_style_and_l…
Browse files Browse the repository at this point in the history
…ocation

Add location tracking mode
  • Loading branch information
yoavrofe authored Feb 8, 2019
2 parents 0a1121a + e6fa6f9 commit 78db9e9
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 30 deletions.
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

0 comments on commit 78db9e9

Please sign in to comment.