Skip to content

Commit

Permalink
wipp
Browse files Browse the repository at this point in the history
  • Loading branch information
Xennis committed Sep 27, 2023
1 parent bdb3453 commit 1f7a73b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 79 deletions.
15 changes: 8 additions & 7 deletions green_walking/lib/map_utils.dart
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import 'dart:developer' show log;
import 'dart:io' show Platform;

import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';

class UserLocation {
UserLocation({required this.location, this.bearing});
class PuckLocation {
PuckLocation({required this.location, this.bearing});

Position location;
double? bearing;
}

extension PuckPosition on StyleManager {
Future<UserLocation?> getPuckPosition() async {
Future<PuckLocation?> getPuckLocation() async {
try {
final Layer? layer = Platform.isAndroid
? await getLayer("mapbox-location-indicator-layer")
: await getLayer("puck");
? await getLayer('mapbox-location-indicator-layer')
: await getLayer('puck');
final LocationIndicatorLayer liLayer = layer as LocationIndicatorLayer;
final List<double?>? location = liLayer.location;
return Future.value(UserLocation(
return Future.value(PuckLocation(
location: Position(location![1]!, location[0]!),
bearing: liLayer.bearing));
} catch (e) {
// FIXME: Log error
log('failed to get puck location: $e');
return null;
}
}
Expand Down
10 changes: 5 additions & 5 deletions green_walking/lib/pages/map/location_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

enum UserLocatinTracking { no, position, full }
enum UserLocationTracking { no, position, positionBearing }

class LocationButton extends StatefulWidget {
const LocationButton(
Expand All @@ -14,7 +14,7 @@ class LocationButton extends StatefulWidget {

final void Function(bool) onOkay;
final VoidCallback onNoPermissions;
final ValueNotifier<UserLocatinTracking> trackUserLocation;
final ValueNotifier<UserLocationTracking> trackUserLocation;

@override
State<LocationButton> createState() => _LocationButtonState();
Expand Down Expand Up @@ -51,13 +51,13 @@ class _LocationButtonState extends State<LocationButton> {
child: FloatingActionButton(
backgroundColor: Theme.of(context).colorScheme.secondary,
onPressed: _onPressed,
child: ValueListenableBuilder<UserLocatinTracking>(
child: ValueListenableBuilder<UserLocationTracking>(
valueListenable: widget.trackUserLocation,
builder: (context, value, child) {
final IconData icon = _locationServiceEnabled
? value == UserLocatinTracking.position
? value == UserLocationTracking.position
? Icons.my_location
: value == UserLocatinTracking.full
: value == UserLocationTracking.positionBearing
? Icons.arrow_upward
: Icons.location_searching
: Icons.location_disabled;
Expand Down
123 changes: 57 additions & 66 deletions green_walking/lib/pages/map/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ class MapPage extends StatefulWidget {

class _MapPageState extends State<MapPage> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final ValueNotifier<UserLocatinTracking> _userlocationTracking =
ValueNotifier<UserLocatinTracking>(UserLocatinTracking.no);
final ValueNotifier<UserLocationTracking> _userlocationTracking =
ValueNotifier<UserLocationTracking>(UserLocationTracking.no);

late MapboxMap _mapboxMap;
CircleAnnotationManager? _circleAnnotationManager;
Timer? _timer;

@override
Expand Down Expand Up @@ -132,76 +133,77 @@ class _MapPageState extends State<MapPage> {

Widget map(BuildContext context, MapConfig config) {
return MapWidget(
key: const ValueKey("mapWidget"),
key: const ValueKey('mapWidget'),
resourceOptions: ResourceOptions(accessToken: config.accessToken),
onMapCreated: (MapboxMap mapboxMap) {
//mapboxMap.setTelemetryEnabled(false);
mapboxMap.compass.updateSettings(CompassSettings(marginTop: 400.0));
mapboxMap.scaleBar.updateSettings(ScaleBarSettings(enabled: false));
_mapboxMap = mapboxMap;

//mapboxMap.setTelemetryEnabled(false);
_mapboxMap.compass.updateSettings(CompassSettings(marginTop: 400.0));
_mapboxMap.scaleBar.updateSettings(ScaleBarSettings(enabled: false));
//mapController!.onSymbolTapped.add(_onSymbolTapped);
//onPositionChanged(mapController!.cameraPosition);

_mapboxMap.annotations.createCircleAnnotationManager().then((value) {
_circleAnnotationManager = value;
});
},
cameraOptions: config.lastPosition ??
CameraOptions(
center: Point(coordinates: Position(9.8682, 53.5519)).toJson(),
zoom: 11.0),
//myLocationEnabled: true,
//rotateGesturesEnabled: true,
//styleString: _mapboxStyle.id,
styleUri: CustomMapboxStyles.outdoor,
//trackCameraPosition: true,
onMapIdleListener: _onCameraIdle,
//onCameraTrackingDismissed: () => _userlocationTracking.value = false,
//onCameraChangeListener:
// (CameraChangedEventData cameraChangedEventData) {
// _userlocationTracking.value = UserLocatinTracking.no;
onScrollListener: (ScreenCoordinate coordinate) {
if (_userlocationTracking.value != UserLocatinTracking.no) {
// Turn of tracking because user scrolled.
_userlocationTracking.value = UserLocatinTracking.no;
if (_userlocationTracking.value != UserLocationTracking.no) {
// Turn off tracking because user scrolled to another location.
_userlocationTracking.value = UserLocationTracking.no;
}
},
);
}

Future<Position?> _getMapPosition() async {
Future<Position?> _getCameraPosition() async {
try {
final CameraState mapCameraState = await _mapboxMap.getCameraState();
final List<Object?> coordinates =
mapCameraState.center["coordinates"] as List<Object?>;
mapCameraState.center['coordinates'] as List<Object?>;
return Position(coordinates[0] as num, coordinates[1] as num);
} catch (e) {
// Fixme: Log error?
log('failed to get camera position: $e');
return null;
}
}

Future<void> _onSearchTab(String accessToken) async {
final Position? mapPosition = await _getMapPosition();
if (mapPosition == null) {
final Position? cameraPosition = await _getCameraPosition();
if (cameraPosition == null) {
return;
}
// See https://dart.dev/tools/linter-rules/use_build_context_synchronously
if (context.mounted) {
final Position? moveToLoc = await Navigator.push(
context,
NoTransitionPageRoute<Position>(
builder: (BuildContext context) =>
SearchPage(mapPosition: mapPosition, accessToken: accessToken)),
builder: (BuildContext context) => SearchPage(
mapPosition: cameraPosition, accessToken: accessToken)),
);
if (moveToLoc == null) {
return;
}
setCameraPosition(moveToLoc, null, null);
/*_mapboxMap?.clearCircles();
_mapboxMap?.addCircle(CircleOptions(
circleRadius: 12,
circleColor: '#FFC0CB',
circleOpacity: 0.6,
circleStrokeWidth: 2,
circleStrokeColor: '#FFC0CB',
geometry: moveToLoc));*/
// If we keep the tracking on the map would move back to the user location.
_userlocationTracking.value = UserLocationTracking.no;
_setCameraPosition(moveToLoc, 0, 0);

// Draw circle
await _circleAnnotationManager?.deleteAll();
_circleAnnotationManager?.create(CircleAnnotationOptions(
geometry: Point(coordinates: moveToLoc).toJson(),
circleRadius: 12,
circleColor: const Color.fromRGBO(255, 192, 203, 1).value,
circleOpacity: 0.6,
circleStrokeWidth: 2,
circleStrokeColor: const Color.fromRGBO(255, 192, 203, 1).value));
}
}

Expand All @@ -214,77 +216,66 @@ class _MapPageState extends State<MapPage> {
}
}

void setCameraPosition(Position position, double? bearing, double? pitch) {
_mapboxMap.flyTo(
Future<void> _setCameraPosition(
Position position, double? bearing, double? pitch) async {
return _mapboxMap.flyTo(
CameraOptions(
center: Point(coordinates: position).toJson(),
bearing: bearing,
pitch: pitch,
//padding: defaultEdgeInsets,
zoom: 16.5,
),
MapAnimationOptions(duration: 900 + 100));
}

void refreshTrackLocation() async {
_timer?.cancel();
if (_userlocationTracking.value == UserLocatinTracking.no) {
return;
}

_timer = Timer.periodic(const Duration(milliseconds: 900), (timer) async {
if (_userlocationTracking.value == UserLocatinTracking.no) {
if (_userlocationTracking.value == UserLocationTracking.no) {
_timer?.cancel();
return;
}

final UserLocation? loc = await _mapboxMap.style
.getPuckPosition()
final PuckLocation? puckLocation = await _mapboxMap.style
.getPuckLocation()
.timeout(const Duration(milliseconds: 900 - 100));
if (loc == null) {
if (puckLocation == null) {
// FIXME: Show toast if no location.
// ScaffoldMessenger.of(context)
// .showSnackBar(SnackBar(content: Text(locale.errorNoPositionFound)));
return;
}

switch (_userlocationTracking.value) {
case UserLocatinTracking.full:
setCameraPosition(loc.location, loc.bearing, 50.0);
case UserLocatinTracking.position:
setCameraPosition(loc.location, 0.0, 0.0);
case UserLocatinTracking.no:
// Handled above already. In case there is no location returned we would not cancel
// the timer otherwise.
case UserLocationTracking.positionBearing:
_setCameraPosition(puckLocation.location, puckLocation.bearing, 50.0);
case UserLocationTracking.position:
_setCameraPosition(puckLocation.location, 0.0, 0.0);
case UserLocationTracking.no:
// Handled above already. In case there is no location returned we would not cancel
// the timer otherwise.
}
});
}

Future<void> _onLocationSearchPressed(
AppLocalizations locale, bool permissionGranted) async {
if (_userlocationTracking.value == UserLocatinTracking.position) {
_userlocationTracking.value = UserLocatinTracking.full;
if (_userlocationTracking.value == UserLocationTracking.position) {
_userlocationTracking.value = UserLocationTracking.positionBearing;
} else {
_userlocationTracking.value = UserLocatinTracking.position;
_userlocationTracking.value = UserLocationTracking.position;
}
await _mapboxMap.location.updateSettings(LocationComponentSettings(
enabled: true,
pulsingEnabled: false,
showAccuracyRing: true,
puckBearingEnabled: true));
refreshTrackLocation();

// FIXME: Show toast if no location.
/*
} else {
// See https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
if (!mounted) return;
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(locale.errorNoPositionFound)));
}
*/
}

Future<void> _onCameraIdle(MapIdleEventData mapIdleEventData) async {
// TODO: Maybe use a Timer instead of writing data that often?
//final CameraState cameraState = await _mapboxMap.getCameraState();
//SharedPrefs.setCameraState(SharedPrefs.keyLastPosition, cameraState);
final CameraState cameraState = await _mapboxMap.getCameraState();
SharedPrefs.setCameraState(SharedPrefs.keyLastPosition, cameraState);
}
}
2 changes: 1 addition & 1 deletion green_walking/lib/services/shared_prefs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SharedPrefs {

static void setCameraState(String key, CameraState val) {
try {
final String raw = jsonEncode(val.encode()); // TODO??????????
final String raw = jsonEncode(val.encode());
SharedPreferences.getInstance()
.then((SharedPreferences prefs) => prefs.setString(key, raw));
} catch (e) {
Expand Down

0 comments on commit 1f7a73b

Please sign in to comment.