Flutter: Map Camera position not update to new LatLong - flutter

I am using Stream Builder that sends api request after some seconds and fetch coordinates (lat, lng).
I want to update the map location (camera position & marker) on newly fetch coordinates.
But Camera position is updating and not focusing on new coordinates.
My google map widget is inside of stream builder and in which we are passing data through snapshot
e.g latlng = LatLng(snapshot.data['lat'],snapshot.data['lng']) to markers: SetMarker( markers, markerID, latlng, ), & initialCameraPosition: CameraPosition( target: latlng, zoom: 9.0, )

The GoogleMaps widget on Flutter does have the attribute initialCameraPosition but as the name says this is just an initial value, if you want to update the map once this has loaded i'd recommend the use of the callback onMapCreated, where you can use the controller to animate to a certain position.
Doing so would look something like this:
onMapCreated: (GoogleMapController controller) {
controller.animateCamera(
CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(snapshot.data['lat'],
snapshot.data['lng']),
zoom: 12)));
setState((){});
}
Hope this helps! ;)

Related

How do I get map rotation on google maps flutter?

I'm trying to get the map rotation (bearing) but can't find it with the map controller.
Using currently google_maps_flutter: ^1.1.1 and flutter: 1.22
You can get the real time updated bearing by following steps:
listen to changes of the location using:
double mainBearing = 15.0;
location.onLocationChanged.listen((locationLib.LocationData cLoc) {
//You can get the bearing of current location by using
mainBearing = cLoc.heading
//Or you can do newCameraPoistion here with new bearing
_controller.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(cLoc.latitude, cLoc.longitude),
zoom: zoomCamera,
bearing: cLoc.heading,
),
),
);
}
You can do that by using this geolocator plugin and then you can get your position with:
Position position = await Geolocator.getCurrentPosition();
and then update map with:
controller.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
target: LatLng(position.latitude, position.longitude),
zoom: 16,
bearing: position.heading,
),
),
),
Found it: CameraPosition has bearing:
controller.animateCamera(
CameraUpdate.newCameraPosition(
CameraPosition(
bearing: location.heading.value,
target: LatLng(location.latitude ?? 51.4,
location.longitude ?? 4.4),
zoom: 18),
),
Actually I found what I was looking for. There is the onCameMove callback on GoogleMap constructor and it receives current CameraPosition as its argument. It has the bearing, target, tilt and zoom fields.
This way I can be aware of changes to the map's bearing at anytime.
PS: This function is executed repeatedly while the user is moving the map and should not perform expensive operations.
You can find it on the properties of CameraPosition function from your GoogleMaps library.
_googleMapController!.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(cLoc.latitude!, cLoc.longitude!),
bearing: cLoc.heading!,
tilt: 30,
zoom: 18,
)))
and you can also call this from location.onLocationChanged.listen((LocationData cLoc) {}
And that's it.

How can I initiate drawing on my Google Map?

I found this library: https://pub.dev/packages/flutter_map_picker
I looked through his code and tried figuring out how he initiates drawing. What he accomplishes is far more complicated than I need, and I can't figure out the first step of what he did. I also don't want to take the guy's code. Can anyone explain how to accomplish this?
I just want to be able to circle objects on my map. There seems to be a polyline solution but it's just straight lines from a list of coordinates, not exactly what I'm looking for.
A Stack widget with GoogleMap and CustomPaint will let you draw anything you want on top of the map.
Stack(
children: <Widget>[
_position == null
? Text('Waiting for location . .')
: GoogleMap(
liteModeEnabled: false,
compassEnabled: true,
mapType: MapType.hybrid,
markers: Set<Marker>.of(markers.values),
initialCameraPosition: CameraPosition(
target: LatLng(_position.latitude, _position.longitude),
zoom: 17,
tilt: 0,
),
onMapCreated: (GoogleMapController controller) {
_mapController = controller;
// trigger initial update and paint of landmarks
_updateLandmarks();
},
onCameraMove: (CameraPosition position) {
_updateLandmarks();
},
),
CustomPaint(
foregroundPainter: MapPainter(_landmarksMap),
),
],
)
You have to convert map coordinates to device screen coordinates. Google has a cookbook on how to do that except it does not work in Flutter since the map plugin does not expose the complete API. But there is a way to do it of course.
void _updateLandmarks() async {
double dpi = MediaQuery.of(context).devicePixelRatio;
LatLngBounds bounds = await _mapController.getVisibleRegion();
ScreenCoordinate topRight = await _mapController.getScreenCoordinate(bounds.northeast);
ScreenCoordinate bottomLeft = await _mapController.getScreenCoordinate(bounds.southwest);
_landmarksMap.values.forEach((element) async {
ScreenCoordinate sc = await _mapController.getScreenCoordinate(LatLng(element.pos.latitude, element.pos.longitude));
element.screenPoint.x = ((sc.x - bottomLeft.x) / dpi).floor();
element.screenPoint.y = ((sc.y - topRight.y) / dpi).floor();
});
setState(() {});
}
You can read here for more details: https://aperico.com/google-maps-with-custom-paint-in-flutter/

Issue with getting current position of camera in google_maps_flutter

I'm a novice in Flutter, and I encountered an issue with google maps plugin. I watched a couple of tutorials in order to get the current position of the camera and Most of them was using GoogleMapController.cameraPosition.target. I think they deleted this method from the controller(Since it is still on the development stage). Is there any other way of getting the current position of the camera?
If you are using the google_maps_flutter package:
The GoogleMap widget have the onCameraMove function that returns the CameraPosition while dragging the map or moving the camera.
To do this, you'll need to create a callback function called _getCameraPosition(CameraPosition cameraPosition which will be invoked when onCameraMove is called. For example:
void _getCameraPosition(CameraPosition cameraPosition) {
// You can do whatever you want with cameraPosition here
log("cameraPosition: " + cameraPosition.target.toString());
}
Then, you'll need to put the _getCameraPosition function to the onCameraMove field on GoogleMap widget, like this:
GoogleMap(
onCameraMove: _getCameraPosition, // pass it here
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(-33.86882, 151.209296),
zoom: 12,
),
),
As a result, you will get a LatLng value in the debug console. For example:
cameraPosition: LatLng(-33.8940124943736, 151.2027569487691)

