I'm using mapbox on flutter with flutter_map package and need to add marker on map when tapped on map and then get marker lat and long to send to server.
As far as I know, this functionality isn't available yet. There is however a pull request you can use to get this functionality while you wait for the Flutter team to merge it into the flutter_google_maps repo. You can find the pull request and code here
When using this pull request version you can do something like the below:
void _onMapLongTapped(LatLng location) {
// add place marker code here
_addMyMarker(location);
}
Future<void> _addMyMarker(LatLng location) async {
if (_myMarker != null) {
mapController.updateMarker(
_myMarker,
MarkerOptions(
position: LatLng(
location.latitude,
location.longitude,
)),
);
} else {
_myMarker = await mapController.addMarker(
MarkerOptions(
position: LatLng(
location.latitude,
location.longitude,
),
),
);
}}
Related
In Flutter I use
google_maps_flutter, google_directions_api and flutter_polyline_points packages to have a map with the following functionalities;
Drawing routes between current location and destination points, get distance and durations between them, driver must be notified to take left/right while driving to the destination.
I have done these all, but when current location keeps updating on the map I'm calling direction api which return lots of data like legs and steps this api call is almost every second and google will charge me a lot.
Is anybody faced to same issue, I really appreciate a help.
There is part of my codes I have done so far
void _getCurrentLocation(context) {
showGeneralDialog(
context: context,
barrierDismissible: false,
barrierColor: Colors.black45,
pageBuilder: (BuildContext buildContext, Animation animation,
Animation secondaryAnimation) {
return Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
height: MediaQuery.of(context).size.height - 80,
padding: EdgeInsets.all(20),
color: Tingsapp.transparent,
child: CurrentLocation(),
),
);
}).then((location) {
if (location != null) {
_addMoverMarker(location, 'mover');
//updateFirebase(location);
_animateCameraToCurrentLocation(location);
}
});
}
destination point are already set.
In the above code I get user current location and add a marker as bellow
void _addMoverMarker(newLocationData, String id) async {
Uint8List imageData = await getMarker();
//LatLng latlng = LatLng(newLocationData.latitude, newLocationData.longitude);
LatLng latlng = LatLng(_moverLatitude!, _moverLongitude!);
MarkerId markerId = MarkerId(id);
Marker marker = Marker(
markerId: markerId,
position: latlng,
zIndex: 2,
icon: BitmapDescriptor.fromBytes(imageData),
infoWindow: InfoWindow(
title: "Mover location",
),
);
markers[markerId] = marker;
circle = Circle(
circleId: CircleId("circle"),
radius: 20,
zIndex: 1,
center: latlng,
strokeColor: Colors.orange.withAlpha(60),
fillColor: Colors.orange.withAlpha(300),
);
_getMoverPolyline(newLocationData);
}
and here I animate the camera
_animateCameraToCurrentLocation(newLocationData) {
if (_locationSubscription != null) {
_locationSubscription!.cancel();
}
_locationSubscription =
_locationTracker.onLocationChanged.listen((newLocationData) {
if (_mapController != null) {
_addMoverMarker(newLocationData, 'mover');
_animateCamera(_moverLatitude, _moverLongitude, 16.0);
//updateFirebase(newLocationData);
}
});
}
when I draw the polyline I call directions api here my problem starts
_getMoverPolyline(LocationData locationData) async {
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
mapKey,
PointLatLng(_originLatitude!, _originLongitude!),
PointLatLng(_moverLatitude!, _moverLongitude!),
//PointLatLng(locationData.latitude!, locationData.longitude!),
travelMode: TravelMode.driving,
);
if (result.points.isNotEmpty) {
moverPolylineCoordinates = [];
result.points.forEach((PointLatLng point) {
moverPolylineCoordinates.add(LatLng(point.latitude, point.longitude));
});
}
_addMoverPolyLine();
_getDirections(_moverLatitude, _moverLongitude, _originLatitude,
_originLongitude).then((data){
_updateData(data);
});
}
_getDirections(_moverLatitude, _moverLongitude, _originLatitude, _originLongitude) async {
Api api = Api();
var res = await api.getDirections(
_moverLatitude, _moverLongitude, _originLatitude, _originLongitude);
var jsonData = jsonDecode(res.body);
print(jsonData['routes'][0]['legs'][0]);
return jsonData['routes'][0]['legs'][0];
}
In the above code _getDirections method gets calling every second.
Isn't possible to call directions api one time?
_updateData method update data like tern right/left or Head south on my map
No I don't think that it's good practice to keep calling the API. And even in the google_directions_api documentation, they say,
Note: This service is not designed to respond in real time to user input.
And to answer your main question..
Don't call the API every time the location changes, instead call it once using the current location. And the response contains everything you need to navigate the user. Check the maneuver key inside each step of a leg.
And you should only use the location subscription to update the current location and animate the camera on the map. Use the getLocation() method to get the current location before starting the trip and use that location to generate the route. Store that route in a variable and use the data inside the route response to display whatever you want.
It´s not a good practice to constantly call directionsAPI, for the good of your pocket and to follow the recommendations of google.
If you are creating a Navigation app you first need to call the Api when the user set a destination, capture de coordinates (overview_polyline) and after that if the user goes off the road you can use maps toolkit to determine when this occurs and after that call again directionsAPI.
Objective:
To be able to show custom markers from dev only and disable google maps' default markers.
Description:
I am trying to put markers in GoogleMap from google_maps_flutter plugin but Google already has its own markers so it is getting in the way of the markers that I am trying to add. Is there any way to just show the map and add user-defined markers only? If not is it possible to minimize the number of markers shown by default map?
Just looked around and found some possible fix.
Seems like we can generate map style from this website:
Styling Wizard.
From there I toned down landmarks and then I was able to remove markers using this:
final String mapStyle =
await rootBundle.loadString('assets/map/map_style.txt');
//Set it on mapcontroller after map is created.
onMapCreated: (GoogleMapController controller) {
if (_controller.isCompleted) {
return;
}
controller.setMapStyle(mapStyle);
_controller.complete(controller);
},
// create a function to create custom marker
Future<BitmapDescriptor> createCustomMarkerBitmap() async {
Uint8List? data = await getBytesFromAsset("assets/icons/map_marker.png", 100);
return BitmapDescriptor.fromBytes(data!);
}
// then call the function to create a custom marker.
BitmapDescriptor? _marker = await createCustomMarkerBitmap();
final Marker marker = Marker(
markerId: _markerId,
position: _position,
icon: _marker, // use the marker
infoWindow: _infoWindow,
onTap: () {},
);
How to add a marker in flutter (as far as I understand, this is placemark, but after studying the documentation. I haven't found how to add it. marker on the map) on the map? I use Yandex Mapkit
Try like this
final List<MapObject> mapObjects = [];
final placemarks = [
Placemark(
mapId: MapObjectId('placemark_3'),
point const Point(latitude: 55.69494398296744, longitude: 37.653375915527334),
....
),
...
];
setState(() {
mapObjects.addAll(placemarks);
});
I have been getting this error every time i use the PlacesAutoComplete widget. Search/request/response everything is working perfectly, no crashes or anything. But the logs show me this error on every search.
I added two packages for it: flutter_google_places and google_web_services.
And i dont use streams at all. So this is a really strange error for me.
I followed a couple of online guides for this, can anyone explain what am i doing wrong?
Also, i see that this is a pretty basic way to implement places autocomplete. I would love your suggestions on a better way to implement google places search.
Future<void> _searchWithPlacesAutoComplete() async {
Prediction _predictions = await PlacesAutocomplete.show(
context: context,
apiKey: GOOGLE_API_KEY,
onError: (response) => _showError(response),
mode: Mode.overlay,
language: "en",
components: [Component(Component.country, "uk")],
location: _currentLocation,
radius: 50,
);
if (_predictions != null) {
PlacesDetailsResponse detail =
await GoogleMapsPlaces(apiKey: GOOGLE_API_KEY)
.getDetailsByPlaceId(_predictions.placeId);
final lat = detail.result.geometry.location.lat;
final lng = detail.result.geometry.location.lng;
setState(() {
_markedPosition = new LatLng(lat, lng);
});
mapController.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: _markedPosition,
zoom: 16.0,
),
),
);
}
}
This is a plugin error which they have fixed in their git code. Unfortunately it hasn't been updated yet on their current release.
What you can do is integrate all of the src files in their github lib folder. It resolved the issue for me.
The exact steps:
[1] Go to https://github.com/fluttercommunity/flutter_google_places/tree/master/lib/src
[2] Copied all the dart files into my project
StreamController<dynamic> subject = StreamController<dynamic>.broadcast();
I am Vaibhav Pathak. I am working on a Flutter app in which I add markers in-app based on data change in firestore database and I want to remove the previous marker from the map using its marker id but I don't understand how to do it. I had watched many Youtube videos and blogs but I don't get to know this because of API changes in google maps flutter plugin. For your kind information, I want to tell that I am using the latest version of the google_maps flutter plugin.
My Code for Making Markers :
showLiveLocation(LatLng latLng) {
_markers.add(
Marker(
markerId: MarkerId(latLng.toString()),
position: latLng,
draggable: false,
infoWindow: InfoWindow(
title: "Live Order Location",
snippet: "Dear customer your order is live at this place."),
icon: liveLocation,
visible: true,
),
);
}
Thanks for everyone's help.
github : github#vkpdeveloper
You need to find that specific marker in your _markers list (e.g. by firstWhere()) and then remove it from the list of markers.
Edit:
Marker marker = _markers.firstWhere((marker) => marker.markerId.value == "myId",orElse: () => null);
setState(() {
_markers.remove(marker);
});
This will trigger a rebuild of your map where the marker is no longer included.
Inspired by Thomas, my solution was:
setState(() {
_markers.removeWhere((key, marker) => marker.markerId.value == "myMarkerId");
});