Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically calculate map bounds from a list of LatLng values #36653

Open
KingWu opened this issue Jul 22, 2019 · 16 comments
Open

Automatically calculate map bounds from a list of LatLng values #36653

KingWu opened this issue Jul 22, 2019 · 16 comments
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter p: maps Google Maps plugin P3 Issues that are less important to the Flutter project package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team

Comments

@KingWu
Copy link

KingWu commented Jul 22, 2019

Just read the source code. Cannot find a method to build a LatLngBounds from a list of LatLng.

https://developers.google.com/android/reference/com/google/android/gms/maps/model/LatLngBounds.Builder

@adim86
Copy link

adim86 commented Jul 25, 2019

I am having the same issue, I want to build the bounds from a couple of Latitude and Longitude Coordinates but I am unable to find how to implement this in FLutter with the classes we have been given. Any ideas?

@unamed000
Copy link

same issue. We need to calculate the zoom and bounds of the map between 2 markers

@adim86
Copy link

adim86 commented Aug 27, 2019

@unamed000 I was able to solve this by adding this function and using it to calculate

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));
  }

@unamed000
Copy link

unamed000 commented Aug 28, 2019

Hi @adim86,
So the northeast should be the maximum number of lat + lng and southwest should be minimum ?

Edit: Thanks adim,
It's working like a charm :), when using with

_mapController.animateCamera(CameraUpdate.newLatLngBounds(
                  LatLngBounds(
                      southwest: LatLng(latMin, longMin),
                      northeast: LatLng(latMax, longMax),
                  ),
                  100
                ));

@BondarenkoStas BondarenkoStas added p: maps Google Maps plugin plugin c: new feature Nothing broken; request for a new capability labels Sep 23, 2019
@Nexuist
Copy link

Nexuist commented Oct 7, 2019

While @adim86's solution works like a charm, I still believe it should be part of the standard API to maintain feature parity with the Google Maps JS SDK. Additionally, LatLngBounds should have a .getCenter() method like its JS counterpart does.

For me this would be useful as I'm trying to make the map show all markers at once, so I need to make a bounds that includes every marker and also dispatch a camera update that sets the target and zoom to adequate values such that the map shows every marker.

@sanisloandras
Copy link

I also need this feature, but sadly don't have the time to help in development.

@timsneath timsneath changed the title Google Map supports LatLngBounds.Builder Automatically calculate map bounds from a list of LatLng values Jan 3, 2020
@karatasemre
Copy link

karatasemre commented Jan 27, 2020

@adim86 thank youuuuuuuu

@DanielFortuyn
Copy link

@Nexuist Yeah that is actually somehting that I would like to achieve as well, did you manage to get something like that working by now?

@Nexuist
Copy link

Nexuist commented Jan 31, 2020

@DanielFortuyn Yes, I did using some custom code mixed and matched from SO:

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));
}

 void _onMapCreated(GoogleMapController controller) {
    _controller.complete(controller);
    Future.delayed(
        Duration(milliseconds: 200),
        () => controller.animateCamera(CameraUpdate.newLatLngBounds(
            boundsFromLatLngList(
                widget.locations.values.map((loc) => loc.asLatLng()).toList()),
            1)));
  }

@pkill37
Copy link

pkill37 commented Mar 11, 2020

@Nexuist Thanks for the Future.delayed snippet, I used this to work around the fact that newLatLngBounds was randomly throwing for me

E/MethodChannel#plugins.flutter.io/google_maps_14( 8309): com.google.maps.api.android.lib6.common.apiexception.c: Error using newLatLngBounds(LatLngBounds, int): Map size can't be 0. Most likely, layout has not yet occured for the map view.  Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions.

even though the map should be all ready in onMapReady.

@giorgio79
Copy link

Google team committed a getVisibleRegion method, would that be the way forward? #25755

@jose-airspace
Copy link

jose-airspace commented Aug 9, 2020

@Nexuist how did you get the appropriate zoom level though?

Nvm, it auto zooms. Unfortunate that you can't set it in the initializer which what was broken for me. Whats the point of cameraTargetBounds?!

@darshankawar darshankawar added passed first triage c: proposal A detailed proposal for a change to Flutter labels Apr 29, 2021
@cyanglaz cyanglaz added the P3 Issues that are less important to the Flutter project label Apr 29, 2021
@velval
Copy link

velval commented Nov 8, 2021

One can use the LatLngBounds.fromPoints(points) built-in method if using the flutter_map library.

@khurram-saeed-malik
Copy link

khurram-saeed-malik commented Feb 12, 2022

Here is a re-written version of @Nexuist suggestion as an extension function to LatLngBounds class:

extension LatLngBoundsExtension on LatLngBounds {
  static fromLatLng(List<LatLng> latLngList) {
      assert(latLngList.isNotEmpty);
      double? x0, x1, y0, y1;
      for (LatLng latLng in latLngList) {
        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!));
  }
}

Usage:

LatLngBoundsExtension.fromLatLng(markers.map((e) => e.position).toList()), 1)

@tomheno
Copy link

tomheno commented May 19, 2022

Null-safe version of @adim86 solution :

LatLngBounds boundsFromLatLngList(List<LatLng> list) {
  double? x0, x1, y0, y1;
  for (LatLng latLng in list) {
    if (x0 == null || x1 == null || y0 == null || y1 == 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(LatLng(x1!, y1!), LatLng(x0!, y0!));
}

@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
@Hixie Hixie removed the plugin label Jul 6, 2023
@flutter-triage-bot flutter-triage-bot bot added team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team labels Jul 8, 2023
@Daeon97
Copy link

Daeon97 commented Sep 13, 2023

@unamed000 I was able to solve this by adding this function and using it to calculate

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));
  }

So I am trying to implement exactly this right now. Fortunately stumbled on this issue here. Thanks @adim86 for this. Works perfectly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter p: maps Google Maps plugin P3 Issues that are less important to the Flutter project package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team
Projects
None yet
Development

No branches or pull requests