Issue with Google Maps-API: fit_bounds does not work

Hello,

I currently have some issues with the Google Maps API when trying to set the map to bounds. I created a bound which seems to work fine (I checked the coordinates):
print(bounds)
<GoogleMap.LatLngBounds sw=<GoogleMap.LatLng: 47.47846,-0.10747>, ne=<GoogleMap.LatLng: 51.13829,13.95889>>

However, when I try to fit my map to the created bound by doing the following:
self.map_1.fit_bounds(bounds)

It even zooms out instead of fitting the map to the bound.

Does anyone has an idea?

It seems to be a bug. I tested quite a lot of things, but the Google API is not working as it is expected to… Anyone from Anvil to support?

Hi @D_S,

Thanks for posting your question.

I can’t find a bug with GoogleMaps API. I’ve created a demo app that creates a LatLngBounds object with your coordinates and then fits the map to those bounds using the fit_bounds() function. It is working as expected.

Here is a clone link if you’d like to investigate yourself:
https://anvil.works/build#clone:GKQKQNMBOMJHTMYT=I6KEA7OZM4T7M7WFV7A5XSC3

If you’re still having issues, I’d suggest posting some more substantial source code or a clone link to an example app that demonstrates the behaviour.

I hope that helps.

Ryan

1 Like

Hi Ryan, thank you for your kind support!

After heavy testing, I was able to identify the core of the issue and am able to reproduce it in different setups. It only occurs when I get coordinates from a data table. The bounds object seems to be created correctly. All values and properties are exactly the same, no matter if I receive the values from the data table to generate it or if I iterate through a list of coordinates in the python function itself. However, the fit_to_bound behaves differently.

Strangely, the difference only occurs if I call the function within python. However, when I call the exact same function e.g. by clicking on a button, it does work as expected.

I created a sample app for reference. The create_map() function is called in the init as well as when the bottom on top of the page is clicked.

https://anvil.works/build#clone:HQ7Q6S56ZDDSWZVC=56PXNX6UCPC2WAH5RE7HCOT6

I am not able to identify the cause of this strange behavior. Would be awesome if you can take a look into it.

Best
DS

@ryan, do you have any idea?

Hi there,

I have been facing misbehavior of the Google Maps functions for several weeks now.
After heavy testing, I was able to identify the core of the issue and am able to reproduce it in different setups. The issue occurs when I use Google Maps API trying to set the map to bounds, e.g. with

self.map_1.fit_bounds(bounds)

Though the bounds object seems to be created correctly, it does not properly align with the map as expected. However, the issue only occurs when I receive coordinates from a data table and does not happen when I create the bounds out of coordinates directly within the Python code. All values and properties are exactly the same, no matter if I receive the values from the data table to generate it or if I iterate through a list of coordinates in the python function itself. However, the fit_to_bound function behaves differently.

Strangely, the difference only occurs if I call the function directly from Python. However, when I call the exact same function e.g. by clicking on a button, it does work as expected.

I created a sample app for reference. The create_map() function is called in the init as well as when the bottom on top of the page is clicked.

https://anvil.works/build#clone:HQ7Q6S56ZDDSWZVC=56PXNX6UCPC2WAH5RE7HCOT6

I am not able to identify the cause of this strange behavior. Would be awesome if you can take a look into it.

Best
DS

Hi @D_S,

I noticed you also tried to call the create_map from the form_show event.

When I move create_map to the form_show event the bounds work as expected.

Hi @stucork,

thank you very much for your reply! Yes, I have tried this and can confirm that it does work in the example I posted. However, in the application I am currently working on I do exactly this (Only calling the function on form_show). But there, it does not work and the same issue occurs as initially stated… Do you have any explanation of this behaviour though? Why doesn’t it work when calling it in the init? Maybe that helps me to further investigate the issue…

Best
DS

I think a better approach then might be to store your bounds

self.bounds = bounds

And then add a show event for the map component itself

def map_1_show(self, **event_args):
    self.map_1.fit_bounds(self.bounds)

We’ll do some more investigation our end and see where we can improve the code/docs and get back to you.

I suspect that it is to do with certain methods that require the component to be on the screen to execute as expected.
fit_bounds likely being one such method.
This combined with getting data from the datatables.
When you call out to the datatables to get the data - you are also suspending the execution of the code and this is likely causing the difference in behaviour.
(vs generating the bounds in python where the code doesn’t need to suspend).

Without going into too much detail - in the version that you’ve highlighted as not working as excepted - the map may have initialised but is not yet on the screen so fit_bounds is having no effect.

Hi @stucork,

thanks for your feedback and the effort. I understand. Unfortunately, your suggestion does also not work for me…
I tried several set-ups.

  1. creating the self.bounds in the __init__ of the form and calling the fit_bounds in map_1_show
    => same behaviour
  2. Doing the following only within the map_1_show function
    self.bounds = self.create_map()
    print(self.bounds)
    self.map_1.fit_bounds(self.bounds)
    print("done")

self.create_map() is returning the bounds object. The output seems to be fine:

<GoogleMap.LatLngBounds sw=<GoogleMap.LatLng: -33.390339,151.353809>, ne=<GoogleMap.LatLng: 53.72861,16.68644>>
done

In both cases, fit_bounds is only executed after the map itself is shown and the self.bounds object is correctly created, right? => However, still the same issue…

Are you able to reproduce the show event fit_bounds behaviour in a clone?
I can’t seem to reproduce

Something else you could try

def map_1_idle(self, **event_args):
    if self.bounds:
        self.map_1.set_event_handler('idle', lambda **e: None)
        self.map_1.fit_bounds(self.bounds)