I am trying to load a Google Map widget to coordinates whose latitude and longitude are saved as double variables in a custom object called AddressObject. In the edit_address.dart I want to initState call the camera position to the saved location's coordinates. Here, editingAddress is an instance of AddressObject. I am calling the getSavedLocation method in initState but the camera would be stuck at (0,0).
Relevant Codes:
class AddressObject {
String personName;
//String? type;
String addressLine1;
String addressLine2;
String? landmark;
String city;
String state;
String pinCode;
bool isCurrentAddress;
double latitude;
double longitude;
AddressObject({
required this.personName,
//this.type,
required this.addressLine1,
required this.addressLine2,
this.landmark,
required this.city,
required this.state,
required this.pinCode,
required this.isCurrentAddress,
required this.latitude,
required this.longitude,
});
}
edit_address.dart
GoogleMapController? _googleMapController;
CameraPosition _cameraPosition = CameraPosition(target: LatLng(0, 0));
LatLng _latlong = LatLng(0, 0);
Future<void> getSavedLocation() async {
bool serviceEnabled;
LocationPermission permission;
serviceEnabled =
await GeolocatorPlatform.instance.isLocationServiceEnabled();
if (!serviceEnabled) {
await GeolocatorPlatform.instance.openLocationSettings();
return Future.error('Location services are disabled.');
}
permission = await GeolocatorPlatform.instance.checkPermission();
if (permission == LocationPermission.denied) {
permission = await GeolocatorPlatform.instance.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.');
}
// position = await GeolocatorPlatform.instance.getCurrentPosition(
// locationSettings:
// const LocationSettings(accuracy: LocationAccuracy.high));
_latlong =
LatLng(widget.editingAddress.latitude, widget.editingAddress.longitude);
setState(() {
_googleMapController!.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(target: _latlong, zoom: 15)));
getAddress();
print(
"${widget.editingAddress.latitude}, ${widget.editingAddress.longitude}");
print("${_latlong.latitude}, ${_latlong.longitude}");
});
//return position;
}
List<Placemark>? placeMarks;
getAddress() async {
placeMarks =
await placemarkFromCoordinates(_latlong.latitude, _latlong.longitude);
Placemark placemark = placeMarks![0];
// _addressController.text =
// "${placemark.street}, ${placemark.subLocality}, ${placemark.locality}, ${placemark.subAdministrativeArea}, ${placemark.postalCode}, ${placemark.country}";
_addressLine1Controller.text =
"${placemark.street}, ${placemark.subThoroughfare}";
_addressLine2Controller.text = "${placemark.thoroughfare}";
_landmarkController.text = "${placemark.subThoroughfare}";
_cityController.text = "${placemark.subLocality}";
_stateController.text = "${placemark.administrativeArea}";
_pinCodeController.text = "${placemark.postalCode}";
}
#override
void initState() {
super.initState();
getSavedLocation();
_personNameController.text = widget.editingAddress.personName;
_addressLine1Controller.text = widget.editingAddress.addressLine1;
_addressLine2Controller.text = widget.editingAddress.addressLine2;
_landmarkController.text = widget.editingAddress.landmark!;
_cityController.text = widget.editingAddress.city;
_stateController.text = widget.editingAddress.state;
_pinCodeController.text = widget.editingAddress.pinCode;
}
I'm having the following code inside Widget build:
SizedBox(
width: screenWidth,
height: screenHeight * 0.225,
child: GoogleMap(
initialCameraPosition: _cameraPosition,
onMapCreated: (controller) {
setState(() {
_googleMapController = controller;
});
},
markers: Set<Marker>.of(<Marker>[
Marker(
markerId: MarkerId("1"),
position: _latlong,
icon: BitmapDescriptor.defaultMarkerWithHue(
BitmapDescriptor.hueRed),
),
]),
onCameraMove: (CameraPosition cameraposition) async {
_cameraPosition = cameraposition;
_latlong = LatLng(cameraposition.target.latitude,
cameraposition.target.longitude);
getAddress();
},
),
),
What is wrong with my code that is preventing the google maps camera to load to the saved location coordinates and how to solve the problem?
Issue resolved when I uncommented the following lines in the getSavedAddress method:
// position = await GeolocatorPlatform.instance.getCurrentPosition(
// locationSettings:
// const LocationSettings(accuracy: LocationAccuracy.high));
Related
Using flutter_polyline_points: ^1.0.0 & google_maps_flutter: ^2.2.1
So what I am trying to achieve is to draw polylines on Google Map at flutter following current WALKING user location [using Geolocator]. The code below works, except when I stay out of the road, polylines are not drawn after my location [the location of blue dot at google maps] but they stick to the main road and won't cross it's boundaries...
(https://i.stack.imgur.com/FHV2d.jpg)
CountDown func is counting down to 0 and then showing map/location/timer etc [start walk]
_CountDown() async {
const oneSec = Duration(seconds: 1);
_timer = Timer.periodic(oneSec, (timer) {
_startTimer == 0
? setState(
() {
timer.cancel();
_getCurrentLocation();
Future.delayed(const Duration(seconds: 5), () {
stopWatchTimer.onStartTimer();
_updateMapAndValues();
});
},
)
: setState(
() => _startTimer--,
);
});
}
_getCurrentLocation() is getting current position and sets late _currectPosition to later zoom on it with map.
_getCurrentLocation() async {
await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true)
.then((Position position) async {
setState(() {
_currentPosition = position;
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(position.latitude, position.longitude),
zoom: 18.0,
),
),
);
});
}).catchError((e) {
print(e);
});
}
After that I am stopping the timer/updating the map.
First I am getting current position to check if location changed, then I am creating polyline between old _currentposition and new position (later calc distance and coins but that's not that importand).
_updateMapAndValues() async {
bool petla = true;
while (petla) {
await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best,
forceAndroidLocationManager: true)
.then((Position position) async {
await Future.delayed(const Duration(milliseconds: 500));
if (_currentPosition.latitude != position.latitude &&
_currentPosition.longitude != position.longitude) {
_createPolylines(_currentPosition, position);
await _calculateDistance();
setState(() {
_currentPosition = position;
int result = distance * 1000 ~/ 50;
print('DYSTANS ILE COINOW : $result');
if (result > 0) {
while (coins < result) {
setState(
() => coins++,
);
}
}
});
}
});
}
}
The _createPolylines function. I thought it will work adding travelMode:walking but it does not. Still (mostly) following the roads and when I am moving at the edges (screen) it just draw straight line.
late PolylinePoints polylinePoints;
List<LatLng> polylineCoords = [];
Map<PolylineId, Polyline> polylines = {};
_createPolylines(Position start, Position end) async {
polylinePoints = PolylinePoints();
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
'AIzaSyDDyBb0N9_jthBS99PRJcT6CjFV2TI9J5E',
PointLatLng(start.latitude, start.longitude),
PointLatLng(end.latitude, end.longitude),
travelMode: TravelMode.walking,
avoidHighways: true,
);
if (result.points.isNotEmpty) {
result.points.forEach((element) {
polylineCoords.add(LatLng(element.latitude, element.longitude));
print('--------WYSWIETLAM: $polylineCoords');
});
}
PolylineId id = const PolylineId('poly');
Polyline polyline = Polyline(
polylineId: id,
color: Colors.red,
points: polylineCoords,
width: 5,
);
polylines[id] = polyline;
}
I'm currently developing a flutter a taxi application and I want to use MapQuest API for the applications to get the locations names and to draw route from one point to another.
The problem is that calling the API and getting the locations works fine but the route is showing on the map in a really weird way.
Here is the provider code for calling the API and getting the route locations points:
class MapQuestDataProvider {
Future<MapQuestDirection> getDirections(
LatLng Source, LatLng Destination) async {
try {
MapQuestDirection result = MapQuestDirection(locations: []);
var aPIKey = "[API_KEY]";
var url =
"https://www.mapquestapi.com/directions/v2/optimizedroute?key=$aPIKey&json={\"locations\":[\"${Source.latitude},${Destination.longitude}\",\"${Destination.latitude},${Source.longitude}\"]}";
var uri = Uri.parse(url);
final response = await http.get(uri);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
var route = data["route"];
var legs = route["legs"];
var zero = legs[0];
var maneuvers = zero["maneuvers"] as List;
for (var element in maneuvers) {
var startPoint = element["startPoint"];
var lat = startPoint["lat"];
var lng = startPoint["lng"];
result.locations.add(LatLng(lat, lng));
}
return result;
} else {
throw Exception('Failed to load Locations');
}
} catch (e) {
print("Exception throuwn $e");
throw e;
}
}
}
Here is the code for my Map Widget:
class MapWidget extends StatefulWidget {
MapWidget(
{Key? key,
this.currentLocation,
required this.onTab,
required this.markers,
this.endLocation,
required this.polylines})
: super(key: key);
LatLng? currentLocation;
void Function(LatLng) onTab;
Set<Marker> markers = {};
LatLng? endLocation;
Map<PolylineId, Polyline> polylines = {};
#override
State<MapWidget> createState() => _MapWidgetState();
}
class _MapWidgetState extends State<MapWidget> {
GoogleMapController? mapController;
final defaultMapZooming = 18.0;
#override
Widget build(BuildContext context) {
return Container(child: mapView(context));
}
Widget mapView(BuildContext context) {
if (mapController != null && widget.currentLocation != null) {
mapController!.animateCamera(CameraUpdate.newLatLngZoom(
LatLng(widget.currentLocation!.latitude,
widget.currentLocation!.longitude),
defaultMapZooming));
}
var map = GoogleMap(
onMapCreated: onMapCreated,
zoomControlsEnabled: false,
myLocationEnabled: false,
mapType: MapType.normal,
onLongPress: (loc) {
widget.onTab(loc);
},
markers: widget.markers,
polylines: widget.polylines.values.toSet(),
minMaxZoomPreference: const MinMaxZoomPreference(12, 25),
initialCameraPosition: CameraPosition(
target: getLocationOrDefault(),
zoom: defaultMapZooming,
),
onCameraMove: (CameraPosition cameraPosition) {
print("ZOOOOOOOOOOOOOOOOOOOM IS : " + cameraPosition.zoom.toString());
},
);
return map;
}
onMapCreated(GoogleMapController controller) {
mapController = controller;
}
getLocationOrDefault() {
return widget.currentLocation ??
const LatLng(21.215415017175165, 72.8879595194489);
}
}
And Here is the code that gets called by placing a new marker on the map which draws the polygon that will be sent to the Map Widget after state update:
SetPathFromMapQuestData(List<LatLng> Locations) {
PolylinePoints polylinePoints = PolylinePoints();
Set<Marker> markers = Set(); //markers for google map
LatLng startLocation = this.startLocation!;
LatLng endLocation = this.endLocation!;
double distance = 0.0;
List<LatLng> polylineCoordinates = [];
//polylineCoordinates.add(this.startLocation!);
Locations.forEach((LatLng point) {
polylineCoordinates.add(point);
});
polylineCoordinates.insert(0, this.startLocation!);
polylineCoordinates.add(this.endLocation!);
PolylineId id = PolylineId("poly");
var poly = GetPloylineId(polylineCoordinates, id);
polylines[id] = poly;
setState(() {
this.polylines = polylines;
});
}
Polyline GetPloylineId(List<LatLng> polylineCoordinates, PolylineId id) {
Polyline polyline = Polyline(
polylineId: id,
color: Colors.deepPurpleAccent,
points: polylineCoordinates,
width: 8,
);
return polyline;
}
This is the result:
The Result Map Image
After working for hours I moved to MapBox and it works perfectly.
Here is the link for the Api:
https://docs.mapbox.com/android/navigation/guides/
i have function which gets user phone location, and i want to set Marker on this location.
The question is :
How i can type to LatLng() location of user's phone.
What i tried? :
When i type there var locationMessage there is an error:
2 positional argument(s) expected, but 1 found
void getCurrentLocation() async {
var position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
var lastPosition = await Geolocator.getLastKnownPosition();
print(lastPosition);
setState(() {
locationMessage = "${position.altitude}, ${position.longitude}";
});
}
GoogleMap(
markers: _markers,
initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
setState(() {
_markers.add(Marker(
icon: mapMarker,
markerId: const MarkerId("marker-1"),
position: LatLng(//HOW TO INSERT HERE USER'S LOCATION)));
});
},
),
Instead of declaring locationMessage with String type use Position type.
so instead of
var position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
replace with
locationMessage = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
Then here
........
........
........
setState(() {
_markers.add(Marker(
icon: mapMarker,
markerId: const MarkerId("marker-1"),
position: LatLng(locationMessage.latitude, locationMessage. longitude)));///PASS LAT AND LONG
});
........
........
........
I would suggest doing something like this:
create _currentLocation var:
LatLng _currentLocation;
update value inside getCurrentLocation() / setState():
_currentLocation = LatLng(position.latitude, position.longitude);
inside _markers.add use:
position: _currentLocation
You should initialize _currentLocation value inside initState() by calling getCurrentLocation():
#override
void initState() {
getCurrentLocation();
super.initState();
}
Note: if you are using google_maps_flutter package and you want to show the user position, you can set the myLocationEnabled property to true:
GoogleMap(
myLocationEnabled: true,
...
I tried get user location when button clicked using flutter location package
Code
FloatingActionButton(
onPressed: () async {
await location
.hasPermission()
.then((PermissionStatus status) async {
if (_permissionGranted == PermissionStatus.denied) {
await location.requestPermission().then(
(PermissionStatus requestStatus) async {
print("PERMISSION TAKEN");
await location
.getLocation()
.then((LocationData userLocation) {
print("LOCATION TAKEN 1");
print(userLocation);
});
},
);
} else {
await location
.getLocation()
.then((LocationData userLocation) {
print("LOCATION TAKEN 2");
print(userLocation);
});
}
});
},
child: Icon(Icons.place, color: Colors.white),
backgroundColor: Colors.green,
),
When user clicked to button requested permission to location and in my code after permission granted work this part of my code
print("PERMISSION TAKEN");
But then not work this part of code
await location
.getLocation()
.then((LocationData userLocation) {
print("LOCATION TAKEN 1");
print(userLocation);
});
you can also get the location by following:---------
pubspec.yaml file under dependencies:----
dependencies:
location: ^3.0.0
Android, add this permission in AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
iOS, you have to add this permission in Info.plist :
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Warning: there is a currently a bug in iOS simulator in which you have to manually select a Location several in order for the Simulator to actually send data. Please keep that in mind when testing in iOS simulator.
main.dart
import 'package:flutter/material.dart';
import 'package:location/location.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter GPS',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: GetLocationPage(),
);
}
}
class GetLocationPage extends StatefulWidget {
#override
_GetLocationPageState createState() => _GetLocationPageState();
}
class _GetLocationPageState extends State<GetLocationPage> {
LocationData _currentLocation;
Location _locationService = new Location();
#override
void initState() {
// TODO: implement initState
super.initState();
_getLocation().then((value) {
setState(() {
_currentLocation = value;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_currentLocation == null
? CircularProgressIndicator()
: Text("Location:" +
_currentLocation.latitude.toString() +
" " +
_currentLocation.longitude.toString()),
],
),
),
);
}
Future<LocationData> _getLocation() async {
LocationData currentLocation;
try {
currentLocation = await _locationService.getLocation();
} catch (e) {
currentLocation = null;
}
return currentLocation;
}
}
ss:---
In order to request location, you should always check manually Location Service status and Permission status. refer this https://pub.dev/packages/location
i get current location as below , try to use like this
Future<LatLng> getUserLocation() async {
LocationData currentLocation;
var location = new Location();
bool _serviceEnabled;
PermissionStatus _permissionGranted;
LocationData _locationData;
_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
_serviceEnabled = await location.requestService();
if (!_serviceEnabled) {
}
}
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.DENIED) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.GRANTED) {
}
}
// Platform messages may fail, so we use a try/catch PlatformException.
try {
currentLocation = await location.getLocation();
final lat = currentLocation.latitude;
final lng = currentLocation.longitude;
final coordinates = new Coordinates(lat, lng);
var addresses =
await Geocoder.local.findAddressesFromCoordinates(coordinates);
var first = addresses.first;
updateLocation(lat, lng, first.postalCode, first.locality,
first.countryName, first.adminArea, first.addressLine);
final center = LatLng(lat, lng);
return center;
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
showToast("LOCATION PERMISSION DENIED",
gravity: Toast.TOP, duration: Toast.LENGTH_LONG);
}
currentLocation = null;
}
}
And don't forget to add this permission in Info.plist
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
I make a simple app in flutter to get markers from API and draw them on Google Map.
I make a model with Location name and I have get markers information from the API and added them to the list of markers.
But when I run my app, no markers shown on map.
How can I solve this problem?
My function That get markers from API :
Future<List<Location>> getLocations() async {
try {
var url = 'http://10.0.2.2/Track_App/locations.php';
final resp = await http.get(url);
final responsebody = jsonDecode(resp.body);
return responsebody; //this return a list
} catch (e) {
return [];
}
}
List<Marker> allMarkers = [];
loadLocations() async {
List<Location> locations;
locations = [];
locations = await getLocations(); //we store the response in a list
for (var i = 0; i < locations.length; i++) {
LatLng latlng;
latlng = LatLng(
double.parse(locations[i].locX),
double.parse(locations[i].locY),
);
allMarkers.add(
Marker(
markerId: MarkerId(locations[i].locId.toString()),
position: latlng,
),
);
}
setState(() {});
}
Google Map Code :
FutureBuilder(
future: loadLocations(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kGooglePlex,
markers: snapshot.data,
);
},
),
JSON data from API :
[
{
loc_id: "1 ",
loc_x: "15.392567",
loc_y: "44.278188"
},
{
loc_id: "2 ",
loc_x: "15.391717",
loc_y: "44.278019"
}
]
My Model :
class Location {
Location({
this.locId,
this.locX,
this.locY,
this.locInfo,
this.locSpd,
this.locDate,
});
String locId;
String locX;
String locY;
String locInfo;
String locSpd;
String locDate;
factory Location.fromJson(Map<String, dynamic> json) => Location(
locId: json['loc_id'],
locX: json['loc_x'],
locY: json['loc_y'],
locInfo: json['loc_info'],
locSpd: json['loc_spd'],
locDate: json['loc_date'],
);
Map<String, dynamic> toJson() => {
'loc_id': locId,
'loc_x': locX,
'loc_y': locY,
'loc_info': locInfo,
'loc_spd': locSpd,
'loc_date': locDate,
};
}
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
Whenever, you want to add maker here, create a new Marker and add to State
Marker marker = Marker(...)
setState(() {
markers[markerId] = marker;
});
And your build function would just be like this
child: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: const CameraPosition(
target: LatLng(-33.852, 151.211),
zoom: 11.0,
),
markers: Set<Marker>.of(markers.values),
),
this code work for me just change your location listner
Future<Offre> location_client() async{
var _loc = await _location.getLocation();
setState(() {
client_lat = _loc.client.lat;
client_lng = _loc.client.lng;
print("test test"+_loc.client.lat.toString()+','+_loc.client.lng.toString());
LatLng latlng = LatLng(client_lat,client_lng);
setState(() {
_markers.add(Marker(
markerId: const MarkerId("home"),
position: latlng,
draggable: false,
zIndex: 2,
flat: true,
anchor: const Offset(0.5, 0.5),
icon: BitmapDescriptor.defaultMarker));
});
});
}