Home > Software engineering >  Flutter Getx geolocator: Get user position for google maps
Flutter Getx geolocator: Get user position for google maps

Time:10-14

I am currently making a maps page and I need to get the user's current location and pass it into google maps. I am using GetX. However I am currently getting an error about type 'Future<dynamic>' is not a subtype of type 'LatLng' and I do not know what to do to fix this. Essentially I just want to get the user's location and pass it in to a GoogleMap as initial camera position.

Here is my controller:

class LocationController extends GetxController {
  static LocationController instance = Get.find();


  @override
  void onReady() {
    super.onReady();
    getlocation();
  }

 

  getlocation() async {
    bool serviceEnabled;
    LocationPermission permission;
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      await Geolocator.openLocationSettings();
      return Future.error("location service is not enabled");
    }
    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      //do stuff here
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        //stuff
        return Future.error("location permissions denied");
      }
    }
    if (permission == LocationPermission.deniedForever) {
      return Future.error("location permissions permanently denied");
    }
    Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    //position stream?
  }
}

This is the code for the map page:

class MapPage extends StatefulWidget {
  const MapPage({super.key});

  @override
  State<MapPage> createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
 
          Container(
            child: GoogleMap(
              initialCameraPosition: CameraPosition(
                  target: locationController.getlocation(), zoom: 16),
              minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
              zoomGesturesEnabled: true,
              cameraTargetBounds: CameraTargetBounds(
                LatLngBounds(
                  northeast: LatLng(43.7970928, -79.3067414),
                  southwest: LatLng(43.592580, -79.483674),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

CodePudding user response:

try this

 // create a class for location also handle permission
    class PermissionToUser {
    static Future permissionForLocation() async {
    final request = await [Permission.location].request();
    log(request[Permission.location].toString());
    final status = await Permission.location.status;

    if (status.isDenied) {
      request;
      return false;
    } else if (status.isRestricted) {
      request;
      return false;
    } else if (status.isLimited) {
      request;
      return false;
    } else {
      return true;
    }
  }
    static Future<Position>? determinePosition() async {
        bool serviceEnabled;
        LocationPermission permission;
    
        serviceEnabled = await Geolocator.isLocationServiceEnabled();
        if (!serviceEnabled) {
          return Future.error('Location services are disabled.');
        }
    
        permission = await Geolocator.checkPermission();
        if (permission == LocationPermission.denied) {
          permission = await Geolocator.requestPermission();
          if (permission == LocationPermission.denied) {
            return Future.error('Location permissions are denied');
          }
        }
    
        if (permission == LocationPermission.deniedForever) {
          return Future.error(
              'Location permissions are permanently denied, we cannot request permissions.');
        }
    
        return await Geolocator.getCurrentPosition(
            desiredAccuracy: LocationAccuracy.high);
      }
    
    }

As per use on the controller

class LocationController extends GetxController {
 /// Declare the postion also the lat long just for example
 late Position? posinitial;
  final lat = 0.0.obs, lng = 0.0.obs;
  @override
  void onInit() async {
    /// Run through here 
      await PermissionToUser.permissionForLocation().then((value) async {
      posinitial = await PermissionToUser.determinePosition();
    }).whenComplete(() { 
      getPositionData();
      });
     super.onInit();
  }

  getPositionData() async{
   // try to log the data if its not empty
   if (posinitial != null) {
     log("${posinitial!.latitude}",name:"latitude");
     log("${posinitial!.longitude}",name:"longtitude");
     /// just pass this to ui to use 
     lat(posinitial!.latitude);
     long(posinitial!.longitude);
   }
}

}

as for the googgle map you can call the postion

posinitial != null ?
GoogleMap(
 initialCameraPosition: CameraPosition(
 /// you can use the lat long that was declared on the controller 
 /// anyways many ways to do it.
 target:   LatLng(controller.posinitial!.latitude, controller.posinitial!.longitude), zoom: 16),
              minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
              zoomGesturesEnabled: true,
              cameraTargetBounds: CameraTargetBounds(
                LatLngBounds(
                  northeast: LatLng(43.7970928, -79.3067414),
                  southwest: LatLng(43.592580, -79.483674),
                ),
              ),
            ) : const SizedBox.shrink(),

CodePudding user response:

I think you should create a seperate variable like this :

In controller, I created a Position type var myLocation and storing my location in it.

 static LocationController instance = Get.find();
 late Position myLocation;

  @override
  void onInit() {
    super.onInit();
    getlocation();
  }

 

  getlocation() async {
    bool serviceEnabled;
    LocationPermission permission;
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      await Geolocator.openLocationSettings();
      return Future.error("location service is not enabled");
    }
    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      //do stuff here
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        //stuff
        return Future.error("location permissions denied");
      }
    }
    if (permission == LocationPermission.deniedForever) {
      return Future.error("location permissions permanently denied");
    }
    myLocation = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    //position stream?
  }

and the GoogleMap widget should be like:

GoogleMap(
          initialCameraPosition: CameraPosition(
              target: LatLng(
                  locationController.myLocation.latitude,
                  locationController.myLocation.longitude ),   
              zoom: 16),
          minMaxZoomPreference: MinMaxZoomPreference(15.5, 19),
          zoomGesturesEnabled: true,
          cameraTargetBounds: CameraTargetBounds(
            LatLngBounds(
              northeast: LatLng(43.7970928, -79.3067414),
              southwest: LatLng(43.592580, -79.483674),
            ),
          ),
  • Related