I'm playing around with Google Maps for Flutter. I want the map view to fit all the markers on the screen. Basically, I want to do same as here for android.
I assumed that cameraTargetBounds
describes the area that should fit inside screen boundaries. But in fact it doesn't fit this area entirely, focusing somewhere in between.
What I've done so far:
@override
Widget build(BuildContext context) {
final bloc = Provider.of<BlocMap>(context);
return SafeArea(
child: Container(
child: Stack(
children: <Widget>[
Positioned.fill(
child: StreamBuilder<MapData>(
stream: bloc.mapData,
builder: (context, snap) {
final mapData = snap.data;
print("mapData: $mapData");
return GoogleMap(
padding: EdgeInsets.only(bottom: 42),
mapType: _mapType,
cameraTargetBounds: mapData?.markers == null
? CameraTargetBounds.unbounded
: CameraTargetBounds(_bounds(mapData?.markers)),
initialCameraPosition: _cameraPosition,
myLocationEnabled: true,
myLocationButtonEnabled: true,
gestureRecognizers: _buildGestureRecognizer(),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
markers: mapData?.markers,
polylines: mapData?.polylines,
polygons: mapData?.polygons,
onLongPress: (latLng) {
print("LatLng: $latLng");
},
);
}),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: _buildBtnBar(),
)
],
),
),
);
LatLngBounds _bounds(Set<Marker> markers) {
if (markers == null || markers.isEmpty) return null;
return _createBounds(markers.map((m) => m.position).toList());
}
LatLngBounds _createBounds(List<LatLng> positions) {
final southwestLat = positions.map((p) => p.latitude).reduce((value, element) => value < element ? value : element); // smallest
final southwestLon = positions.map((p) => p.longitude).reduce((value, element) => value < element ? value : element);
final northeastLat = positions.map((p) => p.latitude).reduce((value, element) => value > element ? value : element); // biggest
final northeastLon = positions.map((p) => p.longitude).reduce((value, element) => value > element ? value : element);
return LatLngBounds(
southwest: LatLng(southwestLat, southwestLon),
northeast: LatLng(northeastLat, northeastLon)
);
}
What is the intended way of achieving this basic functionality in flutter? Any suggestions?
Use this code to do what you wish.
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
setState(() {
controller.animateCamera(CameraUpdate.newLatLngBounds(_bounds(markers), 50));
});
}
Try using the controller to move the camera to the new bounds, eg (from the plugin example):
mapController.moveCamera(
CameraUpdate.newLatLngBounds(
LatLngBounds(
southwest: const LatLng(-38.483935, 113.248673),
northeast: const LatLng(-8.982446, 153.823821),
),
10.0,
),
);
first make a list of latlng and pass it to the given method
List<LatLng> latlonList = [LatLng(125.75,87.00),LatLng(165,46.76),LatLng(175.87,86.00),];
final GoogleMapController googleMapController = await widget.completer.future;
googleMapController.moveCamera(CameraUpdate.newLatLngBounds(
MapUtils.boundsFromLatLngList(latlonList),
4.0,
),
);
after that your map move to all the pointer . but to show more marker decent way we use another method which give us the center point of all the markers
var centerPoint = computeCentroid(latlonList);
var zoom = await googleMapController.getZoomLevel();
this.updateLocation(centerPoint.latitude, centerPoint.longitude,zoom -2);
Now simply copy these method..and every ting work perfectly fine
LatLng computeCentroid(Iterable<LatLng> points) {
double latitude = 0;
double longitude = 0;
int n = points.length;
for (LatLng point in points) {
latitude += point.latitude;
longitude += point.longitude;
}
return LatLng(latitude / n, longitude / n);
}
class MapUtils {
static LatLngBounds boundsFromLatLngList(List<LatLng> list) {
double? x0, x1, y0, y1;
for (LatLng latLng in list) {
if (x0 == null) {
x0 = x1 = latLng.latitude;
y0 = y1 = latLng.longitude;
} else {
if (latLng.latitude > x1!) x1 = latLng.latitude;
if (latLng.latitude < x0) x0 = latLng.latitude;
if (latLng.longitude > y1!) y1 = latLng.longitude;
if (latLng.longitude < y0!) y0 = latLng.longitude;
}
}
return LatLngBounds(northeast: LatLng(x1!, y1!), southwest: LatLng(x0!, y0!));
}
}
updateLocation(double latitude,double longitude,double zoom) async {
final GoogleMapController googleMapController = await widget.completer.future;
print("zoom$zoom");
googleMapController.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
bearing: 0,
target: LatLng(latitude,longitude),
zoom:zoom,
),
));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With