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;
}
Related
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));
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 am customizing flutter ecommerce mobile app from codecanyon.
How can I change the onPressed command to one time function that will work automatically for one time
onPressed: () async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Map(
latitude: latitude == null
? position.latitude
: double.parse(latitude),
longitude: longitude == null
? position.longitude
: double.parse(longitude),
from: getTranslated(context, 'ADDADDRESS'),
)));
if (mounted) setState(() {});
List<Placemark> placemark = await placemarkFromCoordinates(
double.parse(latitude), double.parse(longitude));
state = placemark[0].administrativeArea;
country = placemark[0].country;
pincode = placemark[0].postalCode;
// address = placemark[0].name;
if (mounted)
setState(() {
countryC.text = country;
stateC.text = state;
pincodeC.text = pincode;
// addressC.text = address;
});
},
#override
void initState(){
super.initState();
_openMap();
}
......
void _openMap() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high);
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Map(
latitude: latitude == null
? position.latitude
: double.parse(latitude),
longitude: longitude == null
? position.longitude
: double.parse(longitude),
from: getTranslated(context, 'ADDADDRESS'),
)));
if (mounted) setState(() {});
List<Placemark> placemark = await placemarkFromCoordinates(
double.parse(latitude), double.parse(longitude));
state = placemark[0].administrativeArea;
country = placemark[0].country;
pincode = placemark[0].postalCode;
// address = placemark[0].name;
if (mounted)
setState(() {
countryC.text = country;
stateC.text = state;
pincodeC.text = pincode;
// addressC.text = address;
});
}
.......
.....
onPressed:_openMap
I am building a simple music player type app. I am facing an issue when my audio completed the time it's showing
'package:flutter/src/material/slider.dart': Failed assertion: line 166 pos 15: 'value >= min && value <= max': is not true.
My code
Expanded(
child: Slider(
activeColor: Color(0xffe7ad29),
inactiveColor: Color(0xFF707070),
value: model.playerBarValue,
onChanged: (val) {
model.seekFromBar(val);
},
),
),
class PlayerProvider extends ChangeNotifier {
final player = AssetsAudioPlayer();
String link;
Duration playerTimeNow = Duration(seconds: 0);
Duration playerLength;
double playerBarValue = 0.0;
Episode episode;
Item podcastInfo;
String episodeName, episodeThumbnail;
bool isPlaying = false;
PlayerProvider() {
updateState();
}
play() async {
print("Started Playing");
// Stop previous playing
player.stop();
playerTimeNow = Duration(seconds: 0);
isPlaying = false;
// link = updateLinkToHttps(link);
print(link);
final audio = Audio.network(
link,
metas: Metas(
title: podcastInfo.collectionName,
artist: podcastInfo.artistName,
album: podcastInfo.trackName,
image: MetasImage.network(podcastInfo.artworkUrl600),
//can be MetasImage.network
),
);
var duration = await player.open(
audio,
showNotification: true,
notificationSettings: NotificationSettings(
//seekBarEnabled: false,
//stopEnabled: true,
//customStopAction: (player){
// player.stop();
//}
//prevEnabled: false,
customNextAction: (player) {
print("next1");
forward();
}, customPrevAction: (player) {
print("next2");
backword();
}
//customStopIcon: AndroidResDrawable(name: "ic_stop_custom"),
//customPauseIcon: AndroidResDrawable(name:"ic_pause_custom"),
//customPlayIcon: AndroidResDrawable(name:"ic_play_custom"),
),
);
isPlaying = true;
// player.play(); // Usually you don't want to wait for playback to finish.
print("started");
setState();
}
pause() async {
await player.pause();
isPlaying = false;
print("paused");
setState();
}
resume() async {
//TODO: Setup resume
await player.seek(playerTimeNow);
player.play();
isPlaying = true;
}
speed(double val) async {
print(val);
//TODO: Setup resume
await player.setPlaySpeed(val);
isPlaying = true;
}
updateState() {
player.currentPosition.listen((event) {
playerTimeNow = event;
updatePlayerBar();
});
}
updatePlayerBar() {
int totalLengthInMilliSeconds = playerLength.inMilliseconds;
int totalPlayedInMilliSeconds = playerTimeNow.inMilliseconds;
double newPlayerBarValue =
totalPlayedInMilliSeconds / totalLengthInMilliSeconds;
playerBarValue = newPlayerBarValue;
// print(playerBarValue);
// print(playerTimeNow);
// print(playerLength);
// print(playerLength);
// if (playerLength == playerTimeNow) {
// print('Finish');
// player.stop();
// }
notifyListeners();
}
forward() async {
//TODO: Check if at-least 10 seconds are left;
if (playerTimeNow + Duration(seconds: 10) < playerLength)
await player.seek(playerTimeNow + Duration(seconds: 10));
else
await player.seek(playerLength);
print("Forwarded 10 seconds");
}
backword() async {
Duration back = playerTimeNow.inSeconds > 10
? playerTimeNow - Duration(seconds: 10)
: Duration(seconds: 0);
await player.seek(back);
print("Backwarded 10 seconds");
}
seekFromBar(double val) async {
double totalMillis = playerLength.inMilliseconds * val;
int newMillis = totalMillis.toInt();
Duration newSeekLocations = Duration(milliseconds: newMillis);
await player.seek(newSeekLocations);
print("Seek from Bar");
}
setState() {
notifyListeners();
}
}
When time is finished of player then it's showing this error on red screen. I need to know the fix of this? Mean when it's finished time go to 0 or something. The issue is on the slider I think because if I back from the red screen then my slider goes to zero.
check thet the value of model.playerBarValue is neither Nan or null, and set a max value for the slider.
Slider(
value: model.playerBarValue.isNaN==true || model.playerBarValue==null? 0 : model.playerBarValue,
min: 0.0,
max: duration.inSeconds.toDouble() + 1.0,
onChanged: (value) {
. . .
},
)
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));
});
});
}