Flutter google map maker ontap

I'm pretty new in Flutter. It is amazing. I'm working on small app usign google maps. I have 6 points (Markers) and need to recognize which one was selected.
I've added ontap event into every marker with i-index (i = 0..5). When I tap/click on marker I always get 6. It should be 0..5 based on marker.
Thanx a lot, Gabriel
i=0;
marker.clear();
for (myPoint mar in globals.historia.items) {
print(i.toString());
marker.add(Marker(
markerId: MarkerId(i.toString()),
position: mar.pos,
draggable: false,
consumeTapEvents: true,
onTap: () {
print("Marker_id-${i.toString()}");
},
));
i++;
}
GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: myposition,
zoom: 17.0,
),
polylines: road,
markers: Set.of(marker),
)
When onTap() is triggered it calls i with its last value that's == 6, that's why every time you tap on a marker, the print method prints 6.
i is a global variable, that has its own address, so the print method will search for the value on that address every time onTap is called.
I propose this solution - replace youtr print method inside onTap with this : print("Marker_id-${globals.historia.items.indexOf(mar)}")
mar is a local variable inside the for in loop, and its value has never changed, so he will point on the same value, onTap will behave as you want.

Google maps flutter zoom in/zoom out

I am trying to create a sample app like Uber with google_maps_flutter: ^0.5.10 .. In Uber app when you select a pickup/drop location, and you do double tap (to zoom in) or zoom in/zoom out scaling the screen it always happens respective to the center of screen. Whereas when I add the google maps in flutter and if I do double tap lets say on right bottom of screen, google maps zoom and takes the view to the area where it was tapped. Similarly it happens with the scaling (pinching screen). The area I scale the camera view goes to that particular location. But I want double tap or scaling to stay centered to my selected location (like in Uber).
I did achieve it using cameraMove and cameraStop callbacks. In that I determine if camera was moved due to a zoom, I get the last zoom factor and move camera back to my selected location with the new zoom factor. It works but does not looks good if I double tap on left corner the camera goes back to original position. Similarly I did for the scaling zoom as well to zoom in/zoom out the camera moves back to original location I selected.
Then I tried GestureDetector on top of the GoogleMaps. Inside that I handled the onDoubleTap. That looks neat as I just change the zoom factor on double tap and keep location same. But I am not able to achieve scaling zoom in/out using onScaleUpdate (etc) functions on GestureDetector.
Is there any better way in Google maps flutter plugin to do all this?
use onCameraMove this will listen to the change of the cameraPosition.
for instance if you zoom in using double tap or zoom in/out using gestures,
GoogleMap(
zoomGesturesEnabled: true,
tiltGesturesEnabled: false,
onCameraMove:(CameraPosition cameraPosition){
print(cameraPosition.zoom);
},
onCameraMove take a void function and pass to it the CameraPosition argument, so you can use
"cameraPosition.zoom" to return the current zoom level; "cameraPosition.tilt" return the current tilt angle ...
use zoomGesturesEnabled: true
like that :
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class ZoomInOutMaps extends StatefulWidget {
#override
_ZoomInOutMapsState createState() => _ZoomInOutMapsState();
}
class _ZoomInOutMapsState extends State<ZoomInOutMaps> {
Completer<GoogleMapController> _controller = Completer();
static const LatLng _center = const LatLng(45.521563, -122.677433);
void _onMapCreated(GoogleMapController controller) {
_controller.complete(controller);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Zoom in and Out of Google Maps'),
backgroundColor: Colors.red,
),
body: GoogleMap(
//enable zoom gestures
zoomGesturesEnabled: true,
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Use below for handling min and max zoom:
minMaxZoomPreference: MinMaxZoomPreference(13,17)