Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter LatLngBounds not showing accurate place

I am trying to show all of my markers into the viewport using my flutter google maps. But it seems not working in my case. I have tried so far as below:

    _controller.animateCamera(CameraUpdate.newLatLngBounds(
            LatLngBounds(
              southwest: LatLng(23.785182, 90.330702),
              northeast: LatLng(24.582782, 88.821163),
            ),
            100
        ));

    LatLngBounds boundsFromLatLngList(List<LatLng> list) {
    assert(list.isNotEmpty);
    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));
  }

As i have seen, it just always show the map of North Atlantic Ocean Is there any solution regarding this issue or it is just under development in Flutter ?. thanks in advance

like image 451
Enayet Hossain Avatar asked May 11 '20 05:05

Enayet Hossain


2 Answers

I'm facing the exact same issue on Android (works fine on iOS) when I animate the map with CameraUpdate.newLatLngBounds. It repositions to North Pacific Ocean immediately after setting the bounds, not sure what's causing this but here's a workaround -

Instead of setting the map position using LatLngBounds, you can calculate the centre of the bounds you want to set

// the bounds you want to set
LatLngBounds bounds = LatLngBounds(
  southwest: LatLng(23.785182, 90.330702),
  northeast: LatLng(24.582782, 88.821163),
);
// calculating centre of the bounds
LatLng centerBounds = LatLng(
  (bounds.northeast.latitude + bounds.southwest.latitude)/2,
  (bounds.northeast.longitude + bounds.southwest.longitude)/2
);

// setting map position to centre to start with
controller.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
  target: centerBounds,
  zoom: 17,
)));
zoomToFit(controller, bounds, centerBounds);

Once you set the map position to the centre of the bounds (and zoomed in), you then need to keep zooming out till the visible map region covers the bounds you want to set. You can get the visible map region with controller.getVisibleRegion(). Here's the implementation -

Future<void> zoomToFit(GoogleMapController controller, LatLngBounds bounds, LatLng centerBounds) async {
  bool keepZoomingOut = true;

  while(keepZoomingOut) {
    final LatLngBounds screenBounds = await controller.getVisibleRegion();
    if(fits(bounds, screenBounds)){
      keepZoomingOut = false;
      final double zoomLevel = await controller.getZoomLevel() - 0.5;
      controller.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
        target: centerBounds,
        zoom: zoomLevel,
      )));
      break;
    }
    else {
      // Zooming out by 0.1 zoom level per iteration
      final double zoomLevel = await controller.getZoomLevel() - 0.1;
      controller.moveCamera(CameraUpdate.newCameraPosition(CameraPosition(
        target: centerBounds,
        zoom: zoomLevel,
      )));
    }
  }
}

bool fits(LatLngBounds fitBounds, LatLngBounds screenBounds) {
  final bool northEastLatitudeCheck = screenBounds.northeast.latitude >= fitBounds.northeast.latitude;
  final bool northEastLongitudeCheck = screenBounds.northeast.longitude >= fitBounds.northeast.longitude;

  final bool southWestLatitudeCheck = screenBounds.southwest.latitude <= fitBounds.southwest.latitude;
  final bool southWestLongitudeCheck = screenBounds.southwest.longitude <= fitBounds.southwest.longitude;

  return northEastLatitudeCheck && northEastLongitudeCheck && southWestLatitudeCheck && southWestLongitudeCheck;
}
like image 199
Chinmay Dabke Avatar answered Nov 08 '22 11:11

Chinmay Dabke


Had the same issue the problem for me:

I didn't really gave the southwest and northeast coordinates but: NorthWest and SouthEast. iOS handled this normally but android zoomed on the Atlantic.

After fixing that like:

final highestLat = points.map((e) => e.latitude).reduce(max);
final highestLong = points.map((e) => e.longitude).reduce(max);
final lowestLat = points.map((e) => e.latitude).reduce(min);
final lowestLong = points.map((e) => e.longitude).reduce(min);

final lowestLatLowestLong = LatLng(lowestLat, lowestLong);
final highestLatHighestLong = LatLng(highestLat, highestLong);
final getRouteBoundsCameraUpdate = CameraUpdate.newLatLngBounds(LatLngBounds(southwest: lowestLatLowestLong, northeast: highestLatHighestLong), 25.0);
like image 20
Guus Avatar answered Nov 08 '22 10:11

Guus